Accessibility basics for interfaces
Sep 18, 2026 · Accessibility · 4 min read
Put your mouse in a drawer and try to use your own product with only the keyboard for ten minutes. Within the first minute most people find a place where focus vanishes, a control they cannot reach, or a dialog they cannot escape. It is the fastest accessibility audit there is.
Accessibility gets treated as a big audit project, so it keeps getting postponed. In practice most of the problems in a typical product come from a short list of habits. Fix these and you cover a large share of what keyboard, screen reader and touch users run into.
Keep the focus ring, just style it
Removing the outline is the most common accessibility bug on the web. Keyboard users lose track of where they are. The reason people remove it is that it shows up on mouse clicks too; :focus-visible solves that, because the browser only matches it when focus should be visible, which in practice means keyboard use.
:focus-visible {
outline: 2px solid var(--color-accent-solid);
outline-offset: 2px;
}Use the native element
A <div onClick> looks like a button but cannot be reached with Tab, does not respond to Enter or Space, and is not announced as a button. A <button> gets all of that for free. Likewise, navigation belongs in an <a href>, which also gives people middle-click, open in new tab and copy link.
This side is the same link built from a div with a click handler. Without an href the browser cannot open it in a new tab, offer it in the right-click menu, preview its address on hover or list it as a link.
Make targets big enough
WCAG 2.2 sets 24 by 24px as the minimum target size. Aim for 40px on desktop and 44px on touch. The icon can stay small; the clickable area does not have to match it.
.icon-button {
position: relative;
width: 24px;
height: 24px;
}
/* Invisible, larger hit area around the small visual. */
.icon-button::after {
content: "";
position: absolute;
inset: -10px;
}Make sure expanded hit areas of neighbouring controls never overlap, or taps land on the wrong one.
Forms that help instead of block
- Every field has a visible
<label>. Placeholder text is not a label; it disappears the moment someone types. - Match
typeandinputmodeto the data (email,tel,inputmode="numeric") so phones show the right keyboard. - Keep submit enabled. A disabled button does not explain what is missing; validate on submit instead.
- Mark errors with
aria-invalid="true", connect the message witharia-describedby, and move focus to the first invalid field. - Never block paste. Passwords and one-time codes arrive by paste constantly.
Do not rely on color alone
Red text alone does not tell a colorblind person there is an error. Pair color with an icon, a message or a change in shape.
Enter a valid email address
Respect motion preferences
Some people get dizzy or nauseous from large movement. Their system setting is exposed to CSS, and honouring it is one media query. The safest pattern is to write motion only for people who have not asked to reduce it:
@media (prefers-reduced-motion: no-preference) {
.panel {
transition: translate 300ms ease-out;
}
}Reduced motion does not mean no feedback. Opacity fades are usually fine; it is travel, zoom and parallax that cause trouble.
Two touch-screen traps
Hover styles stick on touch screens after a tap, so an item looks selected when it is not. Wrap them in @media (hover: hover). And decorative layers such as glows and gradients should have pointer-events: none so they never swallow a tap meant for the control underneath.
Checklist
- Focus is styled with
:focus-visibleand never removed. - Actions are buttons, navigation is links.
- Targets are at least 24px, ideally 40 to 44px, and never overlap.
- Fields have visible labels, correct input types and accessible errors.
- Color is never the only signal.
- Motion is wrapped in
prefers-reduced-motion: no-preference. - Hover styles are wrapped in
@media (hover: hover).
This piece expands on the Accessibility rules in my cheat sheet, where every rule has a live example.
Keep readingWriting clear UI copyButton labels, confirmations, toggles, empty states and links: small writing rules that make products easier to use.