7 CSS Typography Features You Didn’t Know Existed (2026)

CSS has quietly picked up a set of typography tools that used to need JavaScript, image hacks or a lot of patience. Here are seven that work in real browsers today, each with the code to copy and a live demo running in your browser right now.

Support notes are correct as of September 2026. We’ll update this list as new properties arrive. If a demo’s two panes look the same, your browser doesn’t support that feature yet, which is also a demo of how gracefully it falls back.

1. text-box: trim the empty space around text

Every font carries extra space above its capitals and below its baseline. That’s why text in a button never looks quite centred, and why a heading never lines up with the top of the image beside it. text-box trims that space away, so the box ends exactly at the cap height and the baseline.

.button {
  text-box: trim-both cap alphabetic;
  padding: 0.75em 1.25em; /* now the padding is what you actually see */
}

trim-both trims the top and bottom; cap alphabetic says where to cut. Use trim-start on a heading to line it up with an image.

DefaultBook now
text-box: trim-both cap alphabeticBook now
Same padding on both buttons. Without trimming, the capitals sit high; with it, they're centred.

Support: Chrome and Edge 133+, Safari 18.2+, Firefox 154+. Older browsers just keep the extra space.

2. initial-letter: real drop caps

Drop caps used to mean floats, magic font sizes and nudging with negative margins until it looked right in one browser. initial-letter sizes the letter to span a number of lines and lines it up with the text for you.

.article > p:first-of-type::first-letter {
  -webkit-initial-letter: 3;
  initial-letter: 3;
  margin-inline-end: 0.5rem;
  font-family: "Playfair Display", serif;
}

3 makes the letter three lines tall and sinks it three lines. 3 2 makes it three lines tall but sinks it only two, so it rises above the paragraph.

font-size: 3.2em

Typography is the craft of endowing human language with a durable visual form, and with it an independent existence.

initial-letter: 3

Typography is the craft of endowing human language with a durable visual form, and with it an independent existence.

Making the letter bigger just stretches the first line. initial-letter sinks it neatly into the first three lines.

Support: Chrome and Edge 110+. Safari needs the -webkit- prefix, as above. Firefox shows a normal first letter, which is a perfectly good fallback.

3. size-adjust: make the fallback font match

While a web font loads, the browser shows a fallback font. When the real font arrives, every line reflows and the page jumps. You can prevent that by declaring a fallback that has been resized to take up the same space as your web font. Here’s Georgia tuned to stand in for Lora:

@font-face {
  font-family: "Lora Fallback";
  src: local("Georgia");
  size-adjust: 104.98%;
  ascent-override: 95.83%;
  descent-override: 26.1%;
}

body {
  font-family: "Lora", "Lora Fallback", serif;
}

Don’t measure these numbers by hand. We got them from Capsize; Fontaine does the same job, and Next.js’s next/font does it automatically.

Web font and its fallback

Pack my box with jugs

Pack my box with jugs

Pack my box with jugs

The same words in Lora, in plain Georgia, and in Georgia with the @font-face above. Plain Georgia is narrower, so every line reflows when Lora arrives. Adjusted, it takes up the same space and nothing moves.

Support: size-adjust works in every modern browser. The -override descriptors work in Chrome, Edge and Firefox but not Safari, where you still get most of the benefit from size-adjust.

4. font-size-adjust: match x-heights across fonts

Two fonts set at the same font-size can look very different in size, because what your eye reads is the x-height (the height of the lowercase letters). This is most obvious when you drop a monospace or serif font into a sans-serif paragraph. font-size-adjust scales fonts so their x-heights match:

body {
  font-family: Verdana, sans-serif;
  font-size-adjust: 0.545; /* Verdana's x-height, as a fraction of its size */
}

Everything inside inherits that number, so a word in another font is scaled to Verdana’s x-height too. font-size-adjust: from-font reads the number from whichever font is actually showing, and cap-height 0.73 matches capitals instead, which suits all-caps labels.

Default

Verdana with a Times New Roman word in it.

font-size-adjust: 0.545

Verdana with a Times New Roman word in it.

Same font size throughout. Adjusted, the Times word grows to match Verdana's x-height.

Support: Baseline since 2024, so it works in every current browser.

5. lh and rlh: spacing measured in lines

1lh is the element’s line height; 1rlh is the root element’s line height. Spacing measured in lines gives you vertical rhythm without doing the maths:

p {
  line-height: 1.6;
  margin-block: 0 1lh;     /* exactly one blank line between paragraphs */
}

h2 {
  margin-block: 2rlh 1rlh;
}

.teaser {
  max-height: 3lh;         /* exactly three lines tall */
  overflow: hidden;
}

If you change the font size or line height, the spacing follows.

margin-bottom: 20px

Spacing measured in pixels drifts away from the lines.

By the second paragraph, the text no longer sits on the grid.

margin-bottom: 1lh

Spacing measured in lines stays on the grid.

Every paragraph starts exactly one line after the last.

The pink rules are drawn every 1lh.

Support: every current browser (Chrome 109+, Safari 16.4+, Firefox 120+).

6. hanging-punctuation: optical margins

In a printed book, an opening quote mark sits just outside the text column, so the letters form a clean left edge. On the web, the quote mark pushes the first line in and the edge looks ragged. hanging-punctuation moves it into the margin:

blockquote,
.article p {
  hanging-punctuation: first allow-end last;
}
Default

“The letters should line up, not the punctuation,” as every typesetter knows.

hanging-punctuation

“The letters should line up, not the punctuation,” as every typesetter knows.

The pink line is the edge of the text. In Safari, the quote mark hangs outside it and the letters line up.

Support: Safari only, and that’s why hardly anyone knows about it. It’s harmless elsewhere, so add it anyway: Safari readers get the book-quality edge and everyone else sees what they saw before.

7. font-synthesis: none: stop fake bold and italics

If you ask for a weight or style you haven’t loaded, the browser fakes it by smearing the regular weight thicker or slanting it. The classic trap is loading a single-weight display face for your headings: h1 is bold by default, so the browser fakes a bold version and the letters come out blurry and heavy.

h1 {
  font-family: "League Gothic", sans-serif;
  font-weight: 400;          /* ask for the weight you actually loaded */
  font-synthesis: none;      /* and never fake one */
}

Set the weight you loaded, and add font-synthesis: none so that a mistake shows up as the wrong weight instead of a smeared one. You can switch off only one part with font-synthesis-weight or font-synthesis-style.

Default

Bold and italic

font-synthesis: none

Bold and italic

This page loads Source Code Pro in a single light weight with no italic. Asked for bold italic, the browser fakes both on the left; on the right it shows the font as it really is.

Support: every modern browser.

A few sites in the Typ.io library already switch synthesis off:

Support at a glance

  1. text-box: Chrome, Edge, Safari and Firefox (all recent).
  2. initial-letter: Chrome, Edge, and Safari (prefixed). Not Firefox.
  3. size-adjust: everywhere. The -override descriptors: not Safari.
  4. font-size-adjust: everywhere.
  5. lh / rlh: everywhere.
  6. hanging-punctuation: Safari only.
  7. font-synthesis: everywhere.

All seven degrade gracefully, so you can use every one of them today.

Close