Skills· Official
Accessibility
Make interfaces usable by everyone, including keyboard and screen-reader users — semantic HTML, labelled controls, visible focus, enough contrast, alt text — tested by keyboard and audit.
When to use it. When you build or change a page, form, dialog, menu, or any interactive component, and before launching a product that must meet WCAG or accessibility law.
Accessible interfaces are better for everyone: they work with a keyboard, a screen reader, a small screen, or tired eyes. Most of it comes from using the right HTML element and labelling things properly.
Steps
- Use the native element first.
<button>for actions,<a href>for navigation,<label>with<input>for fields, plus<select>,<dialog>, and<details>. They come with keyboard support, focus, and screen-reader roles built in. A clickable<div>has none of them. - Give every control an accessible name. Each input has a visible
<label for>— placeholder text isn't a label. Icon-only buttons get anaria-label. Link text says where it goes ("See pricing", not "click here"). - Make everything work by keyboard. Every interactive element is reachable with Tab in a logical order and works with Enter or Space. Menus and dialogs close with Escape; focus moves into a dialog when it opens and returns when it closes. Nothing traps focus.
- Keep focus visible. Never remove the outline without a replacement — style
:focus-visiblewith a clear ring. - Meet contrast. Text at least 4.5:1 against its background (3:1 for large text, and for icons and borders that carry meaning), in both light and dark themes. Never use color alone to signal meaning — add text or an icon to errors and states.
- Describe images. Meaningful images get
alttext that says what matters about them; decorative images getalt="". - Structure the page. One
<h1>, headings in order without skipping levels, landmarks (<header>,<nav>,<main>,<footer>), and alangattribute on<html>. - Announce what changes. Form errors are tied to their field with
aria-describedbyand written in text; status messages that appear without a page load usearia-live="polite". - Use ARIA only to fill gaps. If a native element does the job, use it. Wrong ARIA is worse than none.
- Respect people's settings. Honour
prefers-reduced-motion; text resizes to 200% without breaking the layout; nothing important is reachable only by hover.
Verify
- Put the mouse away: complete the main task with only the keyboard, watching the focus ring the whole way.
- Run an automated audit — axe DevTools, Lighthouse, or
npx @axe-core/cli <url>— and fix every violation. Automated tools catch only a share of issues, so the keyboard pass still matters. - Spot-check the main flow with a screen reader (VoiceOver on macOS: Cmd+F5).
Done when
- Every interactive element is a native control, or has a correct role, name, and keyboard behaviour
- Every form field has a visible label, and errors are announced in text
- The main task can be completed by keyboard alone, with focus always visible
- Contrast passes in light and dark themes
- The automated audit shows no violations
Report back
What you checked (the keyboard pass, the audit tool and its result, the screen-reader spot check), what you fixed, and any remaining issues with the WCAG criterion and who they affect.
Traps
- A
<div onClick>instead of a<button>. - Placeholder text as the only label.
outline: nonewith no focus style to replace it.- Treating a clean automated audit as proof that something is accessible.
More skills