Web features:
font-size
rem
em unit
line-height
overflow-wrap
text-wrap
text-wrap: balance
text-wrap: pretty
min(), max(), and clamp()
Viewport units
Logical properties
Hyphenation
ch unit
Overall best practices
- Use unitless numbers for
line-height(e.g.,1.5) to ensure relative scaling during font-size inheritance. - Use
overflow-wrap: break-word(oranywhere) to contain long URLs. - DON'T use
pxfor font-size. Preferremto honor the user's browser font-size preferences (root font size), orem/percentages for contextual sizing. - DON'T set a fixed
heightorblock-sizeon elements that contain text, such as buttons, badges, tabs and cards. Let the content set the height, withmin-block-sizeif a minimum is needed, so text doesn't overflow or get clipped when users increase text spacing to a line height of 1.5, spacing after paragraphs of 2em, letter spacing of 0.12em and word spacing of 0.16em (WCAG 1.4.12 Text Spacing requires no loss of content or functionality at these values).
Readability
- Avoid long lines of text: Cap paragraph blocks to a maximum of 80 characters width.
- Avoid rivers of whitespace: Avoid
text-align: justifyas it can make text harder to read. If you must use it, combine it withhyphens: autoto avoid excessive whitespace between words.hyphens: autoonly hyphenates text whose language is declared with thelangattribute, such as<html lang="en">. - Don't use Ornate fonts: Omit cursive typefaces for main reading content.
- Don't rely on all-caps for emphasis: Prefer bolding for visual emphasis, and use
<em>/<strong>when the emphasis is semantic. - Limit emphasis overall: Emphasis loses meaning when it's everywhere — apply it only where it changes how the content should be read.
- Support user zoom preferences: Allow users to resize text up to 200% without loss of content or functionality, and let text reflow at a 320 CSS px viewport width without horizontal scrolling (WCAG 1.4.10 Reflow); avoid
white-space: nowrapand fixed widths on running text.
body {
line-height: 1.5;
text-align: start; /* Supports LTR and RTL */
}
article {
max-width: 60ch; /* Caps line length to ~80 characters for readability (1ch is the width of "0", which is wider than most characters) */
}
Text wrapping
- Use
text-wrap: balancefor balanced headlines and headline-like content (e.g.<th>) - Use
text-wrap: prettyfor long-form body text (paragraphs, blockquotes, etc.) - Use
text-wrap: balanceortext-wrap: prettydeliberately, DO NOT apply it on*as it does have a performance cost. - Avoid
text-wrap: balanceon elements with a visible box (backgrounds, borders, shadows, etc) as it does not change the container's width, it only affects how text wraps within that width. This can leave empty space at the end of the container, which is usually undesirable.
Responsive Typography
- DO combine viewport-relative and font-relative units in
clamp()for font sizes that scale with the viewport size while ensuring they stay within a desired range. For example,clamp(2rem, 1rem + 5vw, 4rem). Adjust the proportion of viewport-relative and font-relative units to control how quickly the font-size changes. Use font-relative minimum and maximum values, and keep the maximum no more than 2.5 times the minimum. Viewport units don't grow when users zoom, so the text only grows once its minimum overtakes the viewport-based value; with a maximum no more than 2.5 times the minimum, browser zoom, which goes up to 500%, can still resize the text to 200% (WCAG 1.4.4 Resize Text requires text to resize up to 200% without loss of content or functionality). - DON'T use
vwalone for font-size withoutclamp(), as it can scale text too small or too large on extreme screens.