Dotted pixel art in copper, slate blue and near black, with broad diagonal bars crossing the frame.

Accessible font sizing in CSS

Author
gunlaug team
Updated
8 Nov 2026
Reading time
8 min

Photo by Erik Mclean

Some readers set a larger default font size in their browser. We changed that setting in Chrome and Firefox and measured which CSS follows it and which ignores it.

Check your own browser

The number below is read from this page, which sets no font size on html. The slider shows the same three rules at other default sizes.

Your browser’s default font size right now: checking

font-size: 16px renders at 16px

The quick brown fox reads this at whatever size suits it.

font-size: 1rem renders at 16px

The quick brown fox reads this at whatever size suits it.

html { font-size: 16px } and font-size: 1rem renders at 16px

The quick brown fox reads this at whatever size suits it.

To change the real setting:

  • In Chrome, go to Settings, then Appearance, then Font size. For a finer slider, open chrome://settings/fonts.
  • In Firefox, open Settings and search for “fonts”. Size is in that section.
  • Safari on the Mac documents a minimum font size only, which is a different setting. It’s covered further down.

Which CSS follows the setting

We set the browser default to 16, 20, 24 and 32 pixels and read the computed size of each value. The viewport was 1000 pixels wide and the page set no font size on html. Chrome and Firefox returned the same size for every value.

Computed font size in pixels at each browser default
CSS valueDefault 16Default 20Default 24Default 32
16px16161616
1rem16202432
0.875rem1417.52128
1em16202432
100%16202432
medium16202432
2vw20202020
calc(1rem + 1vw)26303442
clamp(16px, 1.6vw, 24px)16161616
clamp(1rem, 0.5rem + 1vw, 1.5rem)18202432

Text in rem, em, percent or the medium keyword doubled when the default doubled. Text in pixels stayed at 16, and 2vw stayed at 20, because neither has anything to do with the reader’s font size.

The same sentence at font-size: 16px and font-size: 1rem in Chrome with a 32 pixel default font size. The 16px text stays small on two lines. The 1rem text is twice the size and wraps onto four lines.

Use rem at both ends of clamp()

clamp(16px, 1.6vw, 24px) never moved, since nothing inside it depends on font size. clamp(1rem, 0.5rem + 1vw, 1.5rem) went from 18 to 32 pixels across the same range. A sum like calc(1rem + 1vw) follows the setting only in part: it went from 26 to 42 when the default doubled, because the vw half stays fixed.

A fixed size on html cancels it

html { font-size: 16px } looks harmless, since 16 is the default for most people anyway. In our test it held every rem on the page at 16 pixels, whatever the reader had chosen.

What 1rem computed to, by the rule on html
Rule on htmlDefault 16Default 24Default 32
no rule162432
font-size: 100%162432
font-size: 62.5%101520
font-size: 16px161616
font-size: 10px101010

Setting html to 100% matched having no rule at all in every measurement, so you don’t need that line.

What about 62.5%?

The trick makes 1rem equal 10 pixels so the arithmetic is easy, and it does follow the setting: at a default of 24, 1rem was 15. The cost is everywhere else. Text you don’t size yourself, third-party widgets included, starts from 10 pixels. Our 1em and 100% samples both computed to 10. It also causes the minimum font size problem described below. Round numbers aren’t worth that, so we’d leave it out.

When to use rem and when to use em

  • Use rem for font sizes, so a size means the same thing anywhere on the page.
  • Use em for things that should scale with the text next to them, such as an icon inside a button or the padding around a label.

em font sizes multiply as they nest. Three levels of 0.875em computed to 10.72 pixels at a default of 16, while the same value in rem stayed at 14.

Write media queries in em

With a pixel breakpoint, the layout has no idea the text got bigger. In a window 1000 pixels wide with a default of 24, min-width: 800px still matched. min-width: 50em did not, because 50em had become 1200 pixels.

Whether each query matched in a 1000 pixel wide window
Media queryDefault 16Default 20Default 24Default 32
(min-width: 800px)MatchesMatchesMatchesMatches
(min-width: 50em)MatchesMatchesNo matchNo match
(min-width: 50rem)MatchesMatchesNo matchNo match

A reader with larger text gets the narrower layout, which is usually the one that still fits. rem behaved the same as em here, and neither looks at your CSS: the Media Queries spec says relative units in a query “are based on the initial value”. With html at 62.5% and a default of 24, 50rem still failed to match at 1000 pixels. It would have matched if the rule on html had counted.

Minimum font size is a separate setting

The default size scales all relative text. A minimum only lifts text that falls below a floor, and it affects pixel sizes too. The catch is that rem lengths don’t always lift with it.

Size 1rem text was drawn at, next to a box with width: 1rem
Browser, rule on html, minimum1rem text drawn1rem box width
Chrome, no rule, min 121616
Chrome, 62.5%, min 121210
Firefox, 62.5%, min 121210
Chrome, no rule, min 242416
Firefox, no rule, min 242416

When the two numbers differ, an icon or gap sized in rem stops matching the text beside it. With html at 62.5%, a minimum of 12 pixels was enough to cause that. With no rule on html, a minimum of 12 left 1rem text alone. A minimum of 24 splits them in both browsers whatever you do, and you can’t prevent that from CSS.

Firefox has a long-running report on this, bug 816948, about rem following the minimum setting. It was marked reopened when we checked on 8 November 2026. Firefox 159 did not do that in our run: the 1rem box stayed at the smaller size.

Dotted pixel art of dark hills reflected in a still lake under a pale blue sky.Photo by eberhard grossgasteiger

What WCAG actually requires

Success Criterion 1.4.4 says text can be resized “up to 200 percent without loss of content or functionality”. It sets no minimum font size and doesn’t name a unit. W3C’s explanation says one working scaling mechanism is enough and lists browser zoom as a sufficient technique, so text in pixels is not a failure on its own.

Relative units are still the better choice because zoom and the font setting serve different people. Zoom is usually set site by site and enlarges everything. The default font size applies to every site at once. At the Internet Archive, 3.08% of visitors had a default other than 16 pixels in 2018. That is one site, eight years ago, and the only public measurement we found.

The CSS to use

/* No font-size on html. */
body { font-size: 1.125rem; line-height: 1.6; }
h1 { font-size: clamp(2rem, 1.5rem + 2vw, 3.5rem); }
.note { font-size: 0.875rem; }
.icon { width: 1em; height: 1em; }

@media (min-width: 50em) {
  /* wider layout */
}

Then check it in a real browser:

  1. Set Chrome’s font size to Very large and reload the page.
  2. Look for text that stayed small, since that text is set in pixels.
  3. Look for text that overflows or is clipped in fixed-height boxes.
  4. Put the setting back and zoom to 200 percent, which is the WCAG check.

How this was tested

A script loaded the same test page in each browser and each setting on 8 November 2026, in a 1000 by 800 pixel window on Windows 11, and recorded computed sizes, drawn text widths and media query matches.

  • Chrome 156.0.8078.80, headless, with the default and minimum set in its profile.
  • Firefox 159.0.1, headless, with the same settings as preferences.
  • WebKit 26.0 from Playwright, at its unchanged default only, because this build offers no font size setting. At that default it matched Chrome on every value. This WebKit build is not Safari, and nothing here was run on an iPhone.

Browser zoom was not part of the run. The full output is available as raw JSON. The test script and this article were prepared with help from AI.

How this used to work

Internet Explorer’s Text Size menu wouldn’t resize text set in pixels, and that was still true of IE7. Old advice insists on em and percent for that reason. Page zoom, which also scales pixels, has since removed most of that problem, so the case for relative units today is the font setting and the media queries above.

Common questions

Is 16px the minimum size for body text?

No. WCAG sets no minimum. 16 pixels is the starting default: Chrome, Firefox and WebKit all returned 16 with the setting unchanged.

Should padding and widths be in rem too?

Spacing around text should be, so it grows along with the text. Borders can stay in pixels.

Does zoom make any of this unnecessary?

It covers WCAG 1.4.4. It doesn’t help someone who has set a larger default for every site and expects yours to respect it.

Sources