DEV Community

𝗝𝗼𝗵𝗻
𝗝𝗼𝗵𝗻

Posted on

Accessibility Is Not a Lighthouse Checkbox

Modern Web Development in 2026

A practical series about building faster, cleaner, more maintainable web applications without chasing every shiny thing.

Automated accessibility checks are useful.

They catch missing labels, obvious contrast failures, invalid ARIA, and a lot of mistakes that should never reach production.

But accessibility is not finished when a tool gives you a green score.

A green score can still hide a page that is confusing, exhausting, or impossible to use with a keyboard.

Start with semantic HTML

The most underrated accessibility tool is still HTML.

Use the element that matches the job:

<button type="button">Save changes</button>
<a href="/settings">Account settings</a>
<nav aria-label="Main navigation">...</nav>
<main>...</main>
<form>...</form>
Enter fullscreen mode Exit fullscreen mode

Do not turn everything into a div and then rebuild the platform with ARIA.

ARIA is powerful. It is also easy to misuse. Native semantics are usually safer.

Keyboard test every important flow

Put the mouse away.

Can you complete the flow with only:

Tab
Shift + Tab
Enter
Space
Arrow keys
Escape
Enter fullscreen mode Exit fullscreen mode

Test:

  • opening menus,
  • closing dialogs,
  • submitting forms,
  • moving through filters,
  • skipping repeated navigation,
  • reaching error messages,
  • recovering from mistakes.

If your product cannot be used from a keyboard, it is broken for more people than you think.

Focus is part of the interface

Removing focus styles is not polish. It is damage.

Good focus indicators are:

  • visible,
  • consistent,
  • high contrast,
  • not hidden behind shadows,
  • not dependent on color alone.
:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 3px;
}
Enter fullscreen mode Exit fullscreen mode

The goal is not to make focus pretty enough for a screenshot. The goal is to make the current location obvious.

Forms need more care than we give them

A good form explains itself before, during, and after input.

<label for="email">Email address</label>
<input id="email" name="email" type="email" autocomplete="email" aria-describedby="email-hint" />
<p id="email-hint">Use the address where you want to receive account updates.</p>
Enter fullscreen mode Exit fullscreen mode

For errors:

  • place the message near the field,
  • describe how to fix it,
  • connect it programmatically,
  • summarize errors for long forms,
  • move focus intentionally after failed submission.

“Invalid input” is not a helpful error. It is a shrug.

Dialogs are traps unless designed carefully

A modal dialog should:

  • move focus into the dialog when opened,
  • trap focus while open,
  • close with Escape when appropriate,
  • return focus to the triggering element,
  • have a clear accessible name,
  • avoid background interaction.

If that sounds like a lot, use a well-tested primitive. Dialogs are one of the places where “simple custom code” often becomes inaccessible custom code.

Do not use color alone

Color is useful. It should not be the only signal.

Bad:

Required fields are red.
Enter fullscreen mode Exit fullscreen mode

Better:

Required fields have text, an icon, and programmatic state.
Enter fullscreen mode Exit fullscreen mode

For charts, statuses, validation, and alerts, combine:

  • text,
  • shape,
  • position,
  • iconography,
  • semantic markup.

Automated tests are a floor

Add accessibility checks to CI:

import { test, expect } from "@playwright/test";
import AxeBuilder from "@axe-core/playwright";

test("page has no obvious accessibility violations", async ({ page }) => {
  await page.goto("/settings");
  const results = await new AxeBuilder({ page }).analyze();
  expect(results.violations).toEqual([]);
});
Enter fullscreen mode Exit fullscreen mode

This is good. It is not enough.

Automated tools cannot fully judge whether the flow makes sense, whether focus movement feels logical, or whether the content is understandable.

The human checklist

Before release, test:

  • [ ] Can the full flow be completed with keyboard only?
  • [ ] Is focus always visible?
  • [ ] Are headings meaningful and ordered?
  • [ ] Are form labels explicit?
  • [ ] Are errors helpful and connected to fields?
  • [ ] Are dialogs focus-managed?
  • [ ] Is color supported by another signal?
  • [ ] Does the page make sense with CSS disabled?
  • [ ] Does the page make sense with images unavailable?

Final thought

Accessibility is not a separate layer you add after the “normal” product is done.

It is part of the product being usable.

A green automated score is a good start. A real user completing a real task without barriers is the goal.

Sources


Thanks for reading.

You can find me here:

Top comments (0)