What you get free
A real button receives keyboard focus in the right order. It responds to enter and to space. It announces itself as a button to assistive technology.
It also inherits the behavior every visitor has learned from every other site, including the browser's own focus styling.
None of that exists on a styled shape until somebody writes it, and that somebody usually writes half of it.
The half that gets written is usually the click handler. The half that gets forgotten is the keyboard, which is the half that matters here.
The half that usually gets written is the click handler. The half that gets forgotten is the keyboard, and that is the half this page is about.
Links versus buttons
A link takes you to another place. A button performs an action here: submit, open, close, add, play.
It matters because the announcement differs and because the keys differ. Links respond to enter. Buttons respond to enter and to space.
Style them however your design requires. A link can look like a button. It should still be a link if it goes somewhere.
Style them however the design needs. A link can look exactly like a button; what matters is what the element is, because that decides the keys and the announcement.
Icon only controls
A magnifier, a cross, a hamburger, a trash can. Each is clear visually and silent aloud unless labeled.
Give every icon only control a text label. It costs nothing visually and it is the difference between close and unlabelled button.
If the icon is ambiguous even visually, add a visible word. Plenty of sighted visitors are guessing too.
Test by covering the icon and asking what the control does. If you cannot say, a label is not optional.
Cover the icon and ask what the control does. If you cannot say, a label is not optional — the same test as alt text applied to a control.
Size and spacing
Touch targets need to be big enough to hit and far enough apart that a near miss does not trigger the wrong thing.
This matters most where actions differ in consequence. A delete control beside an edit control, both small, is a design that will produce mistakes.
Generous spacing helps everyone on a phone, including people with perfectly steady hands and cold fingers.
State has to be visible and announced
A control that is disabled, selected, expanded or loading needs to say so in a way both a sighted reader and a listener can tell.
Greying something out is a visual signal only. A pressed state shown by color alone is invisible to some readers.
Where scripting changes a state, the announcement has to change with it. A menu reporting itself as closed while it is open is worse than no announcement.
- Disabled, which needs more than being greyed out
- Selected or pressed, which color alone cannot carry
- Expanded or collapsed on a menu or accordion
- Loading, so nobody presses twice
- Current page in a navigation list
- Required, on a form control
Loading and waiting
If pressing something starts a slow operation, say so. A silent pause makes people press again, which on a form means duplicate submissions.
A short message near the control is enough, and it should be announced rather than only displayed.
Disable the control while the operation runs, so the second press cannot happen.
How ours are built
Controls on pages here are real buttons and real links, so the keyboard behavior and the announcements come with them rather than being reconstructed.
Every page passes a check that runs before anything publishes, validated against Google Search Essentials and modern web standards.
The in-app assistant flags a control with no accessible name. Whether the name is the right one is still worth reading once with your own eyes.
Nothing here is legal advice. It is simply that the element which already behaves correctly is cheaper than the one you have to teach.
Real elements also survive a redesign. Styling changes; the behavior of a button does not, because it was never something somebody had to remember to add.