
Web Accessibility Essentials Every Team Should Ship
Around one in six people lives with some form of disability. Many more use the web with a broken trackpad, bright sunlight on a phone screen, or a slow connection. Accessibility is how you make sure all of them can actually use what you built.
The good news: most accessibility wins come from a handful of habits, not a specialist audit at the end of the project.
Start With Semantic HTML
The browser already knows how to make buttons, links, headings, and form fields accessible. You lose that for free behavior the moment you rebuild them out of divs.
<!-- Avoid -->
<div class="btn" onclick="save()">Save</div>
<!-- Prefer -->
<button type="button" onclick="save()">Save</button>
A real button is focusable, works with Enter and Space, and announces itself as a button to screen readers. Rules of thumb:
- Links go somewhere, buttons do something
- One
h1per page, then headings in order without skipping levels - Use landmarks:
header,nav,main,footer - Lists of things are
ulorol, not stacks ofdivs
Make Everything Work With a Keyboard
Unplug your mouse and try your main flows. Can you open the menu, fill the form, close the modal, and reach the footer? Watch for:
- Visible focus - never remove outlines without a clear replacement
- Logical order - tab order should follow the visual order
- Focus traps - modals should keep focus inside while open and return it when closed
- Skip links - a "Skip to main content" link saves keyboard users from tabbing through the whole menu
:focus-visible {
outline: 3px solid #2d4a52;
outline-offset: 2px;
}
Check Color Contrast Early
Light gray text on white looks elegant in a mockup and fails real users. WCAG AA asks for a contrast ratio of at least 4.5:1 for body text and 3:1 for large text and UI components.
Check contrast while you design, not after. Browser dev tools show the ratio right in the color picker. Also make sure color is never the only signal: an error state needs text or an icon, not just a red border.
Label Every Form Field
Placeholders disappear when you type and are often low contrast. Every input needs a real label:
<label for="email">Email</label>
<input type="email" id="email" name="email" autocomplete="email" required>
<p id="email-error" class="field-error">Enter a valid email address.</p>
Connect error messages with aria-describedby, use the right type and autocomplete values, and keep error text specific: "Enter a valid email address" beats "Invalid input".
Images, Media, and Motion
- Give meaningful images a short
altthat says what the image adds - Use
alt=""for purely decorative images so screen readers skip them - Caption videos and provide transcripts for audio
- Respect
prefers-reduced-motionfor large animations and parallax effects
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
Use ARIA Sparingly
The first rule of ARIA is: don't use ARIA if a native element does the job. ARIA changes what assistive tech announces, not how the element behaves. A div role="button" still needs keyboard handling you have to write yourself.
Reach for ARIA for patterns HTML does not cover yet, like tabs, live regions for async updates, and aria-expanded on menu toggles.
Test Like Your Users
Automated tools such as axe and Lighthouse catch around a third of issues. They are a great CI baseline, but add manual checks:
- Keyboard-only pass through key flows
- A screen reader pass with VoiceOver (macOS/iOS) or NVDA (Windows)
- Zoom to 200% and check nothing overlaps or gets cut off
- Test on a real phone in bright light
Conclusion
Accessible sites are better sites: clearer structure, sturdier forms, and fewer surprises across devices. Build the habits into your components once, and every new page inherits them.
Want an accessibility review of your site or design system? Get in touch.