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 `<button>` is keyboard-operable, focusable, announced correctly by screen readers, and triggerable with both Enter and Space — for free. A `<div onclick="...">` styled to look like a button has none of that by default; you'd have to manually add `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> ```
The same logic applies across the board: use `<nav>`, `<main>`, `<header>`, `<footer>` instead of generic `<div>`s with class names implying the same thing; use `<a href>` 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="" /> ```
The common mistake isn't forgetting `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"
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 (`#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" /> ```
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 `<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
An icon-only button (a trash icon, a close "×") has no text content for a screen reader to announce.
<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
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.
<input aria-invalid="true" aria-describedby="email-error" />
<p id="email-error">Enter a valid email address.</p>Pairing color with text, an icon, or both (and wiring it up with `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
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 `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
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.