Web accessibility quick wins for developers

7 min read
accessibility
guide
html

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

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

s with class names implying the same thing; use 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.

Tools from this article

Comments

No login needed. Comments appear after a quick review.

Protected by an on-site captcha — no third-party trackers.

Optional: get an alert when your comment is published or replied to, plus new tool announcements. No sign-up.

Loading comments…

← All articles