Remediation guide

How to Fix Missing Alt Text on Images — WCAG 1.1.1

Missing or empty alt text on images is the most-cited accessibility failure in ADA website demand letters. Automated scanners detect it instantly from the HTML source. The fix is straightforward once you understand the three image types — but applying it correctly requires knowing when to describe, when to leave the alt empty, and when to describe the function instead of the visual content.

The three image types — and what each needs

Every image falls into one of three categories. The category determines whether you need alt text and how to write it.

Informative

Informative images

Images that convey meaning not present elsewhere in the text: product screenshots, team photos in bios, charts, diagrams, article illustrations.

Needs: alt text describing what the image communicates in context — not its visual appearance, but its meaning.

Decorative

Decorative images

Images that serve no informational purpose beyond visual styling: dividers, background textures, stock-photo filler where adjacent text provides all context.

Needs: alt="" (empty string). This tells screen readers to skip the element. A missing alt attribute is different — it causes the reader to announce the filename.

Functional

Functional images

Images that are the only content inside a link or button: a logo linking home, a search icon in a button, a social icon linking to a profile.

Needs: alt text describing what the link goes to or what the button does — not what the image looks like. The alt text is the control’s label.

Code examples for each type

Good — informative images

<!-- Screenshot: describe what it shows -->
<img src="dashboard.png"
     alt="Project dashboard showing 3 active builds, 94% uptime, and a deploy button">

<!-- Team headshot in a bio section -->
<img src="alex-chen.jpg" alt="Alex Chen, Lead Engineer">

<!-- Diagram in an article -->
<img src="tcp-handshake.svg"
     alt="TCP three-way handshake: SYN from client, SYN-ACK from server, ACK from client">

Good — decorative images

<!-- Decorative divider: empty alt string, NOT omitted -->
<img src="wave-divider.svg" alt="">

<!-- Stock photo where adjacent text provides all context -->
<img src="team-collaboration.jpg" alt="">

Good — functional images (inside a link or button)

<!-- Logo link: describe the destination -->
<a href="/">
  <img src="logo.svg" alt="Acme Corp — go to homepage">
</a>

<!-- Icon-only button: describe the action, not the icon -->
<button type="submit">
  <img src="search-icon.svg" alt="Search">
</button>

Wrong — all of these are WCAG 1.1.1 failures

<!-- Missing alt attribute: screen reader announces the filename -->
<img src="hero-2024-v3.jpg">

<!-- Meaningless placeholder alt -->
<img src="product-shot.png" alt="image">

<!-- Empty alt on an informative image -->
<img src="revenue-chart-q3.png" alt="">

<!-- Describing appearance instead of function on a link image -->
<a href="/"><img src="logo.svg" alt="Blue circle with white text"></a>

5 rules for writing good alt text

These rules apply to informative images — the ones that need descriptive alt text. Apply them in order when you’re not sure what to write.

  1. Describe what the image communicates, not what it looks like

    Alt text is a functional replacement — it should give the reader the same understanding they’d get from seeing the image. A screenshot of your SaaS dashboard should describe what information the dashboard shows, not that it is a "screenshot with a blue sidebar". Context matters: the same photo might need different alt text depending on what point the surrounding content is making.

  2. Don’t start with “image of” or “photo of”

    Screen readers already announce “image” (or “graphic”) before reading the alt text. Starting with “image of a person” means users hear “image — image of a person”. Skip the prefix and go straight to the content: “Alex Chen, Lead Engineer” instead of “Photo of Alex Chen, Lead Engineer”.

  3. Match length to information density

    There’s no required length limit. A team headshot: 3–6 words (name and role). A product screenshot: 15–25 words describing what the interface shows. A data chart: a brief summary in alt text, plus a data table or paragraph below the image containing the full data. The W3C technique G94 recommends a short text alternative in alt; G92 recommends a longer description in adjacent text for complex images.

  4. For functional images, describe the destination or action

    An image inside a link or button is a UI control. Its alt text is the control’s accessible label, not an image description. For links: describe where the link goes (“Copper Bay Labs homepage”). For buttons: describe what the button does (“Search”, “Close menu”, “Submit payment”). The visual appearance of the icon is irrelevant.

  5. For complex images, supplement with visible text

    Charts, infographics, and diagrams often communicate data that can’t be compressed into a short string without losing meaning. Provide a brief summary in the alt attribute, then include the underlying data as a visible HTML table or paragraph below the image. Use aria-describedby to link the image to its description element. This makes the data accessible to everyone, not just screen reader users.

How to find images with missing alt text

1. ShipSafe (fastest for a quick page check)

Paste your URL into ShipSafe. It reads the page’s source HTML and flags every <img> missing an alt attribute and every image with a suspicious placeholder value (“image”, “photo”, a URL-looking string). Results in under 10 seconds, no install required.

2. Axe DevTools browser extension (most thorough)

Install the free Axe DevTools extension for Chrome or Firefox. Open any page, right-click → Inspect → click the “axe DevTools” tab. Run the scan: Axe identifies every WCAG 1.1.1 violation with a specific element selector you can click to jump to the node. It catches missing alt attributes, empty alt on informative images, and alt="image"-style non-descriptions.

3. Chrome DevTools Elements search (bulk audit)

Open DevTools (F12) → Elements panel → Ctrl+F (Windows) or Cmd+F (Mac). Search for img:not([alt]) to find all images missing an alt attribute. This won’t catch empty-alt-on-informative-images; use Axe for that.

For CI coverage: run npx axe-core-cli <url> --tags wcag2a for a JSON report of all Level A violations including 1.1.1. Or use Playwright with the axe-core library to catch regressions in a pre-deploy test.

Fix missing alt text in your builder or framework

WordPress (Gutenberg)

Click the Image block → right sidebar → Alt Text field. Check Decorative image for purely decorative images (sets alt="" correctly). For the Media Library: open any image → right column → Alternative Text. Alt text set in the Media Library propagates everywhere the image is used.

WordPress (Classic Editor)

Click the image in the editor → pencil Edit Image icon → Alt Text field in the Image Details modal. For the Media Library: Media → Library → click the image → Alternative Text in the Attachment Details panel.

Webflow

Select the image element on the canvas → right Settings panel → Alt field. For decorative images, enter a single space (Webflow’s UI doesn’t accept an empty string; a space renders as alt=" " which screen readers treat as empty). For precise control, set alt="" directly in code export mode.

Squarespace

Click the image → pencil icon → Filename & Alt Text → Alt Text field. For gallery images, open image details via the pencil icon in the gallery editor. Alt text is stored per-image and persists across the site.

Wix

Click the image → Settings (gear icon) → What’s in the image? (Alt text) field. Background image sections cannot have alt text set — they are CSS background images and are inaccessible to screen readers by nature; treat them as decorative.

Next.js Image component

The next/image <Image> component requires an alt prop — TypeScript will error if it’s absent. For decorative images, pass alt="" explicitly.

// Informative
<Image src="/dashboard.png"
  alt="Dashboard showing 3 active projects" />

// Decorative
<Image src="/divider.svg" alt="" />

React (plain img tags)

The ESLint plugin eslint-plugin-jsx-a11y (bundled in CRA and most starters) enforces jsx-a11y/alt-text, requiring a non-absent alt prop. alt="" is valid for decorative images. Run npx eslint src/ --rule 'jsx-a11y/alt-text: error' to surface all violations.

AI builders (Lovable, Bolt, v0, Cursor)

Open the code view and search for <img. AI builders frequently omit alt or generate alt="[object Object]" or the filename. Edit each occurrence directly. Then prompt: “add descriptive alt text to all images — use empty alt for decorative ones” to fix future output.

Special cases

Inline SVG elements

An SVG embedded as a <svg> element in HTML doesn’t accept an alt attribute. For informative inline SVGs, add role="img" and a <title> child as the text alternative:

<svg role="img" aria-labelledby="chart-title" viewBox="0 0 400 200">
  <title id="chart-title">Monthly active users — Q3 2024</title>
  <!-- SVG content -->
</svg>

For decorative inline SVGs (icons next to visible text labels, background graphics), remove them from the accessibility tree entirely:

<svg aria-hidden="true" focusable="false" viewBox="0 0 24 24">
  <!-- decorative icon -->
</svg>

CSS background images

Images applied via background-image in CSS are invisible to screen readers — they are presentational by definition and cannot carry alt text. Only use CSS background-image for decorative content. If an image is informative and must remain as a background image for layout reasons, provide a visually-hidden text alternative in the HTML:

<div class="hero" style="background-image:url('hero.jpg')">
  <span class="sr-only">Aerial view of downtown at sunset</span>
</div>

Icon fonts (Font Awesome, Material Icons)

Icon fonts render glyphs as text characters that screen readers may announce unpredictably. The correct pattern: hide the icon element from the accessibility tree and provide the accessible name on the containing control:

<!-- Button: accessible name on the button, icon hidden -->
<button type="button" aria-label="Delete">
  <i class="fa fa-trash" aria-hidden="true"></i>
</button>

<!-- Link with visible text: hide the icon, keep the text -->
<a href="/settings">
  <i class="fa fa-cog" aria-hidden="true"></i>
  Settings
</a>

Complex images (charts, infographics)

For complex images where a brief alt string can’t capture all the information, provide a short summary in alt and link the image to a longer visible description with aria-describedby:

<figure>
  <img src="revenue-q3.png"
       alt="Q3 2024 revenue by product line"
       aria-describedby="revenue-q3-data">
  <figcaption id="revenue-q3-data">
    Product A: $1.2M (+18% vs Q2). Product B: $890K (flat).
    Product C: $420K (flat). Total: $2.51M.
  </figcaption>
</figure>

Verify your fixes with ShipSafe

After adding or updating alt text, run ShipSafe on the same URL to confirm the changes are live. ShipSafe reads the page’s HTML source and flags remaining <img> elements with a missing or suspicious alt attribute. Look for the Accessibility category in the results — a green check next to “Images have alt text” confirms the visible images in your source HTML are covered.

Note: ShipSafe reads the initial HTML source. Images injected by JavaScript after the page loads — lazy-loaded images, carousel images, images rendered by a JS framework without SSR — may not appear in the scan. For comprehensive JavaScript-rendered coverage, use Axe DevTools directly in the browser after the page fully loads.

Check my site with ShipSafe →

Related ShipSafe guides:

Frequently asked questions

What is WCAG 1.1.1 and what does it require?

Success Criterion 1.1.1 (Non-text Content) is a Level A requirement in WCAG 2.1 and 2.2. It requires that every non-text element — including images, icons, and image-only buttons — has a text alternative serving the equivalent purpose. For HTML images this means every <img> element must have an alt attribute. For informative images, alt text describes what the image communicates. For decorative images, alt="" tells screen readers to skip the element. For functional images (links or buttons), alt text describes the destination or action.

What is the difference between a missing alt attribute and alt=""?

A missing alt attribute and an empty alt attribute produce completely different screen reader behavior. When the alt attribute is absent, most screen readers announce the image’s file name — often a meaningless hash like hero-2024-final-v3.jpg. An empty alt attribute (alt="") explicitly instructs the screen reader to ignore the element entirely. For decorative images, alt="" is correct. For informative images, both a missing alt and an empty alt are WCAG 1.1.1 failures.

When should I use an empty alt attribute (alt="")?

Use alt="" on purely decorative images that add visual styling but don’t communicate information beyond what the surrounding text already provides: decorative dividers, abstract background textures, stock-photo filler where adjacent text provides all context. The test: would a user who couldn’t see this image miss any information or functionality? If not, the image is decorative and gets alt="".

How do I write good alt text for an informative image?

Describe what the image communicates in context — not just what it looks like. Don’t start with “image of” or “photo of”; screen readers already announce “image” before reading the alt text. Calibrate length to information density: a team headshot might need just name and role; a product screenshot might need 15–25 words. For data charts, supplement with a visible data table below the image. The benchmark: if a sighted user could read only your alt text and understand what the image contributes to the page, the alt text is correct.

Does alt text affect SEO?

Yes, meaningfully. Search engines use alt text to understand image content and index images in Google Image Search — one of the only direct signals available to crawlers for understanding visual content. Well-written alt text for product screenshots, diagrams, and infographics can drive image search traffic. Google’s crawlers function similarly to screen readers: both need text to understand images. The same alt text improvements that reduce ADA lawsuit risk also improve search visibility.

Do SVG images need alt text?

It depends on how the SVG is embedded. An SVG loaded via <img src="..."> requires an alt attribute like any other image. An inline <svg> element should have role="img" and a <title> child element as the text alternative, with aria-labelledby pointing to the title’s id. Decorative inline SVGs — icon glyphs next to text labels — should have aria-hidden="true" and focusable="false".

Does ShipSafe check for missing alt text?

Yes. ShipSafe scans the page’s HTML for <img> elements missing an alt attribute, and for images with placeholder alt values like “image”, “photo”, or a file path string. It flags these as WCAG 1.1.1 violations — the same criterion automated ADA demand-letter scanners check. After adding alt text, run ShipSafe on the same URL to confirm. Note: ShipSafe reads the initial HTML source; images injected by JavaScript after page load may not appear in the scan.

Also in the Copper Bay Labs suite

Accessibility is one layer of pre-launch risk. These free tools cover the rest: