Web accessibility quick wins for developers
Accessibility work has a reputation for being a big, separate project. Most of the highest-impact fixes are small, don't require a redesign, and take minutes each — the trick is knowing which ones matter most.
1. Use semantic HTML before reaching for ARIA
A The same logic applies across the board: use The common mistake isn't forgetting WCAG AA requires a 4.5:1 contrast ratio for normal text and 3:1 for large text (18pt+, or 14pt bold). Light gray text on a white background ( Placeholder text disappears the moment a user starts typing, has poor contrast by browser default, and isn't reliably announced by every screen reader the way an associated An icon-only button (a trash icon, a close "×") has no text content for a screen reader to announce. A form that only turns a field's border red to indicate an error is invisible to colorblind users and to anyone on a low-contrast display. Pairing color with text, an icon, or both (and wiring it up with Unplug your mouse for five minutes and try to complete your site's core flow using only Tab, Shift+Tab and Enter. This single exercise catches more real issues than most automated scanners: modals that trap focus wrong, dropdowns that only open on hover, custom components with no keyboard handler at all, and tab order that jumps illogically around the page because of Automated accessibility scanners (axe, Lighthouse) reliably catch missing alt text, low contrast, and missing form labels — which is exactly why those are cheap wins with an objective check. Keyboard navigation and focus-visible styling require a human pass but take minutes once you know to look. None of the eight items above require a design system overhaul; they're the accessibility equivalent of fixing null-pointer bugs — unglamorous, but they remove the most common real-world barriers for the least effort. No login needed. Comments appear after a quick review. Loading comments…<button> is keyboard-operable, focusable, announced correctly by screen readers, and triggerable with both Enter and Space — for free. A tabindex, a role, and keydown handlers to reproduce what <button> already does.
<!-- Avoid -->
<div class="btn" onclick="submit()">Submit</div>
<!-- Prefer -->
<button type="button" onclick="submit()">Submit</button><nav>, <main>, <header>, <footer> instead of generic for navigation and <button> for actions, not the reverse. The first rule of ARIA is literally "don't use ARIA if a native HTML element already does the job."
2. Never remove focus outlines without replacing them
outline: none on :focus is one of the most common accessibility regressions, usually introduced to "clean up" a design, and it silently makes the entire site unusable for keyboard-only users, who lose all visual indication of where they are on the page./* Don't do this alone */
button:focus { outline: none; }
/* Do this instead */
button:focus-visible {
outline: 2px solid #2563eb;
outline-offset: 2px;
}:focus-visible (supported in all current browsers) shows the outline for keyboard navigation but suppresses it for mouse clicks, which addresses the actual design complaint ("I don't want a ring after clicking") without breaking keyboard access.3. Every image needs an alt attribute — even a blank one
<!-- Informative image -->
<img src="chart.png" alt="Revenue grew 40% year over year" />
<!-- Purely decorative image -->
<img src="divider.svg" alt="" />alt entirely (browsers are loud about that during development) — it's writing alt="image123.png" or the filename, which is worse than nothing, or omitting alt="" on decorative images, which forces a screen reader to announce the filename for something that carries no information.4. Check contrast, not just "does it look fine to me"
#999 on #fff is roughly 2.8:1) reads fine to most sighted users on a good monitor and fails outright for users with low vision, and often for anyone in bright sunlight on a phone. Running your palette through a contrast checker before shipping catches this in seconds — it's one of the few accessibility issues with an objective pass/fail number.5. Label every form field, properly associated
<!-- Placeholder is not a label -->
<input type="email" placeholder="Email" />
<!-- Correct -->
<label for="email">Email</label>
<input type="email" id="email" /><label> is. If you need the compact look of a placeholder-only field, visually hide a real <label> with a .sr-only class rather than deleting it.6. Give interactive icons an accessible name
<button aria-label="Delete item">
<svg aria-hidden="true">...</svg>
</button>aria-label gives the button a name; aria-hidden="true" on the decorative SVG prevents it from being separately (and confusingly) announced.7. Don't rely on color alone to convey meaning
<input aria-invalid="true" aria-describedby="email-error" />
<p id="email-error">Enter a valid email address.</p>aria-invalid/aria-describedby so assistive tech announces it) fixes this for a small amount of markup. Running your color palette through a color-blindness simulator is a fast way to catch cases where a red/green distinction is the only signal a UI gives.8. Make sure keyboard-only navigation actually works
tabindex values greater than zero (avoid positive tabindex — it overrides natural DOM order and is almost always a mistake).Why these are the right first fixes
Tools from this article
Comments