Resources · Fix directory

Fix automated accessibility errors a reproduction, the fix, and how to know it worked

27 errors the analyzer reports, each with the smallest page that triggers it, the same page fixed, and a way to check the fix that goes past the rule. Each reproduction was run through the analyzer’s engine in Chromium: it fails the rule, and the fix clears it.

The six most common, on a million home pages

  1. Low contrast text83.9%
  2. Missing alternative text53.1%
  3. Missing form input labels51.0%
  4. Empty links46.3%
  5. Empty buttons30.6%
  6. Missing document language13.5%

WebAIM Million, 2026: share of home pages with each

Errors
27
Groups
6
Checked

Directory

Find your error

Look it up by the analyzer’s rule id, by the axe-core name your other tools print, or by group. Lighthouse runs axe-core, and its accessibility audits use axe’s rule names.

Images and media
Analyzer ruleaxe-core and LighthouseWhat it meansCriterion
image-alt Most commonimage-altImages must have an alt attribute1.1.1
video-captionNeeds review: video-captionVideo must have captions1.2.2
Names and labels
Analyzer ruleaxe-core and LighthouseWhat it meansCriterion
link-name Most commonlink-nameLinks must have discernible text2.4.4 4.1.2
link-name-genericNot reportedLink text must describe the destination2.4.4 2.4.9
button-name Most commonbutton-nameButtons must have discernible text4.1.2
form-field-label Most commonlabelForm elements must have labels1.3.1 3.3.2 4.1.2
label-placeholder-onlyNot reportedPlaceholder text must not be the only label3.3.2
label-in-nameNot reportedAccessible name must contain the visible label2.5.3
autocomplete-validautocomplete-validautocomplete attribute must use valid tokens1.3.5
frame-titleframe-titleFrames must have a title2.4.1 4.1.2
Color and contrast
Analyzer ruleaxe-core and LighthouseWhat it meansCriterion
color-contrast Most commoncolor-contrastText must meet the minimum contrast ratio1.4.3
link-in-text-blocklink-in-text-blockLinks in body text must not rely on colour alone1.4.1
non-text-contrastNot reportedUI component boundaries need 3:1 contrast1.4.11
Keyboard and focus
Analyzer ruleaxe-core and LighthouseWhat it meansCriterion
focus-visibleNot reportedFocused elements must show a visible focus indicator2.4.7
tabindex-positivetabindexPositive tabindex must not be used2.4.3
target-size-minimumtarget-sizeTouch targets must be at least 24×24 CSS pixels2.5.8
nested-interactiveNot reportedInteractive controls must not be nested4.1.2
aria-hidden-focusaria-hidden-focusaria-hidden elements must not contain focusable content1.3.1 4.1.2
ARIA
Analyzer ruleaxe-core and LighthouseWhat it meansCriterion
aria-role-validaria-rolesrole attribute must contain a valid, non-abstract role4.1.2
aria-required-attraria-required-attrRoles must carry their required ARIA attributes4.1.2
aria-reference-validNeeds review: aria-valid-attr-valueARIA ID references must resolve1.3.1 4.1.2
The page itself
Analyzer ruleaxe-core and LighthouseWhat it meansCriterion
html-has-lang Most commonhtml-has-lang<html> must have a lang attribute3.1.1
document-titledocument-titlePage must have a descriptive title2.4.2
heading-orderheading-orderHeading levels must not skip1.3.1 2.4.6
listitem-parentlistitemList items must be inside a list1.3.1
meta-viewportmeta-viewportZooming and scaling must not be disabled1.4.4
meta-refreshmeta-refreshPages must not auto-refresh or redirect on a timer2.2.1

Marked “most common”: the six failure types the WebAIM Million found most often on a million home pages in 2026.

2 errors

Images and media

image-alt Most common

Images must have an alt attribute

Why it matters

Without an alt attribute, many screen readers read out the file name instead, and what the image was there to say never arrives.

The analyzer reports

Image has no alt attribute — a screen reader will read the file name "sales-march.png" instead.

The fix

Write what the image is for, not what it looks like. A purely decorative image takes an empty alt (alt=""), which tells assistive technology to skip it.

Verify it

  1. Run the analyzer on your page again: image-alt is no longer among the failures.
  2. Read the page with images switched off, or listen to it with a screen reader: each alt should stand in for its image in the sentence around it.

In axe-core and Lighthouse image-alt

Fails

<img src="sales-march.png" width="640" height="360">

Fixed

<img src="sales-march.png" width="640" height="360"
     alt="Sales rose 12% in March, the best month this year">

video-caption

Video must have captions

Why it matters

People who are deaf or hard of hearing, and anyone watching with the sound off, get none of the speech and none of the sounds that carry meaning.

The analyzer reports

<video> has no captions track.

The fix

Add a captions track: a WebVTT file with the dialogue and the meaningful sounds, timed to the video.

Verify it

  1. Run the analyzer on your page again: video-caption is no longer among the failures.
  2. Turn the captions on and watch the whole video: every line of speech appears, in time, with the speaker named when it is not obvious. The analyzer sees that a track exists, not what is in it.

In axe-core and Lighthouse Needs review: video-caption

Fails

<video controls src="launch.mp4" width="640" height="360"></video>

Fixed

<video controls src="launch.mp4" width="640" height="360">
  <track kind="captions" src="launch.en.vtt" srclang="en" label="English">
</video>

Back to the directory

8 errors

Names and labels

link-name Most common

Links must have discernible text

Why it matters

An icon-only link has nothing to announce, so a screen reader says "link" and nothing else, or reads out the address.

The analyzer reports

Link to "/cart" has no accessible name.

The fix

Give the link text. Visually hidden text keeps the icon on screen and puts a name in the accessibility tree; an aria-label on the link works too.

Verify it

  1. Run the analyzer on your page again: link-name is no longer among the failures.
  2. Open the accessibility tree in your browser's developer tools and select the link: its name is the word you wrote.

In axe-core and Lighthouse link-name

<a href="/cart">
  <svg width="24" height="24" aria-hidden="true"><circle cx="12" cy="12" r="8"/></svg>
</a>
<style>.visually-hidden{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}</style>
<a href="/cart">
  <svg width="24" height="24" aria-hidden="true"><circle cx="12" cy="12" r="8"/></svg>
  <span class="visually-hidden">Cart</span>
</a>

link-name-generic

Link text must describe the destination

Why it matters

Screen reader users often move through a page by its list of links, where there is no sentence around each one. Ten "Read more" links are ten identical entries.

The analyzer reports

Link text "Read more" does not describe its destination.

The fix

Put the destination in the link text. If the design needs the short words, extend them with visually hidden text.

Verify it

  1. Run the analyzer on your page again: link-name-generic is no longer among the failures.
  2. List every link on the page (a screen reader's links list does this) and read the list alone: no two different destinations share a name.

In axe-core and Lighthouse Not reported

<p>Our March report is out. <a href="/reports/march">Read more</a></p>
<p>Our March report is out. <a href="/reports/march">Read the March report</a></p>

button-name Most common

Buttons must have discernible text

Why it matters

A button with only an icon in it is announced as "button", with no clue what it does, and voice control users have nothing to say to press it.

The analyzer reports

<button> has no accessible name.

The fix

Name the button with aria-label, or with visible or visually hidden text, and keep the icon hidden from assistive technology.

Verify it

  1. Run the analyzer on your page again: button-name is no longer among the failures.
  2. Tab to the button with a screen reader running: it says the name, then "button".

In axe-core and Lighthouse button-name

Fails

<button type="button">
  <svg width="24" height="24" aria-hidden="true"><path d="M4 4l16 16M20 4L4 20" stroke="currentColor"/></svg>
</button>

Fixed

<button type="button" aria-label="Close">
  <svg width="24" height="24" aria-hidden="true"><path d="M4 4l16 16M20 4L4 20" stroke="currentColor"/></svg>
</button>

form-field-label Most common

Form elements must have labels

Why it matters

A field with no label is announced as "edit text" and nothing more. People using a screen reader or voice control cannot tell what it is for.

The analyzer reports

<input type="email"> has no label.

The fix

Tie a visible label to the field with for and id. Clicking the label then focuses the field too.

The reproduction also fails identify-input-purpose, and the fix clears that too.

Verify it

  1. Run the analyzer on your page again: form-field-label is no longer among the failures.
  2. Click the label: the cursor lands in the field. With a screen reader, focusing the field reads the label.

In axe-core and Lighthouse label

Fails

<input type="email" name="email">

Fixed

<label for="email">Email</label>
<input type="email" id="email" name="email" autocomplete="email">

label-placeholder-only

Placeholder text must not be the only label

Why it matters

The placeholder disappears at the first keystroke, so the field forgets what it was for while it is being filled in. It is usually too faint to read as well.

The analyzer reports

Field is labelled only by its placeholder "Email".

The fix

Use a real label that stays. If a placeholder remains, it holds an example of the format, never the name of the field.

The reproduction also fails identify-input-purpose, and the fix clears that too.

Verify it

  1. Run the analyzer on your page again: label-placeholder-only is no longer among the failures.
  2. Type into the field: its name is still on screen. axe-core does not report this one, because a placeholder does give the field an accessible name.

In axe-core and Lighthouse Not reported

Fails

<input type="email" name="email" placeholder="Email">

Fixed

<label for="email">Email</label>
<input type="email" id="email" name="email" autocomplete="email">

label-in-name

Accessible name must contain the visible label

Why it matters

Someone using voice control says what they see: "click Send". The button's name is "Submit form", so nothing happens.

The analyzer reports

Visible label "send" is not part of the accessible name "submit form".

The fix

Drop the aria-label and let the visible text name the button. If the name needs more words, start it with the visible ones.

Verify it

  1. Run the analyzer on your page again: label-in-name is no longer among the failures.
  2. With voice control (Voice Access on Windows or Android, Voice Control on Apple devices), say "click" and the visible text: the button responds.

In axe-core and Lighthouse Not reported

Fails

<button type="button" aria-label="Submit form">Send</button>

Fixed

<button type="button">Send</button>

autocomplete-valid

autocomplete attribute must use valid tokens

Why it matters

A token the browser does not know is ignored, so the field never offers the saved address, and people who find typing slow or hard type it all again.

The analyzer reports

autocomplete="e-mail" is not a valid token sequence.

The fix

Use the token from the HTML list of autofill field names: email, name, tel, postal-code and so on.

Verify it

  1. Run the analyzer on your page again: autocomplete-valid is no longer among the failures.
  2. Focus the field in a browser with a saved address: it offers to fill it.

In axe-core and Lighthouse autocomplete-valid

Fails

<label for="e">Email</label>
<input id="e" type="email" autocomplete="e-mail">

Fixed

<label for="e">Email</label>
<input id="e" type="email" autocomplete="email">

frame-title

Frames must have a title

Why it matters

A screen reader announces an untitled frame as "frame", so a user has to go into it to learn what it holds.

The analyzer reports

<iframe src="https://maps.example/store"> has no title.

The fix

Give every iframe a title that says what is inside it.

Verify it

  1. Run the analyzer on your page again: frame-title is no longer among the failures.
  2. With a screen reader, move to the frame: it reads the title before the content.

In axe-core and Lighthouse frame-title

Fails

<iframe src="https://maps.example/store" width="600" height="400"></iframe>

Fixed

<iframe src="https://maps.example/store" width="600" height="400"
        title="Map of the Pune store"></iframe>

Back to the directory

3 errors

Color and contrast

color-contrast Most common

Text must meet the minimum contrast ratio

Why it matters

Gray at 2.85:1 on white is hard to read for people with low vision, for older eyes, and for anyone on a phone in daylight.

The analyzer reports

Contrast 2.85:1 is below the required 4.5:1 for normal text (16px). #999999 on #ffffff.

The fix

Darken the text until it reaches 4.5:1, or 3:1 for large text. #767676 is the lightest gray that reaches 4.5:1 on white.

Verify it

  1. Run the analyzer on your page again: color-contrast is no longer among the failures.
  2. Check the pair in the contrast checker, then check hover, focus and visited states, and the dark theme. Text over an image or a gradient needs a person; the rule measures solid colors.

In axe-core and Lighthouse color-contrast

Fails

<p style="color:#999999;background:#ffffff">Delivery in three to five days.</p>

Fixed

<p style="color:#767676;background:#ffffff">Delivery in three to five days.</p>

link-in-text-block

Links in body text must not rely on colour alone

Why it matters

The link differs from the sentence only by hue, at 1.85:1. People who see color differently, or not at all, cannot find it.

The analyzer reports

Inline link "terms of sale" is distinguished from surrounding text by colour alone (1.85:1).

The fix

Underline links in running text. Without an underline, the link needs 3:1 against the text around it and another cue on hover and focus.

Verify it

  1. Run the analyzer on your page again: link-in-text-block is no longer among the failures.
  2. View the page in grayscale, or through the color vision simulator: every link in a paragraph is still findable.

In axe-core and Lighthouse link-in-text-block

<p style="color:#222222">Read the <a href="/terms" style="color:#2a4a8a;text-decoration:none">terms of sale</a> before you buy.</p>
<p style="color:#222222">Read the <a href="/terms" style="color:#2a4a8a;text-decoration:underline">terms of sale</a> before you buy.</p>

non-text-contrast

UI component boundaries need 3:1 contrast

Why it matters

A field drawn with a border at 1.36:1 all but disappears for people with low vision, who then cannot see where to click or type.

The analyzer reports

<input> has neither a visible boundary nor a text label, so nothing identifies it as a control.

The fix

Give the boundary that identifies the control at least 3:1 against what is around it.

Verify it

  1. Run the analyzer on your page again: non-text-contrast is no longer among the failures.
  2. Measure the border against the page in the contrast checker, and check the focused and the error states too.

In axe-core and Lighthouse Not reported

Fails

<label for="q">Search</label>
<input id="q" type="text" style="border:1px solid #dddddd;background:#ffffff">

Fixed

<label for="q">Search</label>
<input id="q" type="text" style="border:1px solid #767676;background:#ffffff">

Back to the directory

5 errors

Keyboard and focus

focus-visible

Focused elements must show a visible focus indicator

Why it matters

Removing the outline without a replacement leaves keyboard users with no idea where they are on the page.

The analyzer reports

1 rule(s) remove the focus outline without providing a replacement: button:focus { outline: none }

The fix

Style :focus-visible instead of removing the outline: the ring shows for keyboard use and stays out of the way for mouse clicks.

Verify it

  1. Run the analyzer on your page again: focus-visible is no longer among the failures.
  2. Tab through the page: every stop shows a ring you can see at a glance, at 3:1 against the background. axe-core has no rule for this; it takes a person or this analyzer's stylesheet check.

In axe-core and Lighthouse Not reported

Fails

<style>button:focus { outline: none }</style>
<button type="button">Save</button>

Fixed

<style>button:focus-visible { outline: 2px solid #1d4ed8; outline-offset: 2px }</style>
<button type="button">Save</button>

tabindex-positive

Positive tabindex must not be used

Why it matters

A positive tabindex pulls the element ahead of everything else in the tab order, so focus jumps around the page instead of following it.

The analyzer reports

tabindex="3" forces this element out of natural tab order.

The fix

Remove it. Put the element where it belongs in the source, and use tabindex="0" only to make a custom control focusable.

Verify it

  1. Run the analyzer on your page again: tabindex-positive is no longer among the failures.
  2. Tab from the top of the page: focus moves in reading order.

In axe-core and Lighthouse tabindex

Fails

<button type="button" tabindex="3">Save</button>

Fixed

<button type="button">Save</button>

target-size-minimum

Touch targets must be at least 24×24 CSS pixels

Why it matters

Two 16-pixel targets side by side are easy to miss and easy to hit by mistake, for people with tremors, and for anyone using a thumb.

The analyzer reports

Target is 16×16px — below the 24×24px minimum.

The fix

Make each target at least 24 by 24 CSS pixels, or leave enough space that a 24-pixel circle on each one does not overlap its neighbor.

Verify it

  1. Run the analyzer on your page again: target-size-minimum is no longer among the failures.
  2. Measure the rendered size in the developer tools at the width people use. This rule needs layout, so it is reported by a scan in a real browser.

In axe-core and Lighthouse target-size

Fails

<button type="button" aria-label="Previous" style="width:16px;height:16px;padding:0;margin:0">&lsaquo;</button><button type="button" aria-label="Next" style="width:16px;height:16px;padding:0;margin:0">&rsaquo;</button>

Fixed

<button type="button" aria-label="Previous" style="min-width:24px;min-height:24px;padding:0;margin:0">&lsaquo;</button><button type="button" aria-label="Next" style="min-width:24px;min-height:24px;padding:0;margin:0">&rsaquo;</button>

nested-interactive

Interactive controls must not be nested

Why it matters

A button inside a link is two controls in one place. Keyboard users meet it twice, and screen readers announce it inconsistently, or not at all.

The analyzer reports

A link holds a <button>: two controls in one, which HTML does not allow, and screen readers announce only one of them.

The fix

Use one element. If it goes somewhere, it is a link, styled however the design needs.

Verify it

  1. Run the analyzer on your page again: nested-interactive is no longer among the failures.
  2. Tab past it: one stop, not two. axe-core does not report a button inside a link; its rule of the same name covers other roles.

In axe-core and Lighthouse Not reported

Fails

<a href="/plans"><button type="button">See plans</button></a>

Fixed

<a href="/plans">See plans</a>

aria-hidden-focus

aria-hidden elements must not contain focusable content

Why it matters

The link is hidden from screen readers but still takes focus, so a keyboard user lands on something that, for their screen reader, does not exist.

The analyzer reports

aria-hidden="true" contains <a> that remain in the tab order.

The fix

Hide it from everyone. inert on the container takes its contents out of the tab order as well; this is the usual fix for the page behind an open dialog. If nobody should see it, use hidden.

Verify it

  1. Run the analyzer on your page again: aria-hidden-focus is no longer among the failures.
  2. Tab through the page: focus never reaches the hidden part.

In axe-core and Lighthouse aria-hidden-focus

Fails

<div aria-hidden="true">
  <a href="/help">Help</a>
</div>

Fixed

<div aria-hidden="true" inert>
  <a href="/help">Help</a>
</div>

Back to the directory

3 errors

ARIA

aria-role-valid

role attribute must contain a valid, non-abstract role

Why it matters

A misspelled role is ignored, so the element is announced as plain text and nobody using a screen reader knows it can be pressed.

The analyzer reports

role="buton" is not a valid ARIA role.

The fix

Use the native element. A real button brings its role, focus and keyboard handling with it; role="button" brings only the role.

Verify it

  1. Run the analyzer on your page again: aria-role-valid is no longer among the failures.
  2. Focus it with a screen reader running: it is announced as a button, and Enter and Space both press it.

In axe-core and Lighthouse aria-roles

Fails

<div role="buton" tabindex="0">Save</div>

Fixed

<button type="button">Save</button>

aria-required-attr

Roles must carry their required ARIA attributes

Why it matters

A checkbox with no state cannot say whether it is ticked, so a screen reader user cannot tell what they have chosen.

The analyzer reports

role="checkbox" is missing required aria-checked.

The fix

Add the state the role requires, and update it on every change. Better still, use <input type="checkbox">, which keeps its own state.

Verify it

  1. Run the analyzer on your page again: aria-required-attr is no longer among the failures.
  2. Press Space on it with a screen reader running: it announces "checked" and "not checked" in turn.

In axe-core and Lighthouse aria-required-attr

Fails

<span role="checkbox" tabindex="0">Remember me</span>

Fixed

<span role="checkbox" tabindex="0" aria-checked="false">Remember me</span>

aria-reference-valid

ARIA ID references must resolve

Why it matters

The field points at a hint that is not there, so the hint (or the error message it was meant to read) is never announced.

The analyzer reports

Broken ARIA reference(s): aria-describedby → #pw-hint.

The fix

Make every id that aria-describedby, aria-labelledby or aria-controls names exist on the page, and render it before the field refers to it.

Verify it

  1. Run the analyzer on your page again: aria-reference-valid is no longer among the failures.
  2. Focus the field with a screen reader running: the hint is read after the label.

In axe-core and Lighthouse Needs review: aria-valid-attr-value

Fails

<label for="pw">Password</label>
<input id="pw" type="password" aria-describedby="pw-hint">

Fixed

<label for="pw">Password</label>
<input id="pw" type="password" aria-describedby="pw-hint">
<p id="pw-hint">At least 12 characters.</p>

Back to the directory

6 errors

The page itself

html-has-lang Most common

<html> must have a lang attribute

Why it matters

Without a language, a screen reader reads the page in its own default voice and rules: Hindi read with English pronunciation, or the other way round.

The analyzer reports

<html> has no lang attribute.

The fix

Set lang on the html element, and on any passage in another language.

Verify it

  1. Run the analyzer on your page again: html-has-lang is no longer among the failures.
  2. Listen to the first paragraph with a screen reader: the voice and pronunciation match the language.

In axe-core and Lighthouse html-has-lang

Fails

<html>

Fixed

<html lang="en">

document-title

Page must have a descriptive title

Why it matters

The title is the first thing a screen reader says on arrival, and the name of the tab. Without one, every page announces itself the same way.

The analyzer reports

Document has no <title>.

The fix

Give each page a unique title that names the page first and the site second.

Verify it

  1. Run the analyzer on your page again: document-title is no longer among the failures.
  2. Open the page in a new tab, and move between routes in a single-page app: the tab name changes and is announced each time.

In axe-core and Lighthouse document-title

Fails

<head>
  <meta charset="utf-8">
</head>

Fixed

<head>
  <meta charset="utf-8">
  <title>Order history | Shop</title>
</head>

heading-order

Heading levels must not skip

Why it matters

Screen reader users skim a page by its headings. A jump from h1 to h3 suggests a missing section, and the outline stops matching the page.

The analyzer reports

Heading level jumps from h1 to h3: "Shipping"

The fix

Choose the level from the structure, then set the size in CSS. A heading is one level below the section that contains it.

Verify it

  1. Run the analyzer on your page again: heading-order is no longer among the failures.
  2. List the headings (a screen reader's headings list, or an outline extension): the outline reads like a table of contents.

In axe-core and Lighthouse heading-order

Fails

<h3>Shipping</h3>
<p>Free over 500 rupees.</p>

Fixed

<h2>Shipping</h2>
<p>Free over 500 rupees.</p>

listitem-parent

List items must be inside a list

Why it matters

Items outside a list lose the "list, 2 items" a screen reader announces, and the count that tells a listener how much is coming.

The analyzer reports

<li> is not inside a <ul>, <ol> or <menu>.

The fix

Wrap list items in ul or ol, and style the list instead of replacing it with a div.

Verify it

  1. Run the analyzer on your page again: listitem-parent is no longer among the failures.
  2. Move into the list with a screen reader: it announces a list and the number of items.

In axe-core and Lighthouse listitem

Fails

<div>
  <li>Free returns</li>
  <li>Two-year warranty</li>
</div>

Fixed

<ul>
  <li>Free returns</li>
  <li>Two-year warranty</li>
</ul>

meta-viewport

Zooming and scaling must not be disabled

Why it matters

Blocking pinch zoom stops people with low vision enlarging the text on a phone, which is how many of them read.

The analyzer reports

Viewport meta blocks zoom: "width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no".

The fix

Remove user-scalable=no and maximum-scale. The rule fails a maximum below 2; the analyzer also asks for at least 5 (500%) in a separate rule.

Verify it

  1. Run the analyzer on your page again: meta-viewport is no longer among the failures.
  2. On a phone, pinch to zoom: the page enlarges, and at 200% nothing is cut off.

In axe-core and Lighthouse meta-viewport

Fails

<meta name="viewport"
      content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

Fixed

<meta name="viewport" content="width=device-width, initial-scale=1">

meta-refresh

Pages must not auto-refresh or redirect on a timer

Why it matters

The page reloads every 30 seconds whatever the reader is doing, so a screen reader starts again from the top and someone reading slowly never finishes.

The analyzer reports

Page refreshes after 30s.

The fix

Remove the timed refresh. Update the part that changes in place, and let the reader pause or ask for the update.

Verify it

  1. Run the analyzer on your page again: meta-refresh is no longer among the failures.
  2. Leave the page open for a few minutes while reading with a screen reader: it is never interrupted.

In axe-core and Lighthouse meta-refresh

Fails

<meta http-equiv="refresh" content="30">

Fixed

<!-- no timed refresh; update the content in place -->

Back to the directory

How it was checked

How these were made

Each reproduction is the code shown, placed in a page that is otherwise clean: a language, a title, a main landmark and one h1. “Copy the whole page” copies exactly that page.

Both pages of every entry were run through the analyzer’s own engine in Chromium 147.0.7727.15, with axe-core 4.12.1 on the same pages, on 18 October 2026. A reproduction is published only if it fails its rule, and a fix only if it clears that rule without leaving or adding a failure at level A or AA. The messages above are the engine’s own words from that run.

A rule that passes is not the end. Every entry ends with a check a person makes, because the rule confirms the markup and not the experience: the manual testing page puts those checks in order.

Where this comes from

Sources

Found a mistake? Write to us and we will correct it.