image-alt-text

Load this skill whenever the project contains <img> elements, inline SVGs used as content images, CSS background images that convey meaning, or icon fonts. Under no circumstances omit alt text on meaningful images. Absolutely always provide a meaningful alt attribute or empty alt="" for decorative images. Apply WCAG 2.2 SC 1.1.1 — every non-text element requires a text alternative.

Image Alt Text Accessibility Skill

Canonical source: examples/IMAGE_ALT_TEXT_ACCESSIBILITY_BEST_PRACTICES.md in mgifford/ACCESSIBILITY.md This skill is derived from that file. When in doubt, the example is authoritative.

Apply these rules when creating, reviewing, or auditing any page containing images. Only load this skill if the project contains <img> elements, inline SVG images used as content, or CSS background images that may convey meaning.


Core Mandate

WCAG 2.2 Success Criterion 1.1.1 — Non-text Content (Level A): every non-text element must have a text alternative conveying the same meaning and purpose. There are no exceptions for decorative images — those require an explicit empty alt attribute.

Automated tools can flag missing alt text, but only human judgment can determine whether alt text is meaningful and appropriate for the context.


Severity Scale (this skill)

LevelMeaning
CriticalImage conveying essential meaning has no alt attribute, or alt is entirely absent
SeriousFunctional image (button/link) has no text alternative, preventing keyboard/screen reader use
ModerateAlt text is present but inaccurate, redundant ("image of…"), or missing meaningful context
MinorAlt text is slightly verbose or could be improved but does not prevent understanding

The Alt Text Decision Tree

Use this flowchart (based on the W3C WAI Images Tutorial):

Does the image contain text?
├── YES → Use the same text as the alt attribute (unless decorative/logo)
└── NO
    └── Is the image used for a functional purpose (link, button)?
        ├── YES → Describe the destination/action (e.g., "Go to homepage")
        └── NO
            └── Does the image convey information not present in surrounding text?
                ├── YES
                │   └── Is the image complex (chart, diagram, graph)?
                │       ├── YES → Provide a short alt + long description in nearby text
                │       └── NO  → Write a concise description of the content and meaning
                └── NO
                    └── Is the image purely decorative or redundant?
                        ├── YES → Use empty alt: alt=""
                        └── NO  → Re-evaluate — the image likely carries meaning

Image Categories and Requirements

Informative Images

Images that convey information not expressed in surrounding text.

<!-- DO: Describe the meaning/content -->
<img src="quarterly-growth.png" alt="Bar chart showing 23% revenue growth in Q3 2024">

<!-- DON'T: Describe visual appearance only -->
<img src="quarterly-growth.png" alt="Blue and green bar chart">

<!-- DON'T: Use file names or generic labels -->
<img src="quarterly-growth.png" alt="quarterly-growth.png">
<img src="quarterly-growth.png" alt="image">

Decorative Images

Images that are purely aesthetic and add no information beyond what the page text already provides.

<!-- DO: Empty alt for decorative images -->
<img src="decorative-divider.png" alt="">

<!-- DO: aria-hidden for inline SVG decorations -->
<svg aria-hidden="true" focusable="false">...</svg>

<!-- DON'T: Omit alt entirely — screen readers announce the filename -->
<img src="decorative-divider.png">

<!-- DON'T: Use "decorative" or "spacer" as alt text -->
<img src="decorative-divider.png" alt="decorative">

When is an image truly decorative? Only if it is purely aesthetic (border, texture, flourish), adds no information beyond surrounding text, and removing it would not affect a user's understanding.

If you are debating whether an image is decorative, it probably is not. When in doubt, provide alt text. The cost of unnecessary alt text is low; the cost of missing alt text can be complete loss of meaning.

Functional Images

Images that are the only content of a link or button.

<!-- DO: Describe the link destination -->
<a href="/home">
  <img src="logo.svg" alt="Go to homepage">
</a>

<!-- DO: Describe the button action -->
<button>
  <img src="search-icon.svg" alt="Search">
</button>

<!-- DO: Use aria-label on the button, empty alt on the image -->
<button aria-label="Search">
  <img src="search-icon.svg" alt="">
</button>

<!-- DON'T: Leave functional images with empty alt (creates unlabelled control) -->
<button>
  <img src="search-icon.svg" alt="">
  <!-- Missing accessible name — use aria-label on the button instead -->
</button>

Complex Images

Charts, graphs, diagrams, maps, and infographics where a short alt cannot convey all information.

<!-- Pattern 1: Alt summary + adjacent long description -->
<figure>
  <img
    src="accessibility-adoption-chart.png"
    alt="Line chart: WCAG AA adoption rose from 38% in 2020 to 67% in 2024"
    aria-describedby="chart-desc">
  <figcaption id="chart-desc">
    Annual WCAG 2.1 Level AA adoption rates from 2020 to 2024 across a sample
    of 10,000 public websites. Adoption grew steadily from 38% (2020) to 67%
    (2024), driven by increased procurement requirements.
  </figcaption>
</figure>

Images of Text

<!-- DO: Reproduce the exact text in the alt attribute -->
<img src="sale-banner.png" alt="Summer Sale: 50% off all items through July 31">

<!-- DON'T: Describe that it is text -->
<img src="sale-banner.png" alt="Sale banner showing promotional text">

Prefer actual text over images of text whenever possible (WCAG 1.4.5).

Groups of Images

When multiple images work together to convey a single piece of information (e.g., a star rating):

<!-- Star rating: 4 out of 5 stars — only the first image needs meaningful alt -->
<img src="star-filled.png" alt="Rating: 4 out of 5 stars">
<img src="star-filled.png" alt="">
<img src="star-filled.png" alt="">
<img src="star-filled.png" alt="">
<img src="star-empty.png" alt="">

Linked Images with Adjacent Text

When an image and text are together inside the same link:

<!-- DO: Empty alt when link text describes the destination -->
<a href="/articles/accessibility-guide">
  <img src="accessibility-thumbnail.jpg" alt="">
  <span>The Complete Accessibility Guide</span>
</a>

<!-- DON'T: Duplicate the link text in alt -->
<a href="/articles/accessibility-guide">
  <img src="accessibility-thumbnail.jpg" alt="The Complete Accessibility Guide">
  The Complete Accessibility Guide
</a>

Writing Quality Alt Text

  1. Be concise but complete. Aim for 125 characters or fewer for simple images; use long descriptions for complex images.
  2. Describe content and purpose, not appearance. "Person in a wheelchair using a laptop" is more useful than "image of a person".
  3. Context is everything. The same image can have different alt text depending on how it is used.
  4. Do not start with "Image of", "Picture of", or "Photo of". Screen readers already announce that they are reading an image.
  5. Avoid keyword stuffing. Alt text serves users, not search engines.
  6. Include text that appears within the image.
  7. Match the level of detail to the image's role.

Common Bad Alt Text Patterns (Critical/Serious to flag and fix)

Missing or absent alt attribute — Critical

<!-- WRONG: Screen reader reads the filename -->
<img src="Q3-revenue-chart-final-v2.png">

<!-- RIGHT -->
<img src="Q3-revenue-chart-final-v2.png"
     alt="Bar chart: Q3 2024 revenue reached $4.2M, up 18% from Q2">

Filename or CMS-injected alt text — Serious

<!-- WRONG -->
<img src="golden-retriever.jpg" alt="golden-retriever.jpg">
<img src="dog.png" alt="This image has an empty alt attribute; its file name is dog.png">

Generic single-word placeholders — Serious

The following values are flagged as errors by multiple accessibility checkers:

<!-- WRONG -->
<img src="photo.jpg" alt="image">
<img src="photo.jpg" alt="photo">
<img src="photo.jpg" alt="graphic">
<img src="photo.jpg" alt="chart">
<img src="photo.jpg" alt="alt">
<img src="spacer.gif" alt="spacer">     <!-- use alt="" instead -->
<img src="divider.png" alt="decorative"> <!-- use alt="" instead -->

Draft/placeholder text — Serious

<!-- WRONG -->
<img src="portrait.jpg" alt="TBD">
<img src="portrait.jpg" alt="TODO">
<img src="portrait.jpg" alt="placeholder">
<img src="portrait.jpg" alt="null">
<img src="portrait.jpg" alt="undefined">

"Type" prefix phrases — Moderate

<!-- WRONG: Redundant medium prefix -->
<img src="team-photo.jpg" alt="Image of the team">
<img src="team-photo.jpg" alt="Photo of team members">

<!-- RIGHT -->
<img src="team-photo.jpg" alt="The Civic Innovations team of 12 staff gathered outside City Hall">

Alt text that duplicates a figcaption — Moderate

<!-- WRONG: Screen reader announces the text twice -->
<figure>
  <img src="annual-report-cover.jpg"
       alt="2024 Annual Report cover showing the city skyline at dusk">
  <figcaption>2024 Annual Report cover showing the city skyline at dusk</figcaption>
</figure>

<!-- RIGHT: Caption fully describes — use empty alt -->
<figure>
  <img src="annual-report-cover.jpg" alt="">
  <figcaption>2024 Annual Report cover showing the city skyline at dusk</figcaption>
</figure>

Name-only alt for person portraits — Moderate

<!-- POOR: Name only -->
<img src="j-smith.jpg" alt="J Smith">

<!-- BETTER: Include role and context -->
<img src="j-smith.jpg"
     alt="Dr. Jane Smith, Chief Medical Officer, presenting at the 2024 health summit">

CSS Background Images

CSS background-image does not support alt text. Use only for decorative purposes.

/* OK: Decorative pattern */
.hero { background-image: url('geometric-pattern.svg'); }
<!-- NOT OK: Meaningful image as CSS background (invisible to screen readers) -->
<div style="background-image: url('award-badge.png')"></div>

<!-- DO: Use <img> for meaningful images -->
<img src="award-badge.png" alt="Winner: Best Accessibility Tool 2024">

Automated vs. Human Testing

Automated tools can detectRequires human review
Missing alt attributeWhether alt text is meaningful
Empty alt on functional imagesWhether alt text matches context
Alt text that equals the file nameWhether a decorative image actually needs alt text
Suspicious prefix phrases ("image of")Whether the description conveys the right meaning
Known placeholder values ("TBD", "null")Whether content-author intent was decorative or informative
Alt text identical to adjacent figcaptionWhether the alt or the caption should be kept

Automated tools such as axe-core detect structural issues. Human review is always required to evaluate quality.


Definition of Done Checklist

  • Every <img> element has an alt attribute (even decorative images use alt="")
  • Decorative images use alt="" and are confirmed to add no meaning
  • Functional images (links, buttons) describe the action or destination
  • Alt text does not begin with "image of", "picture of", or "photo of"
  • Alt text does not repeat the file name or generic label ("image", "photo", "graphic", "chart")
  • Alt text is not a draft placeholder ("TBD", "TODO", "null", "none", "undefined", "placeholder")
  • Alt text is not a machine-generated code or CMS-injected message
  • Complex images (charts, diagrams) have both a short alt and a long description
  • Images of text reproduce the exact text in the alt attribute
  • Grouped images convey combined meaning via one image's alt (others are alt="")
  • Linked images with adjacent link text use alt="" on the image
  • Figures with a <figcaption> do not duplicate the caption verbatim in the alt
  • Portrait images include the person's role and context, not just their name
  • CSS background images are decorative (meaningful images use <img>)
  • Alt text has been reviewed in context, not just in isolation
  • Alt text has been tested with a screen reader (NVDA + Firefox or VoiceOver + Safari)

Key WCAG Criteria

  • 1.1.1 Non-text Content (A) — Critical if any meaningful image has no text alternative
  • 1.4.5 Images of Text (AA) — prefer real text over images of text
  • 1.4.9 Images of Text (No Exception) (AAA)
  • 4.1.2 Name, Role, Value (A) — all UI components have accessible names and roles

References