# Accessibility at scale: contrast, alt text and labels on every page

> Lighthouse's accessibility audit finds low contrast, missing alt text and unlabeled controls. Learn its limits and how to catch issues on every page.

Published: 2026-11-15 · Author: AiroPages

Lighthouse's accessibility category checks each page for common, machine-detectable problems: low color contrast, images without alt text, buttons and links with no accessible name, unlabeled form fields, skipped heading levels and a missing page language. It catches a useful share of issues quickly, but only part of what accessibility standards cover. Because most failures come from shared components, the way to make progress on a real site is to test every page and fix the template, not the page.

## What Lighthouse's accessibility audit checks

Lighthouse uses **axe-core**, an open-source accessibility testing engine, to run its accessibility audits. Each audit is a rule that either passes or fails for the page as it loads. The score from 0 to 100 is a weighted average, with more serious issues counting for more than minor ones.

The checks fall into a few groups:

- **Contrast:** text and background colors meet minimum contrast ratios.
- **Names and labels:** buttons, links, form fields, images and frames have an accessible name a screen reader can announce.
- **Structure:** headings descend in order, lists are marked up as lists, the page has a title and a valid `lang` attribute.
- **ARIA:** ARIA roles and attributes are valid, used on the right elements and not hiding focusable content.
- **Navigation:** elements with a positive `tabindex` and duplicate IDs referenced by ARIA, both of which can break keyboard and screen reader use.
- **Zoom:** the viewport meta tag does not stop users from zooming.

Lighthouse also lists **additional items to check manually**, such as logical tab order, visible focus and whether custom controls have the right roles. These are not scored, but they are a useful starting checklist.

## What automated checks can't catch

Automated testing only covers rules a machine can verify, and that is a subset of WCAG. Lighthouse can confirm that an image has an `alt` attribute, but not that the text describes the image. It can confirm a button has a name, but not that the name makes sense.

Things you still need to test by hand:

- **Keyboard use.** Can you reach and operate every control with Tab, Enter, Space and the arrow keys? Is focus always visible?
- **Focus management.** When a modal opens, does focus move into it and return when it closes?
- **Meaning.** Is alt text accurate? Are link names clear out of context? Do headings describe their sections?
- **Interactive states.** Lighthouse tests the page on load. Menus, modals, accordions, error messages and content loaded after a click are often never checked.
- **Screen reader experience.** Does the page make sense when read aloud in order?
- **Media.** Do videos have captions and do audio files have transcripts?

So treat a score of 100 as a floor. It means the common automated rules pass, not that the page is accessible. The W3C's [WCAG overview](https://www.w3.org/WAI/standards-guidelines/wcag/) is the reference for the full set of success criteria.

## The most common failures, and how to fix them

The same handful of issues shows up on most sites. Here is what each looks like and the usual fix.

| Failure | Typical cause | Usual fix |
|---|---|---|
| Low color contrast | Light gray text, placeholder text, text on brand colors or images | Darken text or adjust the background to reach 4.5:1 (3:1 for large text) |
| Images without alt | Gallery, logo strip, product grid or CMS images with no alt field | Add descriptive alt text, or `alt=""` for purely decorative images |
| Buttons without a name | Icon-only buttons: menu, search, close, carousel arrows | Add an `aria-label` or visually hidden text |
| Links without a name | Linked icons, logos or images with no alt text | Give the image alt text or add an `aria-label` to the link |
| Form fields without labels | Inputs that rely on placeholder text only | Add a `<label>` tied to the input, or `aria-label` if a visible label is not possible |
| Heading levels skipped | Headings chosen for size, such as an `h4` straight after an `h2` | Use the correct level and style it with CSS |
| Missing `lang` | Page template has `<html>` with no `lang` attribute | Add `lang="en"` (or the right language) to the root template |

### Contrast

Contrast is often the most widespread failure because it comes from the design system. WCAG Level AA asks for at least **4.5:1** for normal text and **3:1** for large text. A single gray used for captions, dates and footer links can fail on every page of the site. Fix it once in the design tokens or stylesheet, not page by page.

### Alt text

Missing alt text is usually a content workflow issue. If the CMS image field has no alt input, or it is optional and editors skip it, every new page adds more failures. Make the field required for content images, and mark decorative images with an empty `alt=""` so screen readers skip them.

### Names and labels

Icon-only buttons are the classic case. A hamburger menu that contains only an SVG has no name, so a screen reader announces "button" and nothing else. The same goes for social icons, close buttons and carousel arrows. Form fields that rely only on a placeholder have the same problem, and the placeholder disappears as soon as someone starts typing.

## Why accessibility issues repeat across pages

Most accessibility failures are not page-specific. They come from **components** that appear on every page or every page of one type:

- The header's icon buttons are on every page.
- The footer's low-contrast links are on every page.
- The newsletter form in the sidebar is on every blog post.
- The product card's image without alt text is on every category page.

For example, a site with 600 pages might show thousands of individual failures in a bulk scan, but trace back to eight or ten components. Fixing those components clears most of the list. That is the idea behind [template-level fixes](/blog/template-level-fixes): sort issues by how many pages they affect, and fix the shared source.

This is also why testing a single page is misleading. A homepage might pass with 100 while every product page fails on unlabeled filter controls. The pillar post on why [Lighthouse only tests one page](/blog/lighthouse-only-tests-one-page) covers this problem in general.

## How to check this across your whole site

The manual way is to export your sitemap, run Lighthouse or another axe-based tool on each URL, and merge the failing audits into one table. Then group rows by audit and by the element selector Lighthouse reports, which often points straight at the shared component. The guide on [running Lighthouse on every page](/guides/run-lighthouse-on-every-page) covers collecting URLs and scripting the runs.

AiroPages does this as a hosted service: it finds your pages, runs Lighthouse on mobile and desktop for each one, and groups identical issues by page template, ranked by pages affected. Each group has a plain-English explanation and a technical fix, which you can copy as a prompt for a coding agent. The guide to [fixing Lighthouse issues with Claude Code](/guides/fix-lighthouse-issues-with-claude-code) shows that workflow.

## A practical routine

You do not need to fix everything at once. A steady routine works better:

1. **Scan every page** to get a baseline and a list of issues by component.
2. **Fix the top three shared components** first, usually contrast tokens, icon buttons and form labels.
3. **Add guardrails** so issues do not come back: required alt fields in the CMS, labeled components in the design system, contrast-checked color tokens.
4. **Test by hand** on your key templates with a keyboard and a screen reader, especially menus, modals and forms.
5. **Re-scan after releases** to catch new failures before they spread.

Good accessibility also helps machines. AI agents and assistants often rely on the same structure screen readers use, which is why Lighthouse's newer [Agentic Browsing](/glossary/agentic-browsing) checks start with the accessibility tree.

Automated checks will not make a site accessible on their own, but they catch the common, repeatable problems quickly. Run them on every page, fix the components behind them, and save your manual testing time for the things only a person can judge.
