</> ConvertAtlas Developer Tools
Level 3 · Advanced — Modern CSS Lesson 37 Advanced 14 min

Accessibility-Focused CSS

Focus states, reduced motion, colour contrast and visually-hidden patterns done right.

Accessibility is not a feature you bolt on — it is part of writing good CSS. A few habits make your interfaces usable by people with disabilities and better for everyone. These are expected of professional work.

Visible focus with :focus-visible

Keyboard users need to see which element is focused. Never remove outlines without a replacement. <code>:focus-visible</code> shows a focus ring for keyboard users but not on mouse clicks — the best of both worlds.

HTML
<button class="btn">Tab to me</button>
CSS
.btn{padding:10px 18px;border:0;border-radius:9px;background:#2563eb;color:#fff;cursor:pointer}
.btn:focus-visible{outline:3px solid #93c5fd;outline-offset:2px}
Result
A focus ring that appears for keyboard users.

Respecting reduced motion

Some people experience nausea or distraction from motion. The <code>prefers-reduced-motion</code> media query lets you disable or soften animations for them. Wrap non-essential motion in a guard, or globally reduce it.

css
@media (prefers-reduced-motion: reduce) {
  *, ::before, ::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}

Colour contrast

Text must have enough contrast against its background — at least 4.5:1 for normal text, 3:1 for large text (WCAG AA). Light grey on white may look elegant but is unreadable for many. Always check contrast, and never use colour as the only signal (pair it with text or icons).

Visually-hidden text

Sometimes you need text for screen readers but not on screen (like a label for an icon button). The visually-hidden pattern hides it visually while keeping it accessible — do not use <code>display: none</code>, which hides it from everyone.

css
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0);
  white-space: nowrap; border: 0;
}
Common mistake
Don't
.label { display: none; }
Do
.label { /* visually-hidden pattern */ }

Using display: none to hide text for screen readers — it removes it from everyone, including assistive tech. Use the visually-hidden pattern instead.

Best practice

Always provide visible :focus-visible styles, honour prefers-reduced-motion, meet 4.5:1 contrast, never rely on colour alone, and use visually-hidden for screen-reader-only text. These are baseline professional requirements.

Try it yourself

Add a :focus-visible ring to a button, write a prefers-reduced-motion guard that disables an animation, and add a .visually-hidden label to an icon-only button.

Quick quiz

1. What shows focus for keyboard users but not mouse clicks?

2. Minimum contrast for normal text (WCAG AA)?

3. How to hide text but keep it for screen readers?

Key takeaways
  • Provide visible :focus-visible styles — never remove outlines bare.
  • Honour prefers-reduced-motion for non-essential animation.
  • Meet 4.5:1 contrast and never use colour as the only signal.
  • Use the visually-hidden pattern, not display:none, for SR-only text.