# Capsize for Predictable CSS Typography

> Capsize is a TypeScript toolkit that sizes text by cap height or font size, trims unused font space, and aligns font fallback metrics. It suits teams that need predictable typography in CSS-in-JS or generated stylesheets, but it requires correct font metadata and careful control of layout styles.

**seek-oss/capsize** — Flipping how we define typography in CSS.

- Repository: https://github.com/seek-oss/capsize
- Website: https://seek-oss.github.io/capsize/
- Stars: 1,734 · Forks: 48
- Language: TypeScript
- License: MIT
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/seek-oss-capsize

## Capsize’s Cap-Height Sizing Model

Capsize addresses a specific CSS problem: a font’s normal line box can contain substantial space above capital letters and below the baseline, making text difficult to align with grids, icons, or nearby interface elements. The project uses font metadata to define typography by the visible height of capital letters instead of treating `font-size` as the only useful sizing reference.

The core package supports two sizing modes. `capHeight` sets the height of capital letters to a requested number of pixels. This is useful when a design or grid depends on the visible capital-letter dimension. `fontSize` preserves the conventional CSS sizing model while still allowing Capsize to trim the unused space around the text. The README explicitly says that only one of these options should be passed.

It also offers two line-spacing models. `lineGap` describes the space between lines measured from the baseline and cap height of the next line. `leading` sets the line height as a value measured from the baseline, matching the terminology used by typography design tools. Passing neither option leaves the text with the font’s default spacing, described in the documentation as `line-height: normal`. Passing both sizing options or both line-spacing options is explicitly discouraged because their meanings overlap.

The result is useful for interface systems where predictable geometry matters more than preserving every font’s native line box. It is less compelling for ordinary prose where the browser’s normal line-height behavior is acceptable.

## How Capsize Builds Its CSS Output

Capsize is organized around a small set of font metrics: `capHeight`, `ascent`, `descent`, `lineGap`, and `unitsPerEm`. The README identifies these values as metadata extracted from a font’s metrics tables. Once the metrics and sizing choices are supplied, the core package can return either a CSS-in-JS object or a CSS string.

`createStyleObject` returns an object that can be spread into a framework’s `css` prop or another style object. `createStyleString` returns a selector and declarations that can be inserted into a stylesheet or a `style` element. Both APIs accept the same central options: the text size or cap height, line spacing or leading, and the font metrics.

The font metrics can come from `@capsizecss/metrics`, from `@capsizecss/unpack` when a font file is available, or from the Capsize website’s Metrics tab. The documented package layout also shows the repository contains separate packages for metrics and font unpacking, along with an integration package for vanilla-extract. This makes the project usable as a small TypeScript utility inside an existing styling pipeline rather than as a separate runtime service.

Capsize also provides `createFontStack`, which creates metric-based `@font-face` declarations for font fallbacks. The stated purpose is to improve alignment when a preferred web font is unavailable and a fallback font is rendered. The exact declarations depend on metrics for each font in the stack, so fallback setup is part of the same metadata-driven model as trimming.

## Installing @capsizecss/core and Creating a First Style

The README gives the core installation command for npm users. The example then imports metrics for Arial from the companion metrics package. Install the core package first, then add the metrics package when using named font metrics.

The following command installs the package documented in the README:

```bash
npm install @capsizecss/core
```

After installation, import `createStyleObject` and the metrics package shown in the example. This code requests a `fontSize` of 16, `leading` of 24, and Arial font metrics:

```ts
import { createStyleObject } from '@capsizecss/core';
import arialMetrics from '@capsizecss/metrics/arial';

const capsizeStyles = createStyleObject({
  fontSize: 16,
  leading: 24,
  fontMetrics: arialMetrics,
});
```

Apply the returned styles to the text element. The README warns against adding further layout-related styles to that same element, because those styles can interfere with the trim. A nested element is suggested when the outer element needs separate layout behavior:

```tsx
<div
  css={{
    ...capsizeStyles,
  }}
>
  My capsized text
</div>
```

For CSS-string output, the documented import and call are:

```ts
import { createStyleString } from '@capsizecss/core';
import arialMetrics from '@capsizecss/metrics/arial';

const capsizedStyleRule = createStyleString('capsizedText', {
  fontSize: 16,
  leading: 24,
  fontMetrics: arialMetrics,
});
```

The generated rule can then be placed in a stylesheet or style element under the specified class name.

## Choosing Metrics for Files, System Fonts, and Fallbacks

The quality of Capsize output depends on selecting the correct metrics source. The README presents three routes. For a Google Font or system font, install `@capsizecss/metrics` and import the named metrics. For a font supplied as a file, install `@capsizecss/unpack` and call `fromFile`. Alternatively, use the Capsize website to select a font and read its Metrics tab.

The file-based route returns metrics asynchronously:

```ts
import { fromFile } from '@capsizecss/unpack';

const metrics = await fromFile(filePath);
```

The documentation does not specify how to derive metrics for every custom or inaccessible font format. It also does not describe a workflow for automatically selecting metrics when `font-family` contains a system fallback chosen by the operating system. That makes metric coverage an adoption concern for teams using varied font stacks.

For fallback alignment, `createFontStack` needs metrics for each desired font. The README’s example names Lobster as the preferred web font and Helvetica Neue and Arial as fallbacks. The documentation says the generated `@font-face` declarations are intended to improve alignment and reduce layout shift associated with fallback differences. This is a narrower claim than saying that it removes all layout shift. Actual results still depend on the browser, the fonts available, and the CSS surrounding the component.

The repository package scripts also include metric generation, metric extraction, and unpacking generation commands. Those commands belong to repository development and release workflows, not to the basic consumer installation documented at the top of the README.

## Layout Conflicts and Cases Where Capsize Is Unnecessary

The most significant limitation is structural. Capsize generates styles that trim a text element’s font space, and the README warns that applying additional layout-related styles to the same element can interfere with the trim. A design system may still need margins, flex alignment, grid placement, or transitions on that element. The documented response is to use a nested element, but that changes the component structure and must be accounted for in styling and accessibility decisions.

Capsize also requires a decision about sizing semantics. A team that needs every text token to retain a strict CSS `font-size` should use `fontSize`. A team designing around visible capital-letter height can use `capHeight`, but that changes the relationship between typography tokens and the rest of the interface. Passing the wrong metrics or treating `capHeight` as a substitute for every notion of font size can produce a layout that matches the intended capital height while differing from the design specification elsewhere.

The project is not a complete typography system. The README does not document font loading, variable-font axes, localization-specific line breaking, text wrapping policy, or broad design-token management. It also does not document rollback. Its scope is metrics-based sizing, whitespace trimming, and related font fallback declarations. Teams that only need standard line spacing can use ordinary CSS and avoid adding this dependency.

## Manual CSS Versus Metric-Based Capsize Sizing

A realistic alternative is to define text sizing and spacing directly in CSS using `font-size`, `line-height`, and a carefully designed line box. That approach avoids font metadata imports and generated style objects. It can be a better fit for a small site, a content-only page, or a design system whose line spacing is already consistent across fonts.

Capsize takes a different approach. It reads font metrics and uses them to calculate the space that is not visually occupied by capital letters and the baseline area. A conventional CSS implementation treats the line box as the primary geometry. Capsize instead treats the visible cap height as a design reference and then trims the surrounding font space. That difference is meaningful for aligning headings with icons or aligning text to a grid, but it also introduces a metadata requirement and a stricter rule about competing layout styles.

The repository also includes a vanilla-extract integration, so Capsize is not limited to style-object spreading or hand-written style strings. Its practical value is greatest when the application already has a build-time TypeScript styling system and wants to generate metric-derived rules as part of that system.

## Maintenance, Releases, and MIT Adoption

The repository is not archived. Its last push was on 2026-10-15, and the release history shown for `@capsizecss/metrics` includes versions 4.2.0, 4.3.0, and 4.4.0 between July and October 2026. The available history therefore indicates recent package releases, although the README does not describe the release cadence or a support policy for older releases.

The repository license is MIT. That is the relevant licensing fact for adoption planning, although it does not answer questions about font licenses. Font files, system fonts, and downloaded web fonts can have separate usage terms. Teams should check the licensing of each font asset independently rather than treating the MIT license for the Capsize code as permission for every font included in a design.

Upgrade cost depends on which packages a project uses. The core package, metrics package, unpack package, and framework integration are separate concerns. The documented root scripts run workspace builds, generation, formatting, linting, and release preparation with pnpm, so contributors also need to account for the monorepo workflow when changing package source. The basic README installation, however, uses npm and exposes only the consumer-facing core package.

## Conclusion

Adopt Capsize when cap-height alignment, trimmed whitespace, or fallback consistency are concrete product requirements, especially in a CSS-in-JS interface. Do not adopt it for a small static site where ordinary CSS line-height is sufficient. Before choosing it, verify that the intended fonts have accurate metrics, decide whether cap height or font size is authoritative, and check how the generated layout styles interact with your component system. The repository is under the MIT license, and its most recent documented push was on 2026-10-15.

## FAQ

### How do I install Capsize for a TypeScript project?

The README documents installing `@capsizecss/core` with npm. If your text uses named font metrics, also use `@capsizecss/metrics`, as shown by the Arial example.

### Can Capsize size text by font size instead of cap height?

Yes. The `fontSize` option preserves an explicit CSS font size while Capsize applies the whitespace trimming. The README says to pass either `fontSize` or `capHeight`, not both.

### Where does Capsize get font metrics?

The README lists `@capsizecss/metrics`, `@capsizecss/unpack` with `fromFile`, and the Capsize website’s Metrics tab as sources for font metadata. The correct source depends on whether the font is a named web or system font or a file you control.

## Sources

- [License: MIT](https://github.com/seek-oss/capsize/blob/master/LICENSE)
- [Project website](https://seek-oss.github.io/capsize/)
- [README](https://github.com/seek-oss/capsize/blob/master/README.md)
- [Releases](https://github.com/seek-oss/capsize/releases)
- [seek-oss/capsize on GitHub](https://github.com/seek-oss/capsize)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/seek-oss-capsize
