Fix a failing check
Your pull request carries an accessibility annotation and you would like it gone. This page takes one violation from the annotation to a green local run. You do not need to learn axe, and you do not need to know how the check was set up. You need the rule it names and the element it fired on.
The annotation
Section titled “The annotation”This is what the job left on the run:
::error title=a11y/image-alt::Images must have alternative text: 1 node on http://127.0.0.1:4173/orphan.html.%0Aimg → Fix any of the following: Element does not have an alt attribute; …%0A <img src="y.png">%0Aaxe-core 4.13.0 image-alt: Ensure <img> elements have alternative text or a role of none or presentation%0AGuide: https://dequeuniversity.com/rules/axe/4.13/image-alt?application=playwrightGitHub shows each %0A as a line break. image-alt is the axe rule, and
orphan.html is the published page it fired on. The next two lines name the
element, say what to change, and print its html. The last two say what the rule
checks and link its page on Deque University, which explains the rule itself
rather than your page.
There is no file and no line number, because the check saw a rendered URL rather than your source. Finding the source is the first thing you do, and the selector in the local run is what points at it.
Reproduce it locally
Section titled “Reproduce it locally”Serve your build, then check that one page. --no-crawl skips the sitemap and
the link following, so the run takes a couple of seconds instead of a minute:
npx @hawkeyexl/manni a11y check http://127.0.0.1:4173/orphan.html --no-crawlChecked 1 of 1 pages (no crawl)✗ http://127.0.0.1:4173/orphan.html score 94 1 error error image-alt (axe: critical) 1 node Images must have alternative text axe-core 4.13.0 image-alt: Ensure <img> elements have alternative text or a role of none or presentation Guide: https://dequeuniversity.com/rules/axe/4.13/image-alt?application=playwright img → Fix any of the following: Element does not have an alt attribute; … <img src="y.png">
1 violation on 1 of 1 pagesIf the command stops with No browser found, install one once with
npx playwright install chromium. Get started has
the detail, including how to serve a build.
The four things every finding carries
Section titled “The four things every finding carries”| Part | In this finding | What to do with it |
|---|---|---|
| Rule id | image-alt | Names the rule in one token. Search your templates for the pattern it describes, and use it when you talk about the finding. |
| Selector | img | The element that failed, as a CSS selector. Match it against the rendered page to find the component or partial that emits it. |
| Failure summary | Element does not have an alt attribute; … | axe’s statement of what is wrong with this element. It lists every condition that would have satisfied the rule. |
| Guide | The Deque University link | Explains the rule, why it exists, and the accepted ways to satisfy it. Read it when the summary alone is not enough. |
The pretty output prints the first three failing elements per rule, each with
its html, and (+N more) past three. When you need every element, use
--format json:
{ "id": "image-alt", "severity": "error", "impact": "critical", "help": "Images must have alternative text", "helpUrl": "https://dequeuniversity.com/rules/axe/4.13/image-alt?application=playwright", "nodes": [ { "target": "img", "html": "<img src=\"y.png\">", "summary": "Fix any of the following:\n Element does not have an alt attribute\n …" } ], "guidance": { "id": "axe-core 4.13.0", "rule": "image-alt", "description": "Ensure <img> elements have alternative text or a role of none or presentation", "guide": "https://dequeuniversity.com/rules/axe/4.13/image-alt?application=playwright" }}That is one entry of results[].violations, with the tags array left out.
html is usually the fastest way to find the source, because the attribute
values in it are yours.
Make the fix
Section titled “Make the fix”nodes[0].html gives <img src="y.png">, so the source is whatever emits that
image. Add the alt text there:
<h1>Orphan</h1><img src="y.png" /><img src="y.png" alt="The orphan diagram" />Writing the words is the part no tool does for you. Describe what the image
conveys in context, not what it depicts. An icon beside a link that already says
“Download” conveys nothing extra, and its alt attribute should be empty:
alt="". That is a deliberate statement that the image is decorative, and it is
different from having no attribute at all.
Confirm it
Section titled “Confirm it”Rebuild, then run the same command again:
Checked 1 of 1 pages (no crawl)✓ http://127.0.0.1:4173/orphan.html score 100
0 violations on 0 of 1 pagesExit 0, and the annotation is gone on the next push. The score went from 94
to 100, which is the share of applicable axe rules that passed. Violations
below the severity floor do not count against it. Read the exit
code as the verdict and the score as a trend.
Why there is no --fix
Section titled “Why there is no --fix”check sees a rendered URL. It never sees the Markdown, the template, or the
component tree that produced it. There is nothing at that level it could edit,
and rewriting the served HTML would fix a build artifact that the next build
throws away.
The deeper reason holds even where the source is reachable. The fix for
image-alt is a sentence describing an image, and the fix for button-name is
the name of what the button does. Both are content. A tool that invented them
would produce a page that passes the check and still fails the reader, which is
worse than a red build.
What the check does deterministically is name the element and the condition that failed. That is the node line, and it is where the machine’s contribution ends.
What axe cannot decide from a rendered page
Section titled “What axe cannot decide from a rendered page”A green run means no rule fired, not that the page is accessible. Four classes of problem are outside what a rendered page can settle.
- Text that is present but wrong.
alt="image"satisfiesimage-alt.<button>Click here</button>satisfiesbutton-name. Both pass, and neither helps anyone. - Rules axe could not decide. Contrast over a background image is the common
one. These are counted as
incompletein-f jsonoutput, and they never fail the run. A person has to look. - Anything that needs interaction. Keyboard order, focus traps, a menu that opens on hover, a dialog that does not return focus. The check loads a page and reads it once.
- Meaning and order. Whether a heading level matches the document’s structure, whether the reading order matches the visual one, whether a label describes its field truthfully.
What an automated check catches is the part that regresses silently, which is why it belongs in CI. It is a floor rather than a certificate, and a manual review still finds things no rule can.