font-size in CSS: picking the right unit for text that reads well everywhere

font-size sets text size in px, em, rem or clamp(), and the unit you pick has real consequences for accessibility.
5 min read
Believemy logo

Text size is often the very first setting people touch in CSS, and one of the most misunderstood. Setting font-size in pixels feels like the simplest choice, but that exact choice is what quietly breaks accessibility for a share of visitors.

font-size sets the text size of an element, and that size also becomes the reference unit for anything expressed in em inside that element. Understanding how the browser computes this value prevents overflowing headings, unreadable text on mobile, and interfaces that ignore a visitor's own settings.


Definition

font-size accepts several kinds of values: a fixed size in pixels, a relative size in em or rem, a percentage, or, more recently, a fluid value computed with clamp().

CSS
h1 {
  font-size: 32px;
}

p {
  font-size: 1rem;
}

With no CSS rule at all, every browser renders text at 16 pixels by default. That value is not arbitrary: it is the reference size every relative unit is built on, starting with rem and em.


px, rem and clamp(): three ways to size text

A pixel gives the same size everywhere, no matter the visitor's own settings. rem is computed relative to the font size of the root html element, the one a visitor can change in their browser or system settings. clamp() combines a minimum value, a preferred value that scales with screen width, and a maximum value.

UnitComputed relative toRespects the visitor's settings
pxNothing, an absolute valueNo
remThe font size of htmlYes
clamp()A range between two bounds, based on screen widthDepends on the units used inside it
CSS
h1 {
  /* Never smaller than 1.75rem, never larger than 3rem,
     and a value that tracks screen width in between */
  font-size: clamp(1.75rem, 4vw + 1rem, 3rem);
}

This heading stays readable on a small phone, grows gradually on a tablet, then settles down on a large screen instead of scaling forever. That is the most common use of clamp(), min() and max() in modern CSS: replacing a series of Media query rules that redefine the size at each breakpoint with a single line that adapts continuously.


The accessibility trap

A visitor with low vision can ask their browser or their operating system to enlarge all text, without having to zoom in on every page they visit. That setting acts on the reference font size, so it affects everything expressed in rem or em. Text fixed in pixels stays exactly at its original size and completely ignores that setting.

Good to know

Regular browser zoom, the Ctrl-plus-scroll shortcut, enlarges everything, pixels included, which hides the problem during manual testing. It is the dedicated text-size setting available on some browsers and mobile systems that reveals the gap: only that setting distinguishes relative sizes, which scale, from pixel sizes, which stay fixed.

That is exactly why most accessibility guidelines recommend expressing font-size in rem rather than pixels for body content, reserving pixels for details that genuinely need to stay fixed no matter what, like the width of a one-pixel border.


The 16-pixel baseline

Because 1rem equals 16 pixels by default, converting in your head is easy: 0.875rem is 14 pixels, 1.5rem is 24 pixels, 2rem is 32 pixels. Some teams redefine the root size, for example html { font-size: 62.5%; } to bring 1rem down to 10 pixels and simplify the mental math, but that trick has a cost: it shrinks all text on the page by 37.5 percent for a visitor who never asked for that, and it makes the code harder to read for anyone unfamiliar with the convention.


Frequently asked questions

Question

Should pixels be banned entirely from font-size?

No, but reserve them for specific cases where a fixed size is genuinely intended, like an icon calibrated to the exact pixel. For text visitors actually read, rem and em remains the recommended choice, precisely because it respects their display preferences.

Question

What is the difference between em and rem for a text size?

em is computed relative to the font size of the nearest parent element, which can create a compounding effect when several nested levels all use em. rem is always computed relative to the root html element, which gives a more predictable result in a complex layout.

Question

Why does my site look smaller after changing the root font size?

If html gets a font size below 16 pixels, every rem value on the site shrinks along with it, including ones that seemed unrelated to text, like spacing or icon sizes defined in rem for consistency.

Question

Does clamp() fully replace media queries for text size?

It replaces most simple cases of text that grows with the screen, but a Media query is still useful for bigger changes, like rearranging an entire layout or switching an aspect ratio at a specific breakpoint.

Related terms

Discover our hTML and CSS glossary

Browse the terms and definitions most commonly used in HTML and CSS development.

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.