CSS Reference
font-size
Controls the size of text. Five unit types, infinite possibilities, one accessibility rule.
Last updated: October 2026
Definition: The font-size property sets the size of text. It accepts absolute units (px, pt), relative units (em, rem, %), and viewport units (vw, vh). Modern CSS often uses clamp() for fluid typography that scales smoothly with the viewport width.
🎬 Live Example
The same sentence at five different font sizes.
12px — Too small for body text
14px — Small, used for UI labels
16px — The standard body size (1rem)
20px — Subheading size (1.25rem)
32px — Heading size (2rem)
Fluid: clamp(1rem, 3vw, 2rem) — resizes as you resize the browser
💡 16px is the accepted minimum for body text. Smaller sizes only for labels and captions.
Basic Syntax
p {
font-size: 16px; /* Absolute */
}
h1 {
font-size: 2rem; /* Relative to root */
}
.lead {
font-size: 1.25em; /* Relative to parent */
}
.hero {
font-size: clamp(2rem, 5vw, 4rem); /* Fluid */
}
🎯 Every font-size Unit
| Unit | Relative to | Best for |
|---|---|---|
px | Absolute pixels | Fixed elements (borders, shadows) |
rem | Root font size (16px default) | Everything (body, headings, spacing) |
em | Parent element font-size | Component-relative sizing |
% | Parent element font-size | Same as em in most cases |
vw | Viewport width (1vw = 1%) | Fluid typography (with clamp) |
vh | Viewport height | Rarely used for font-size |
pt, pc | Print typography (72pt = 1in) | Print stylesheets only |
rem vs em — The Difference
Both are relative, but to different things.
html {
font-size: 16px; /* The root size */
}
.parent {
font-size: 20px; /* Local override */
}
/* rem: relative to */
.rem-child {
font-size: 1.5rem; /* = 1.5 × 16px = 24px */
}
/* em: relative to the parent's font-size */
.em-child {
font-size: 1.5em; /* = 1.5 × 20px = 30px */
}
💡 Rule: Use rem for consistency across components. Use em when you want a component to scale relative to its own font-size (like buttons with padding in em).
Why px Hurts Accessibility
Users with visual impairments change their browser's default font size. px ignores that setting. rem respects it.
/* ❌ Ignores user preference */
p {
font-size: 16px;
}
/* ✅ Respects user preference */
p {
font-size: 1rem;
}
Accessibility: WCAG requires that text scale up to 200% without breaking layout. Using px blocks this. Always use rem for text.
Fluid Typography with clamp()
Smooth scaling between two sizes, no media queries.
h1 {
/* min: 2rem, preferred: scales with viewport, max: 4rem */
font-size: clamp(2rem, 5vw, 4rem);
}
h2 {
font-size: clamp(1.5rem, 3vw, 2.5rem);
}
body {
font-size: clamp(1rem, 0.95rem + 0.25vw, 1.125rem);
}
How clamp works: clamp(min, preferred, max). The browser picks the preferred value, but never goes below min or above max.
👉 Full guide: CSS clamp() Fluid Typography.
A Complete Type Scale
A production-ready scale using rem and clamp.
:root {
--fs-xs: 0.75rem; /* 12px — captions, labels */
--fs-sm: 0.875rem; /* 14px — small UI text */
--fs-base: 1rem; /* 16px — body */
--fs-lg: 1.125rem; /* 18px — lead paragraphs */
--fs-xl: 1.25rem; /* 20px — subheadings */
--fs-2xl: 1.5rem; /* 24px — section headings */
--fs-3xl: 2rem; /* 32px — page headings */
--fs-4xl: clamp(2rem, 4vw, 3.5rem); /* Hero */
}
body { font-size: var(--fs-base); }
small { font-size: var(--fs-sm); }
h1 { font-size: var(--fs-4xl); }
h2 { font-size: var(--fs-3xl); }
h3 { font-size: var(--fs-2xl); }
.lead { font-size: var(--fs-lg); }
🎯 Keyword font-size Values
CSS also accepts named sizes, which map to specific pixel values in browsers.
| Keyword | Approx. size | Use |
|---|---|---|
xx-small | ~9px | Rarely used |
small | ~13px | Footnotes |
medium | ~16px (default) | Body |
large | ~18px | Lead paragraphs |
x-large | ~24px | Subheadings |
xx-large | ~32px | Large headings |
Keywords are consistent in modern browsers, but you should use rem or clamp() for precision.
⚠️ Common Mistakes
- Using px for body text. Ignores user browser settings. Use
rem. - Nesting em inside em. Sizes compound — 1em inside 1.5em parent = 1.5em. Easier to use rem for clarity.
- Body text below 16px. Hurts readability and fails accessibility on many devices.
- No defined type scale. Random sizes across the site look inconsistent. Define a scale with CSS variables.
- Overusing vw without clamp. A pure
vwfont-size can become unreadable on narrow or very wide screens. - Not testing with zoom. Browser zoom should scale the layout without breaking. rem-based sizes handle this correctly.
- All-caps with small font. All-caps text should be larger than normal for readability. Small all-caps is a known accessibility failure.
♿ Accessibility Notes
- Body text must be at least 16px (1rem). Smaller sizes strain readability, especially on mobile.
- Use rem for text. It respects the user's browser font-size settings.
- Support 200% zoom. WCAG requires layouts to remain functional at 200% zoom. rem-based sizing makes this automatic.
- Line height matters as much as font-size. 1.5–1.7 for body text improves readability.
- Avoid all-caps for long text. All-caps is harder to read because there are no ascenders/descenders. Reserve for short labels.
- Test on real devices. Mobile screens have different pixel densities. What looks right on a 4K monitor may be tiny on a phone.
❓ Frequently Asked Questions
What is the CSS font-size property?
The font-size property sets the size of the text. It accepts absolute units (px, pt), relative units (em, rem, %), and viewport units (vw, vh). Modern CSS often uses clamp() for fluid typography that scales with the viewport.
What is the difference between em and rem?
em is relative to the parent element's font-size. rem is relative to the root (html) font-size. Use rem for consistency and predictability. Use em when you want sizing to cascade with a component's own font-size.
What is the best font-size unit for accessibility?
rem is the best choice for accessibility. It respects the user's browser font-size setting. px does not scale with user preferences. Use rem for body text and headings.
What is a fluid font-size?
Fluid font-size uses clamp() to interpolate between a minimum and maximum size based on the viewport width. Example: font-size: clamp(1rem, 2vw, 1.5rem). It scales smoothly without media queries.
What is the minimum readable font size?
16px (1rem) is the widely accepted minimum for body text. Anything smaller strains readability, especially on mobile. Headings can be larger; UI labels and captions should stay at or above 14px.