Accessibility is not a nice-to-have. It is a quality bar. When your site works well for people using screen readers, keyboards, switch devices, voice control, magnifiers, or just a cracked phone screen in bright sunlight, it usually works better for everyone.
WCAG 2.2 is the current standard most teams should align to today. It is organised around four principles, often summarised as POUR.
- Perceivable: users can sense the content
- Operable: users can operate the interface
- Understandable: users can understand what is happening
- Robust: the experience works across browsers and assistive technologies
Most organisations target Level AA because it covers the most important real-world barriers without drifting into the edge cases of AAA.
Start with semantic HTML because it is the cheapest win
If you do nothing else, choose the right elements. Native HTML controls come with keyboard behaviour, focus handling, and accessibility semantics built in.
Bad:
<div onclick="save()">Save</div>
Good:
<button type="button">Save</button>
The second version automatically supports Tab focus, <button type="button">Save</button>
Enter and Space activation, and reliable screen reader announcements.
Make forms understandable with connected labels, hints, and errors
A visually good form can still be unusable if hints and errors are not programmatically linked to inputs. The goal is simple: when a user lands on the field, they should hear and understand the label, any supporting hint, and any error message.
<label for="email">Email</label>
<p id="email-hint">We’ll send the receipt here.</p>
<input
id="email"
name="email"
type="email"
aria-describedby="email-hint email-error"
required
/>
<p id="email-error" role="alert" hidden>Please enter a valid email.</p>
And a minimal JavaScript pattern that shows the error, flags invalid state, and moves focus back to the field:
const input = document.querySelector("#email");
const error = document.querySelector("#email-error");
input.addEventListener("invalid", (e) => {
e.preventDefault();
error.hidden = false;
input.setAttribute("aria-invalid", "true");
input.focus();
});
Two small notes that make a big difference:
- Do not rely on placeholder text as the label.
- Do not show errors only with colour. Use text and ensure it is announced.
Give focus a visible, reliable style
Keyboard users need a clear focus indicator. Too many interfaces remove it, reduce it, or make it blend into the background.
A good baseline:
:focus-visible {
outline: 3px solid currentColor;
outline-offset: 3px;
}
That alone prevents a huge class of accessibility failures.
What WCAG 2.2 added and why you should care
WCAG 2.2 places extra emphasis on keyboard focus, touch targets, cognitive load, and authentication. Here are the additions that show up most often in real products.
Focus should not be hidden
If your site has sticky headers, footers, cookie banners, or floating toolbars, they can cover the element that currently has focus. That is confusing for keyboard users and can make navigation feel broken.
A practical fix for in-page links with a sticky header:
html { scroll-padding-top: 80px; }
section { scroll-margin-top: 80px; }
Also, watch for overlays. If a banner or modal opens, ensure focus is managed properly and users are not stuck behind it.
Touch targets should be large enough
Small icons are a common problem on mobile. WCAG 2.2 improves guidance around minimum target sizes so buttons and links are easier to activate without precision tapping.
A practical styling approach:
button, .icon-button, a.buttonlike {
min-width: 24px;
min-height: 24px;
padding: 8px 12px;
}
If you have a tiny icon-only button, padding often does more for usability than simply scaling the icon.
Drag and drop must have an alternative
If an interaction depends on dragging, provide another way to perform the same action. Drag can be difficult or impossible for many users.
Example for a sortable list that also supports click controls:
<li>
Item A
<button type="button" aria-label="Move Item A up">Up</button>
<button type="button" aria-label="Move Item A down">Down</button>
</li>
You can still keep drag and drop. The key is not making it the only option.
Help should be consistent
If you provide help like a contact link, support chat, or a help centre, place it in a consistent spot across pages. Randomly moving support entry points forces users to relearn navigation and increases cognitive load.
A simple rule that works: put help in the header or footer and keep it there everywhere.
Avoid making users re-enter information
If someone has already entered their address or contact details earlier in a journey, do not make them type it again unless you genuinely need confirmation.
Good patterns:
- Prefill known info when returning to a step
- Provide a “same as above” option for repeated address fields
- Let users review and edit rather than retype
Authentication should not rely on memory tricks
Login flows often introduce unnecessary barriers: forcing users to remember something, transcribe characters, or solve puzzles. WCAG 2.2 pushes teams toward authentication that works with password managers and accessible input methods.
Good patterns:
- Allow paste into password fields
- Provide “show password”
- Support password managers smoothly
- Offer accessible MFA options and alternatives where possible
A lightweight test routine for every feature
You do not need a huge accessibility programme to improve quickly. You need consistency. Here is a routine you can apply to every story or ticket.
- Keyboard only
- Tab through the page. Can you reach everything? Can you operate it? Is focus always visible?
- Focus visibility and obstruction
- When something is focused, can you actually see it or is it hidden behind a sticky element?
- Zoom and layout
- Zoom to 200%. Does content reflow in a sensible way? Do you avoid horizontal scrolling for normal content?
- Forms and errors
- Submit an empty form. Are errors clear, specific, and connected to fields? Does the page move focus to the first error?
- Assistive tech sanity check
- You do not need to be an expert. Use a screen reader briefly and check if headings, landmarks, buttons, and form fields are announced in a way that matches what you see.
- Automation as a safety net
- Run automated checks to catch frequent issues, then rely on manual testing for the meaningful stuff.
Closing thought
Accessibility is not a separate mode of development, and it is not something to bolt on at the end. It is the result of small, repeatable choices: semantic HTML, visible focus, clear labels, consistent help, and interaction patterns that do not depend on precision, memory, or perfect motor control.
Build like someone is using your interface with one hand, on a shaky bus, at 200% zoom, with a keyboard. Because someone is.