Skip to content

Sizing now scales with the reader's font size

September 18, 2026 – By Dieter Luypaert

A reader who raises their browser’s font size expects the interface to grow with the text, not just the text. CDS only half did that: the dimension tokens have been rem for a while, but the sizing written by hand in component CSS — icon boxes, control heights, the width caps on text, and the spacing that never made it onto a token — was fixed px and stayed put.

That sizing is now rem as well. Set the browser to a larger font size and the components grow with it.

Nothing to change

There is no new API and no markup change. On the 62.5% root the tokens are designed against, every component renders pixel-identical to 7.6.1 — this only changes what happens when the root moves.

Some things stay px on purpose, because they shouldn’t grow with text:

  • Borders, focus rings and shadows. A hairline is a hairline at any text size.
  • Breakpoints. Layout switches on the viewport, not on type.
  • The touch-target minimum. Targets scale in rem but keep their 24px / 44px floor, so a small root can’t shrink a hit area below what a finger needs.

The root font size ships with the styleguide

The other half of this is the root itself. The generated token CSS emits every dimension as base-10 rem--tng-spacing-24 is 2.4rem — so the tokens only render at their design size on a 62.5% root, where 1rem = 10px. The legacy AEM clientlib has always set that. A host without it rendered every CDS dimension 1.6× too large.

The styleguide now ships that root itself:

:where(html) {
font-size: 62.5%;
}

It’s a fallback, never an override. It sits behind :where() in legacy, the lowest layer, so any host rule on the root still wins — an unlayered rule by layer, a legacy-layer html rule by specificity. The host stays in charge of the root.

So don’t set font-size on html or :root yourself. If you already do, nothing changes for you; if you don’t, you no longer need to.

Writing rem in component CSS

Hand-written CSS could previously only size in px, because typing a rem hard-codes the 10px root into the value. remOf() keeps px as the source of truth and compiles to rem at build time:

inline-size: remOf(20px); /* → 2rem */

The divisor lives in one place — REM_PX in figma-tokens — and ships as the --tng-rem token alongside every other one, so moving off 62.5% later is a change to that constant rather than a sweep through the CSS.

More on the root and what a host has to provide is on the Setup page.