What 1.1.1 requires

All non-text content that is presented to the user has a text alternative that serves the equivalent purpose, except for the situations listed below.

Controls, Input
If non-text content is a control or accepts user input, then it has a name that describes its purpose. (Refer to Success Criterion 4.1.2 for additional requirements for controls and content that accepts user input.)
Time-Based Media
If non-text content is time-based media, then text alternatives at least provide descriptive identification of the non-text content. (Refer to Guideline 1.2 for additional requirements for media.)
Test
If non-text content is a test or exercise that would be invalid if presented in text, then text alternatives at least provide descriptive identification of the non-text content.
Sensory
If non-text content is primarily intended to create a specific sensory experience, then text alternatives at least provide descriptive identification of the non-text content.
CAPTCHA
If the purpose of non-text content is to confirm that content is being accessed by a person rather than a computer, then text alternatives that identify and describe the purpose of the non-text content are provided, and alternative forms of CAPTCHA using output modes for different types of sensory perception are provided to accommodate different disabilities.
Decoration, Formatting, Invisible
If non-text content is pure decoration, is used only for visual formatting, or is not presented to users, then it is implemented in a way that it can be ignored by assistive technology.
Success criterion 1.1.1 Non-text Content (Level A), quoted from Web Content Accessibility Guidelines (WCAG) 2.1, W3C Recommendation 06 May 2025. Copyright © 2020-2025 World Wide Web Consortium. Used under the W3C Document License.

A text alternative is what a screen reader speaks, what a braille display shows and what appears when the image does not load. Serving the equivalent purpose means doing the job the image does on this page: a product photo names the product, a chart states its point, an image button names its action.

Context changes the answer. Understanding 1.1.1 gives the same picture of the world the alternative “International Travel” on a travel site and “International Campuses” on a university’s. Inside a link or a button, the alternative names where it goes or what it does.

An image that adds nothing gets an empty alternative, alt="", so assistive technology skips it. WCAG lists both directions as failures: a file name or placeholder as the alternative (F30), and a non-empty alt such as “spacer” on an image that should be ignored (F39).

Common failures

Under each example: what axe-core and Rampa reported on the markup before the fix, in a run with Gemma 4 12B on 8 October 2026.

A file name as the alternative

Content systems often fill the alt with the file name, and a screen reader then reads “8841-front”. WCAG lists this as failure F30.

Illustration: a green backpack with a zipped front pocket and a yellow tag.

Before, fails 1.1.1

<img src="/products/8841-front.svg" alt="8841-front">

After, passes

<img src="/products/8841-front.svg"
     alt="Green backpack with a zipped front pocket">
axe-core

Passes: image-alt finds an alt.

Rampa
✗ html > body > main > img:nth-of-type(2)
  The text alternative "8841-front" is a file name or a placeholder.
  Evidence: "8841-front"
  Patch:
    - <img src="/products/8841-front.svg" alt="8841-front">
    + <img src="/products/8841-front.svg" alt="Green backpack with a yellow zipper pull">
  confidence high · 1/1 runs · evidence verified · id d5195a6a68ff

An alternative written for another image

The banner changed for the winter campaign and the alt still describes the summer one. Not updating an alternative when the image changes is WCAG failure F20, and only something that looks at the image can notice it.

Illustration: a banner that reads “Winter sale, leather boots, 20% off”, next to a brown boot.

Before, fails 1.1.1

<img src="/banners/winter-sale.svg"
     alt="Summer sale: sandals 30% off">

After, passes

<img src="/banners/winter-sale.svg"
     alt="Winter sale: leather boots 20% off">
axe-core

Passes: image-alt finds an alt.

Rampa
✗ html > body > main > img:nth-of-type(1)
  The text alternative "Summer sale: sandals 30% off" describes something the image does not show.
  Evidence: "Summer sale: sandals 30% off"
  Patch:
    - <img src="/banners/winter-sale.svg" alt="Summer sale: sandals 30% off">
    + <img src="/banners/winter-sale.svg" alt="Winter sale: leather boots 20% off">
  confidence high · 1/1 runs · evidence verified · id 47563eaa69e7

An icon link called “icon”

Inside a link, the image’s alternative is the link’s name, so it has to say where the link goes. A screen reader announces a link called “icon” and nothing more.

Illustration: a shopping cart icon.

Before, fails 1.1.1

<a href="/cart"><img src="/icons/cart.svg" alt="icon"></a>

After, passes

<a href="/cart"><img src="/icons/cart.svg" alt="Shopping cart"></a>
axe-core

Passes: image-alt finds an alt and link-name finds a name.

Rampa
✗ html > body > header > a > img
  The text alternative "icon" is a file name or a placeholder.
  Evidence: "icon"
  Patch:
    - <img src="/icons/cart.svg" alt="icon">
    + <img src="/icons/cart.svg" alt="Shopping cart">
  confidence high · 1/1 runs · evidence verified · id 0dc8e036ebda

What axe-core checks

axe-core 4.14.0 maps seven rules to 1.1.1. Each checks that an element has a text alternative or an accessible name; image-alt also accepts an image marked as decorative. Rampa runs them first and reports their failures as they are. An image that image-alt, input-image-alt, role-img-alt or svg-img-alt failed never goes to the model.

axe-core 4.14.0 rules for 1.1.1, and the rules next to it
RuleWhat it checksMapped toIn a Rampa run
image-alt, rule page at Deque UniversityImages must have alternative text1.1.1runs
input-image-alt, rule page at Deque UniversityImage buttons must have alternative text1.1.1, 4.1.2runs
role-img-alt, rule page at Deque University[role="img"] and [role="image"] elements must have alternative text1.1.1runs
svg-img-alt, rule page at Deque University<svg> elements with an img or image role must have alternative text1.1.1runs
object-alt, rule page at Deque University<object> elements must have alternative text1.1.1runs
aria-meter-name, rule page at Deque UniversityARIA meter nodes must have an accessible name1.1.1runs
aria-progressbar-name, rule page at Deque UniversityARIA progressbar nodes must have an accessible name1.1.1runs
image-redundant-alt, rule page at Deque UniversityAlternative text of images should not be repeated as textbest practicenot run: best practice

None of them reads what the alternative says. alt="8841-front", alt="icon" and an alt written for another picture all pass. The best-practice rule image-redundant-alt flags an alt that repeats the text next to it; Rampa runs only rules tagged with WCAG A and AA, so it is not part of a run.

Each rule links to its page at Deque University, which makes axe-core.

What Rampa judges, and how

What goes to the model

Every img, input type="image", element with role="img" (inline SVG included) and named canvas that has a non-empty text alternative, is not hidden, and was not failed by axe-core. An empty alt marks the image as decorative, so it is not sent. Images are captured as they render: the first 25 on the page that are at least 8 by 8 pixels. An image without a capture is not judged.

What the model sees

  • The image as it renders on the page: a PNG of the element, with its size, crop and CSS. Fixed and sticky layers, such as a cookie banner, are hidden while it is taken.
  • The current text alternative and the image’s file name.
  • The element’s markup, up to 500 characters.
  • The name of the link or button the image sits in, which the alternative has to convey.
  • Text of the elements around it, up to 300 characters, and the page language for the suggestion.

What it must answer

A verdict (pass, fail or cannot tell), the current alternative copied as evidence, the problem (a file name or placeholder, too generic, wrong content, missing information, or decorative), what the image shows in one sentence, a suggested alternative under 125 characters in the page’s language, and a confidence.

What drops a claim

  • The evidence is not the current text alternative.
  • There is no description of what the image shows.
  • A pass names a problem, or a fail names none.
  • A fail that is not about decoration has no suggestion, one over 250 characters, or one equal to the current alternative.

The patch

The suggestion replaces the alt, or the aria-label on elements that have no alt, such as a canvas. For a decorative image, the patch empties the alt. For obvious placeholders such as img-1 or IMG_2034.jpg, a fixed pattern names the problem in the message; the verdict still comes from the model. A suggested alt is for a person to review: what a model says it sees cannot be checked against the page.

For every criterion

  • Page content reaches the model marked as data, and the prompt tells it to ignore any instruction inside.
  • Answers are cached by a hash of the prompt, the image, the model and its settings, so the same input never calls a model twice.
  • --runs 3 asks three times and keeps the majority; when runs disagree, confidence drops. Findings below --min-confidence (medium by default) are hidden, and --verbose lists them.
  • Claims dropped by verification are counted in every report, never shown as findings.

How Rampa was measured on it

W3C ACT test cases for 1.1.1: precision, recall and F1, Gemma 4 12B on a local GPU
SetTestsCasesaxe-core, precision / recallRampa, precision / recall / F1
1.1.1, image has a name (ACT 23a2a8)syntax181.00 / 1.001.00 / 1.00 / 1.00
1.1.1, name describes the image (ACT qt1vmo)meaning16not defined, nothing flagged / 0.001.00 / 1.00 / 1.00

Corrupted pairs: Rampa told 2 of 2 apart (image alt), axe-core 0. A pair is a passing test page and a copy broken on purpose; a checker that gives both the same verdict is not judging.

Run on 9 October 2026: axe-core 4.14.0, Gemma 4 12B on a local GPU, reasoning off, one run, ACT test cases a9a1483e. Small samples and one run: read the numbers as a working pipeline, not as a result.

Read with these caveats

  • The first run, on 2026-10-07, had recall 0.67 on qt1vmo. The misses never reached a model, because Rampa did not treat <canvas> as an image; with that fixed, recall is 1.00.
  • On 1.1.1 and 3.1.2, openai:gpt-6-luna got the same numbers as Gemma in two runs with fresh calls, at about US$ 0.005 per run.

Method and error analysis in the README

Limitations

  • An image with an empty alt is taken as decorative and never sent, so an informative image hidden that way is not caught.
  • Only the first 25 images of a page are captured, and images smaller than 8 by 8 pixels are skipped.
  • CSS background images, image maps (area), video and audio are not judged.
  • A chart or diagram that needs a long description is judged on its short alternative only.
  • The model sees pixels, not facts: it cannot know who is in a photo or whether a product code is right. Review every suggested alt before you use it.
  • Judging images needs a model with vision, for 1.1.1 and for 1.4.5. Text-only models can judge the other criteria with --criteria 1.3.5,2.4.2,2.4.4,2.4.6,3.1.1,3.1.2,3.3.2.

Questions about 1.1.1

Can a tool check alt text quality automatically?

In part. A rule can see that an alt exists, and word lists catch file names and words like “image”. Whether the alt says what the image shows takes judgment: Rampa sends the rendered image and its alt to a vision model, one image at a time, and keeps the answer only when the model quotes the alt that is on the page. A person should still review each suggestion.

Does axe-core check alt text quality?

No. Its image-alt rule checks that an image has a text alternative or is marked as decorative, so alt="img-1" passes. Whether the text fits the image is left to people.

What should the alt of a decorative image be?

Empty: alt="", so screen readers skip the image. A word such as “spacer” or “image” in it is WCAG failure F39. When the model says an image is decorative, Rampa’s patch empties the alt.

Are my images sent to a cloud provider?

Only if you choose one. With a local model through Ollama or LM Studio, the image never leaves your machine. With a provider, each image goes in its own request, with its alt and a little context.

Check your pages

Rampa is not on npm yet. Clone it and run it from source with Node.js 22.12 or newer and Chrome or Edge. --criteria 1.1.1 judges only this criterion; leave it out to run the eight that run by default.

With Ollama running, Rampa picks a local model by itself; node dist/cli.mjs doctor says what is missing.

git clone https://github.com/guilhermebsantiago/rampa-cli.git
cd rampa-cli
pnpm install && pnpm build
node dist/cli.mjs check https://example.com --criteria 1.1.1

Checked against rampa-cli (commit 0459809) and the W3C sources on 9 October 2026.