Frontend Accessibility: The Fixes That Take an Hour, Not a Rewrite

A practical accessibility guide for web apps and marketing sites — contrast, keyboard traps, form labels, alt text, and focus states. Most of it is fixing defaults, not building new features.

Frontend Accessibility: The Fixes That Take an Hour, Not a Rewrite

Accessibility has a reputation problem. Teams hear "WCAG compliance" and imagine an audit, a redesign, and three months of refactoring. In practice, most of the accessibility issues we find during a review are the same handful of small things: buttons built out of divs, form fields with no labels, focus states deleted in the name of clean design, images that say "image" to a screen reader. None of those need a rewrite. They need an afternoon and the habit of catching them before they ship.

This is the checklist we run through on new builds, and the one we start with when a client asks why their site is hard to use for part of their audience.

Contrast: the cheapest fix with the biggest reach

Low-contrast gray text on white is everywhere because it looks elegant in a Figma file. For readers with low vision, on a cheap laptop screen in daylight, or on a phone in the sun, it reads as a blank area. The fix is a color change; no markup involved.

What we actually do:

  • Run body text, links, and button labels through a contrast checker. WCAG AA wants 4.5:1 for normal text and 3:1 for large text. Gray #999 on white fails at about 2.85:1, which is why it comes up in almost every review.
  • Check the disabled states too. A disabled button you cannot distinguish from an enabled one is its own problem, and "it's disabled anyway" is not an excuse for 2:1 text.
  • Spot-check text over images and gradients. This is where contrast dies quietly, because nobody thinks to test it.

Keyboard: if you can't tab through it, it's broken

Unplug your mouse for five minutes and use the site with Tab, Enter, and Esc only. This single exercise finds more real problems than any automated scanner: menu items that cannot be reached, modals you cannot leave, custom dropdowns that trap focus, and "buttons" that are actually <div onclick>, invisible to keyboards and screen readers alike.

The fixes are mostly boring:

  • Real interactive elements get real HTML tags. <button>, <a href>, <input>. Native elements come with keyboard behavior for free; a div with a click handler has nothing for free.
  • Any openable UI (dropdown, modal, mobile nav) closes on Escape and returns focus where it came from. Otherwise keyboard users are stranded after closing it.
  • Focus stays visible. If the design removed the outline, replace it with something better rather than nothing: an offset ring, a color change, a border. outline: none with no replacement means a keyboard user is navigating blind.
  • Skip links at the top of the page: one anchor, ten lines of CSS, and keyboard users stop tabbing through the whole header on every page.

Forms: label first, placeholder never alone

Forms are where accessibility failures cost actual money, because forms are where signups and checkouts happen.

  • Every input has a <label for>. Placeholders disappear the moment someone starts typing, so a placeholder in place of a label means the field has no name at all for a screen reader.
  • Mark required fields in the label or with aria-required, not with a red asterisk alone.
  • Error messages need to be text next to the field, tied to it with aria-describedby, and they need to say what to fix. "Invalid input" is not an answer; "Enter a date in DD.MM.YYYY format" is.
  • Never disable the submit button to "prevent double submits". Disabled buttons can't be focused, so screen reader users get an unreachable button and no explanation. Accept the double click and make the handler idempotent, or show a message.

Images and names

Alt text is not an SEO field, it is a description for people who cannot see the image. Decorative images get alt="" so screen readers skip them. Informative ones get a short description of what the image shows, not "image of". Charts need the takeaway in text nearby, because no alt string can carry a chart. SVG icons need aria-hidden="true" unless they carry meaning.

Same logic applies to links: "click here" and "read more" repeated down a page make the link list useless. Link text should describe the destination: "the pricing guide" beats "read more".

Headings and landmarks: the invisible page map

Screen reader users navigate by headings the way sighted users scan by shape. One h1 per page, heading levels that don't skip, and real semantic landmarks (<nav>, <main>, <footer>) give them a map for free. This usually takes an hour on an existing page and mostly means changing <div class="heading"> to h2 and <div id="main"> to <main>.

Where Vue and Inertia apps go wrong

SPA frameworks make accessibility harder in specific, predictable ways, because the framework now owns things the browser used to do:

  • Route changes don't announce anything. The page swaps under a screen reader and nothing says so. Announce the new page title with a polite live region, and move focus to main or the new heading.
  • Portals and teleports drop a modal at the end of the DOM, far from the trigger. That is fine if you manage focus: trap it inside the modal while open, restore it on close.
  • Loading states tend to be visual only. A spinner that is just a div is silence; give it a role and a text alternative, or the user waits without knowing whether anything is happening.
  • After a failed submit, focus the error message, not the button. Otherwise the announcement happens somewhere the user isn't looking.

None of this is framework-specific genius. It is a handful of patterns you write once and copy into every project.

The 80/20 for a site you inherited

When a client asks for an accessibility pass on an existing site, this is the order that gives the most improvement per hour:

  1. Fix contrast failures in text and controls.
  2. Add labels and error text to every form field.
  3. Replace div-buttons with real buttons and links.
  4. Restore visible focus and add skip links.
  5. Write real alt text, mark decorations with alt="".
  6. Fix the heading structure, one h1, no skipped levels.
  7. Make menus and modals closable with Escape.

That list covers the issues that show up in nearly every review. It will not make a site fully WCAG-conformant, and it will not replace testing with real assistive technology. But it removes the barriers that make a site unusable for a meaningful share of visitors, and it does so in days, not months.

The habit that keeps it from regressing: run the keyboard-and-no-mouse exercise and a contrast check before every launch, the same way you run a performance and SEO check. Accessibility belongs on the pre-launch checklist next to them, not on a someday list after them.