Styling content
CSS decides how your page looks, and good looks can still lock people out. Colour, size, and motion must hold up when someone zooms in, has weak vision, sees colours differently, or asks their device to calm down.
In one minute
- Contrast: normal text needs at least 4.5 : 1 against its background. Large text and icons need 3 : 1.
- Colour is never the only clue. Add text, an icon, or an underline next to it.
- Size in
rem, notpx, so the text grows when people change their browser setting or zoom. - Targets at least 24 by 24 CSS pixels (44 is kinder), and stop decorative motion when the user asks with
prefers-reduced-motion.
Imagine a road sign. If the letters are pale grey on a white sign, only people with perfect eyesight in perfect light can read it. If the sign says "turn" only by being red, drivers who cannot tell red from green miss it. If the sign is tiny, or spins, many people give up. CSS is the paint on your road signs. This lesson is about painting them so everyone can read them.
1. Contrast: how different are text and background?
Contrast ratio is a number from 1 (identical colours) to 21 (black on white). It compares how light the text is with how light the background is. WCAG 2.2 criterion 1.4.3 asks for 4.5 : 1 for normal text and 3 : 1 for large text (about 24 px, or about 19 px bold). Criterion 1.4.11 asks for 3 : 1 for icons, input borders, and focus rings. Weak contrast hurts people with low vision, but also anyone reading in sunlight or on a dim screen.
Lab: fade the text and watch the number
Step 1. Drag the slider. The text colour is a mix of the theme text colour and the background. The ratio is calculated live.
Orders placed before 14:00 leave the same day.
Contrast ratio: 21.0 : 1
A screen reader reads the words the same at any contrast. That is why contrast problems are easy to miss if you only test with your ears. Test with a checker (browser devtools show the ratio when you inspect a colour), and re-test in dark mode, which has its own colours. Gradients and background images need a check at the worst spot behind the text.
2. Colour is not the only channel
About 1 in 12 men and 1 in 200 women have some colour-vision difference. Others use a black-and-white display or a bright-sun screen. WCAG 1.4.1 says: do not use colour alone to show an error, a required field, a link, or a chart series. A screen reader user gets nothing from a colour either, so a text clue helps them too.
Lab: required field, with and without a text clue
Step 2. Pick the markup, then switch the view to grayscale to see what colour-blind or monochrome users see.
Read the shipping policy before you order.
Links follow the same rule. Links inside a paragraph should keep their underline (or another non-colour cue with 3 : 1 contrast). The lab toggles the underline too: the "text" version underlines the link.
3. Units: let the text grow
Many people raise their browser's default text size instead of zooming. A font size written in px ignores that setting.
A size in rem (a multiple of the root font size) respects it. WCAG 1.4.4 requires text to scale to 200% without losing content,
1.4.10 (Reflow) requires no sideways scrolling at 320 CSS pixels wide (that is 400% zoom on a desktop), and 1.4.12 requires that your layout survives
wider line, letter, and word spacing.
Lab: change the "browser default" and compare
Step 3. Pick a default text size, as if the user had set it in browser settings.
font-size: 16px ✕ ignores the setting
Delivery is free over 50 euros.
font-size: 1rem ✓ follows the setting
Delivery is free over 50 euros.
- Never lock a box height in
pxaround text. Usemin-height, padding, or let it grow. - Do not block zoom with
maximum-scale=1oruser-scalable=noin the viewport meta tag. - Do not set
user-select: noneon body copy. People select text to copy it, translate it, or have it read aloud.
4. Target size: can a thumb or a tremor hit it?
WCAG 2.2 criterion 2.5.8 (AA) asks for targets of at least 24 by 24 CSS pixels, or enough spacing around smaller ones. Criterion 2.5.5 (AAA) suggests 44 by 44. Small targets hurt people with hand tremors, people using a switch or head pointer, and anyone on a bumpy bus.
Lab: try to hit the small buttons
Step 4. Choose a size. Then click or tap the row of buttons, or Tab through them.
No rating chosen yet.
Make a small icon bigger without changing how it looks by adding padding to the button, not by growing the icon.
5. Motion: stop when asked
Spinning, sliding, and parallax effects can cause dizziness, nausea, or migraines for people with vestibular disorders. They also distract people with attention difficulties.
Operating systems have a "reduce motion" setting. CSS can read it with @media (prefers-reduced-motion: reduce).
Stop decorative motion. If motion carries meaning (a progress bar), keep the meaning and add text.
Anything that moves for more than 5 seconds needs a pause control (WCAG 2.2.2), and nothing should flash more than three times a second (2.3.1).
Lab: the spinner
Step 5. Flip the switch to pretend your device has reduce motion turned on.
Saving your draft (in progress)
@media (prefers-reduced-motion: reduce) {
.spin { animation: none; }
}
In devtools, open the Rendering panel and emulate prefers-reduced-motion: reduce to test the real thing.
Also check forced colours (Windows high-contrast mode): backgrounds and shadows are removed, so borders and text must still carry the design.
Common mistakes
| You see | Why it is a problem | Fix |
|---|---|---|
| Light grey placeholder or helper text | Below 4.5 : 1, unreadable for many. | Darken until the checker passes. |
| Red border as the only error cue | Invisible in grayscale and to screen readers. | Add text and an icon. |
font-size: 14px everywhere | Ignores the user's default size. | Use rem. |
| Links without underline in body text | Colour alone marks them. | Keep underline. |
| 16 px icon buttons side by side | Hard to hit, easy to mis-tap. | Pad to 24 px or more. |
| Infinite spinning decoration | Makes some people ill. | Honour prefers-reduced-motion. |
- Zoom this page to 400%. Does any text get cut off or force sideways scrolling?
- In devtools, emulate
prefers-reduced-motion: reduceand reload. The spinner in lab 5 should sit still. - Inspect a grey text colour and read the contrast ratio the devtools show.
Remember
- 4.5 : 1 for normal text, 3 : 1 for large text and UI parts. Check dark mode too.
- Never use colour alone. Pair it with words, icons, or underlines.
- Use
rem, allow zoom, let boxes grow. - Targets of 24 px or more; honour reduced motion.