Accessibility and CSS
Prerequisites: Responsive design and media queries
CSS can make an accessible page unusable — or make a good one excellent.
Contrast
- Text: at least 4.5:1 against its background (3:1 for large text, about 24px, or 18.7px bold).
- Interface components and focus indicators: at least 3:1 against adjacent colors.
- Check text over images and gradients at their lightest point.
- Placeholder text and disabled states are common failures.
Visible focus
:focus-visible {
outline: 3px solid var(--focus, #f5a623);
outline-offset: 2px;
}
.card:has(a:focus-visible) {
outline: 3px solid var(--focus, #f5a623);
}
Never remove outlines without a replacement. outline is also kept in
forced-colors mode, where box-shadow focus rings disappear.
Respect user preferences
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
@media (forced-colors: active) {
.button { border: 1px solid ButtonText; }
.icon { forced-color-adjust: auto; }
}
prefers-reduced-motion— the durations are near zero rather thannone, soanimationend/transitionendevents still fire for scripts that wait for them.forced-colors(Windows contrast themes) replaces your colors with the user's system colors. Backgrounds disappear, so shapes defined only by background color (buttons, toggles) need a real border.
Zoom and text resizing
- Size text in
rem; never block zooming. - Layouts must work at 400% zoom (a 320-pixel-wide viewport) without horizontal scrolling for normal text content — WCAG's "reflow" requirement.
- Don't set fixed heights on text containers; let them grow.
- Line height at least 1.5 for body text, and text must survive users
overriding
letter-spacingandword-spacing.
Visual order vs DOM order
order, flex-direction: row-reverse, grid-auto-flow: dense, and
explicit grid placement can make the visual order differ from the source
order that keyboard and screen-reader users follow. Keep them matching.
(The new reading-flow property lets focus follow the visual order of
flex and grid items; support is still limited to Chromium.)
Hiding content correctly
| Goal | Use |
|---|---|
| Hide from everyone | display: none or the hidden attribute |
| Hide visually, keep for screen readers | A .visually-hidden class |
| Hide decorative content from screen readers | aria-hidden="true" in the HTML |
content in ::before/::after may be read aloud — don't put
decorative emoji there without an empty alternative
(content: "✨" / "").
Target sizes
Make interactive targets at least 24 × 24 CSS pixels (WCAG 2.2 AA), ideally 44 × 44 on touch screens. Padding on links and buttons counts.
Test
Use DevTools' Rendering panel to emulate reduced motion, forced colors, dark mode, and color vision deficiencies; zoom to 400%; and check contrast with the color picker in the Styles panel.