The CSS font-size property
The CSS font-size property sets the size of text, e.g. font-size: 1.125rem;. Prefer rem units over px so the text scales with the reader's browser settings. For headings that adapt to screen size, clamp() lets the size grow and shrink between a minimum and maximum.
Overview
font-size sets how big an element's text is, and because it is inherited, it cascades down — set it on <body> and every element starts from that size unless it changes its own. It is also the anchor for the em unit and for line spacing, so it quietly affects more than just the characters themselves.
The unit you choose matters more than people expect. A fixed px size ignores the font size a reader has set in their browser, which is a real accessibility problem for anyone who has bumped it up. The rem unit sidesteps that: it is relative to the root font size, so your whole type scale grows and shrinks with the user's preference while staying perfectly in proportion. As a rule of thumb, 1rem is 16px in a default browser.
For headings that should feel big on a wide screen but not overwhelm a phone, clamp() is the modern answer. clamp(1.75rem, 4vw, 3rem) reads as "never smaller than 1.75rem, never larger than 3rem, and 4% of the viewport width in between" — fluid typography in a single line, no media queries.
Syntax
selector {
font-size: value;
}
/* fluid heading, no media query */
h1 {
font-size: clamp(1.75rem, 4vw, 3rem);
}
Values
The font-size property accepts the values below. Every property also accepts the CSS-wide keywords inherit, initial, revert and unset.
| Value | Description |
|---|---|
length |
An absolute or relative size such as 16px, 1rem or 1.25em. |
percentage |
A share of the parent's font size, e.g. 120%. |
keyword |
Named sizes: xx-small, x-small, small, medium, large, x-large, xx-large. |
smaller, larger |
One step down or up from the parent's size. |
clamp() |
A responsive size that scales with the viewport, e.g. clamp(1rem, 2.5vw, 1.5rem). |
Example
<style>
.s { font-size: 0.875rem; }
.m { font-size: 1.125rem; }
.l { font-size: clamp(1.5rem, 5vw, 2.5rem); }
p { margin: 0 0 8px; font-family: system-ui, sans-serif; }
</style>
<p class="s">0.875rem — small print.</p>
<p class="m">1.125rem — comfortable body text.</p>
<p class="l">clamp() — I grow and shrink with the screen.</p>
Best practices
- Use
remfor font sizes so text honors the reader's browser setting. Avoid pixel sizes for body copy. - Keep body text at roughly 1rem (about 16px) or larger — smaller defaults strain most readers.
- Build a small, consistent type scale (for example 1rem, 1.25rem, 1.5rem, 2rem) rather than picking arbitrary sizes per element.
- Use
clamp()for fluid headings instead of stacking media queries; it stays smooth at every width.
Accessibility
Font size is one of the most direct levers on readability. Sizing text in rem (or em) means it scales when a user increases their default font size or zooms — sizing it in px overrides that choice and can leave people unable to read comfortably. WCAG expects text to remain usable at 200% zoom, and relative units make that effortless.
Resist the urge to shrink text to fit a design. A larger base size with generous line spacing helps everyone, particularly readers with low vision or dyslexia. If space is tight, trim the words before you trim the size.
Frequently asked questions
What is the best unit for font-size in CSS?
rem is the safest default. It is relative to the root font size, so text scales with the reader's browser settings while keeping your type scale in proportion. Avoid px for body text.What is the difference between em and rem?
em is relative to the parent's font size, so it compounds when elements nest. rem is relative to the root element, so it stays predictable no matter how deep the element sits.How do I make font size responsive?
clamp(), e.g. font-size: clamp(1rem, 2.5vw, 1.5rem). The text grows with the viewport between a minimum and maximum, with no media queries.