CSS Letter Spacing Tool
Base sizes
Role table
| Role | Size | Tracking | px | Rule |
|---|---|---|---|---|
| Display / hero | 48px | -0.02em | -0.96px | Large sizes need negative tracking; the default rhythm is too airy. |
| H1 | 28.8px | -0.015em | -0.432px | Or the h1 body size, scaled. |
| H2 | 32px | -0.01em | -0.32px | First step where tracking should tighten. |
| H3 | 24px | 0em | 0px | The crossover point — leave at 0. |
| Body | 16px | 0em | 0px | Never track body text: it fights the designer's spacing. |
| Small / caption | 12.8px | 0.01em | 0.128px | A hair of positive tracking at small sizes. |
| Uppercase / caps | 14.4px | 0.05em | 0.72px | Always track uppercase; capitals are drawn to be spaced. |
| Button label | 14px | 0.025em | 0.35px | Half the uppercase bump if the label is sentence case. |
| Numeric / tabular | 16px | 0.01em | 0.16px | Separates digits in dense tables. |
Uppercase counter-example
Untracked uppercase crowds — Inter
Tracked uppercase breathes — Inter
:root {
--tracking-display-hero: -0.02em; /* Display / hero */
--tracking-h1: -0.015em; /* H1 */
--tracking-h2: -0.01em; /* H2 */
--tracking-h3: 0em; /* H3 */
--tracking-body: 0em; /* Body */
--tracking-small-caption: 0.01em; /* Small / caption */
--tracking-uppercase-caps: 0.05em; /* Uppercase / caps */
--tracking-button-label: 0.025em; /* Button label */
--tracking-numeric-tabular: 0.01em; /* Numeric / tabular */
}
.uppercase { letter-spacing: var(--tracking-uppercase-caps); text-transform: uppercase; }
.display { letter-spacing: var(--tracking-display-hero); }You Might Also Need
The CSS letter spacing tool writes the tracking values a stylesheet really needs: one per role, from a tight display setting to a positive uppercase bump, emitted as custom properties. Body text stays at zero on purpose, and the tool says so.
What is CSS Letter Spacing Tool?
The CSS letter spacing tool turns two base sizes and one uppercase bump into a full set of tracking tokens, one per text role, and exports them as custom properties with a role table explaining each value.
The role set covers the decisions a stylesheet actually makes.
- Display and hero roles take negative tracking, minus 0.02em, because large letterforms show their sidebearings as gaps.
- The first and second heading levels continue in the same direction, minus 0.015em and minus 0.01em, so the tightening is progressive rather than abrupt.
- Body text sits at exactly zero, which the panel states as a rule rather than a default: tracking body copy fights the spacing the type designer drew.
- Small text and captions take a hair of positive tracking, 0.01em, which is the rasterisation case rather than a stylistic one.
- Uppercase takes the bump value, adjustable from 0.01 to 0.15em, because capitals are drawn to be spaced and look crowded when set against each other.
- Button labels take half the uppercase bump when the label is sentence case, and tabular figures take the same small positive value as captions, to separate digits in dense tables.
Each row reports its size, its tracking in em and the same value converted to pixels at that size, which is what makes the numbers checkable: a tracking of 0.01em is a third of a pixel at 32 pixels of body text and a visible 0.14 at a 14 pixel uppercase label. The pixel column is also how the case gets made to a reviewer: a bare em value looks like a rounding error until it is converted into the gap it produces. The exported block names a custom property per role, derived from the role name, followed by a couple of usage examples for the uppercase and display cases. The counter-example beside it sets the same uppercase string twice, once untracked and once with the bump, which is the quickest way to show someone why caps need positive tracking at all.
The starting values are optical rules of thumb rather than measurements, and the tool is clear about the difference between a template and a specification.
- A condensed grotesque with tight sidebearings wants more uppercase tracking at small sizes than a wide geometric sans, so the bump is a starting point per family.
- A face with an unusually large x-height reads as crowded at the same nominal size, which shows up first in the small-text row.
- The role table is fixed at nine entries, so a design with a different set of roles maps the tokens onto them rather than adding rows.
- Every value is authored in em, so one letter-spacing declaration holds across every breakpoint while the pixel column stays a readout of what that means at each size.
- Nothing here replaces kerning: tracking acts on every gap in a run, so a bad pair inside a word needs the typeface's own kerning rather than a token.
The templates are deliberately plain values, which is what makes them easy to override when a face turns out to want something different.
How to use CSS Letter Spacing Tool
- Set the body and display sizes, since the pixel column is derived from them and is what makes the em values legible.
- Set the uppercase bump and watch the caps row and the button row move together, since one is half of the other.
- Read the role table and check the roles that sit at zero against the roles that are tracked, so the pattern is deliberate.
- Copy the token block and use the variables in component styles rather than retyping the values, then check the uppercase counter-example against a real label.
When to use CSS Letter Spacing Tool vs related tools
Reach for it when a stylesheet needs tracking values as a system rather than as one-offs, when uppercase labels look cramped at small sizes, or when several heading levels are being tuned and the tracking should tighten progressively instead of being decided per component. The zero for body text is the rule to keep. For converting a single value between units, the letter spacing calculator handles em, pixels and design-tool tracking; the font letter spacing tester shows the values on real text, and the CSS typography token generator exports the sizes these tokens are applied at.
Privacy & Security
This tool runs entirely in your browser — no data ever leaves your device. There is no server round-trip, no upload, no logging, and no account required. Your input is processed locally using client-side JavaScript and is never stored, transmitted, or accessible to anyone else. When you close the tab, everything disappears.