How to Fix Missing Alt Text: A Practical Guide
Your accessibility scanner flagged one or more images without adequate alternative text. This is consistently the most common accessibility violation on the web — and one of the easiest to fix. This guide covers every alt text scenario you will encounter, with concrete before-and-after code examples.
What the Scanner Found
Axe-core (the engine behind most accessibility scanners including Passiro, Lighthouse, and Deque) checks several rules related to alt text:
- image-alt —
<img>elements must have analtattribute - input-image-alt —
<input type="image">elements must have analtattribute - area-alt —
<area>elements in image maps must have analtattribute - svg-img-alt — SVG elements with
role="img"must have an accessible name - role-img-alt — Elements with
role="img"must have an accessible name
All of these trace back to a single WCAG requirement: Success Criterion 1.1.1 Non-text Content (Level A). This is the most basic conformance level — you cannot claim any level of WCAG compliance without satisfying it.
Why It Matters
When an image lacks alt text, screen readers handle it in one of several unhelpful ways:
- Announce "image" with no further context — the user knows something is there but not what
- Read the filename: "DSC underscore zero zero four seven dot jpeg" or "hero dash banner dash final dash v2 dot png"
- Read the full URL path, which can be dozens of words of meaningless text
- Skip the image entirely, which is correct for decorative images but wrong for informative ones
This affects roughly 8 million screen reader users in the US and EU alone. It also affects users who disabled images for bandwidth reasons, users on broken connections where images fail to load, and search engines indexing your content.
The Decision Tree: Decorative or Informative?
Before writing alt text, ask one question: if I removed this image entirely, would the user miss any information?
- Yes → The image is informative. Write a description in the
altattribute. - No → The image is decorative. Use an empty
alt=""attribute (not a missing alt attribute — those are different).
Common decorative images: background textures, ornamental dividers, icons next to text that already conveys the same meaning, stock photos used purely for visual appeal.
Common informative images: product photos, charts, diagrams, screenshots, logos that serve as links, icons that are the only indicator of meaning.
Fix: <img> Without alt (Missing Attribute)
This is the most common violation. The alt attribute is completely absent.
Before (fails):
<img src="team-photo.jpg">
After (informative image):
<img src="team-photo.jpg" alt="The Passiro team at the 2025 accessibility summit">
After (decorative image):
<img src="decorative-wave.svg" alt="">
Note: alt="" (empty string) tells screen readers to skip the image entirely. This is correct for decorative images. A missing alt attribute is never correct — it forces screen readers to guess.
Fix: Informative Image Incorrectly Marked as Decorative
Sometimes images have alt="" when they actually convey information. Scanners cannot catch this automatically — it requires human judgment.
Before (technically passes the scanner, but wrong):
<img src="warning-icon.svg" alt="">
<span>Your session will expire soon</span>
If the warning icon is the only visual cue that this is an alert (not just informational text), it needs alt text:
After:
<img src="warning-icon.svg" alt="Warning">
<span>Your session will expire soon</span>
However, if the text itself makes the meaning clear and the icon is purely reinforcing it, alt="" is correct.
Fix: <input type="image"> Without alt
Image inputs are used as submit buttons. The alt text serves as the button label.
Before (fails):
<input type="image" src="search-icon.png">
After:
<input type="image" src="search-icon.png" alt="Search">
The alt text should describe the action, not the image. Use "Search" not "magnifying glass icon".
Fix: <area> Without alt in Image Maps
Image maps use <area> elements to define clickable regions. Each area needs alt text describing its destination or function.
Before (fails):
<img src="floor-plan.png" usemap="#offices" alt="Office floor plan">
<map name="offices">
<area shape="rect" coords="0,0,100,100" href="/room-a">
<area shape="rect" coords="100,0,200,100" href="/room-b">
</map>
After:
<img src="floor-plan.png" usemap="#offices" alt="Office floor plan">
<map name="offices">
<area shape="rect" coords="0,0,100,100" href="/room-a" alt="Conference Room A">
<area shape="rect" coords="100,0,200,100" href="/room-b" alt="Conference Room B">
</map>
Fix: SVG Without an Accessible Name
Inline SVGs need explicit accessibility markup. There are two reliable approaches.
Before (fails):
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M12 2L2 7l10 5 10-5-10-5z"/>
<path d="M2 17l10 5 10-5"/>
</svg>
After (approach 1 — role + aria-label):
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
role="img" aria-label="Layers icon">
<path d="M12 2L2 7l10 5 10-5-10-5z"/>
<path d="M2 17l10 5 10-5"/>
</svg>
After (approach 2 — title element with aria-labelledby):
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
role="img" aria-labelledby="layers-title">
<title id="layers-title">Layers icon</title>
<path d="M12 2L2 7l10 5 10-5-10-5z"/>
<path d="M2 17l10 5 10-5"/>
</svg>
For decorative SVGs, hide them from the accessibility tree entirely:
<svg aria-hidden="true" focusable="false" viewBox="0 0 24 24">
<!-- ... -->
</svg>
The focusable="false" attribute prevents Internet Explorer and older Edge from adding the SVG to the tab order.
Fix: CSS Background Images That Convey Information
If a CSS background image conveys meaningful content, there is no alt attribute to set. Use visually hidden text instead.
Before (inaccessible — information only in background image):
<div class="certification-badge" style="background-image: url('iso-certified.png')">
</div>
After:
<div class="certification-badge" style="background-image: url('iso-certified.png')">
<span class="sr-only">ISO 27001 Certified</span>
</div>
The sr-only class (screen reader only) hides the text visually while keeping it accessible. Here is a reliable implementation:
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
Fix: figure and figcaption Patterns
When using <figure> with <figcaption>, the image still needs an alt attribute. The figcaption provides a visible caption; the alt provides the screen reader description.
Before (fails):
<figure>
<img src="chart-q4.png">
<figcaption>Q4 2025 revenue by region</figcaption>
</figure>
After (option 1 — alt repeats or extends the caption):
<figure>
<img src="chart-q4.png" alt="Bar chart showing Q4 2025 revenue: North America 45%, Europe 32%, Asia 18%, Other 5%">
<figcaption>Q4 2025 revenue by region</figcaption>
</figure>
After (option 2 — alt defers to caption via aria-describedby):
<figure>
<img src="chart-q4.png" alt="Bar chart of Q4 revenue" aria-describedby="chart-desc">
<figcaption id="chart-desc">Q4 2025 revenue by region: North America 45%, Europe 32%, Asia 18%, Other 5%</figcaption>
</figure>
Fix: Icons (Font Icons and SVG Icons)
Icons fall into two categories: decorative (next to text that already conveys the meaning) and meaningful (the sole indicator of an action or status).
Decorative icon next to text — hide it:
<!-- Before (redundant announcement) -->
<button>
<svg viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>
Add item
</button>
<!-- After (icon hidden from screen readers) -->
<button>
<svg aria-hidden="true" focusable="false" viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>
Add item
</button>
Meaningful icon with no visible text — label it:
<!-- Before (no accessible name) -->
<button>
<svg viewBox="0 0 24 24"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25z"/></svg>
</button>
<!-- After (aria-label on the button) -->
<button aria-label="Edit">
<svg aria-hidden="true" focusable="false" viewBox="0 0 24 24"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25z"/></svg>
</button>
Place the aria-label on the interactive element (the button), not on the SVG. The SVG gets aria-hidden="true" because the button's label carries the meaning.
Font icons (Font Awesome, Material Icons, etc.):
<!-- Before -->
<button>
<i class="fa fa-trash"></i>
</button>
<!-- After -->
<button aria-label="Delete">
<i class="fa fa-trash" aria-hidden="true"></i>
</button>
Writing Good Alt Text
Bad alt text can be worse than no alt text — it wastes the user's time with useless information. Follow these guidelines:
- Be concise. Aim for one sentence or less. Screen reader users cannot skim alt text the way sighted users skim images.
- Do not start with "image of" or "picture of." Screen readers already announce the element as an image. Writing "Image of a sunset" results in the announcement "image, Image of a sunset."
- Describe the content, not the appearance — unless appearance is the point. "Company logo" is usually better than "Blue circle with white letter P inside."
- Consider context. The same photo might need different alt text on different pages. A headshot on an About page: "Jane Smith, CTO." The same headshot on a blog post by Jane: alt can be empty because her name is already in the byline.
- Include text that appears in the image. If an image contains visible text (a sign, a chart label, a meme), include that text in the alt attribute.
- Do not describe what is not there. Stick to what the image actually shows.
Alt Text for Different Image Types
Product photos: Describe what a buyer needs to know. Not "shoe" but "Nike Air Max 90 in white and gray, side view." Include color, size, angle, and distinguishing features if they matter for the purchase decision.
Charts and graphs: State the type of chart, its subject, and the key takeaway. For simple charts, the alt text may suffice. For complex data visualizations, use a data table as an alternative or link to one with aria-describedby.
<img src="monthly-users.png"
alt="Line chart showing monthly active users growing from 12,000 in January to 34,000 in December 2025">
Logos: If a logo is a link (e.g., in a header), the alt text should describe the destination, not the visual design.
<!-- Logo as home link -->
<a href="/">
<img src="logo.svg" alt="Passiro — home">
</a>
<!-- Standalone logo (not a link) -->
<img src="partner-logo.png" alt="Acme Corp logo">
Buttons and linked images: When an image is inside a link or button and there is no other text, the alt text must describe the action or destination — not the image itself.
<!-- Before -->
<a href="/cart">
<img src="cart.svg" alt="shopping cart icon">
</a>
<!-- After -->
<a href="/cart">
<img src="cart.svg" alt="View shopping cart (3 items)">
</a>
Complex images (infographics, diagrams, flowcharts): Alt text alone is insufficient for complex images. Provide a brief alt text summary and a longer description using one of these methods:
<!-- Method 1: Link to a text alternative -->
<img src="architecture-diagram.png" alt="System architecture diagram (described below)">
<div id="arch-desc">
<p>The system consists of three tiers: ...</p>
</div>
<!-- Method 2: aria-describedby -->
<img src="architecture-diagram.png"
alt="System architecture diagram"
aria-describedby="arch-long-desc">
<p id="arch-long-desc">The system consists of three tiers: ...</p>
<!-- Method 3: details/summary for expandable description -->
<figure>
<img src="architecture-diagram.png" alt="System architecture diagram">
<details>
<summary>Full description of the architecture diagram</summary>
<p>The system consists of three tiers: ...</p>
</details>
</figure>
CMS-Specific Fixes
WordPress: Open the Media Library, click the image, and fill in the "Alt Text" field on the right side. For images already inserted in posts, click the image in the editor, then click the pencil icon (Edit) and add alt text. In the block editor (Gutenberg), select the image block and enter alt text in the "Alt text (alternative text)" field in the block settings panel on the right.
Shopify: Go to Products, click the product, click the image, and enter alt text in the "Add alt text" field. For theme images (banners, feature images), open the theme customizer, click the image section, and find the alt text or "Image alt" field. For images inserted via the rich text editor, click the image and select "Edit alt text."
Squarespace: Click any image block, then click the pencil icon (Edit). In the image editor, open the Design tab and find the "Image alt text" field (labeled "Filename" in older versions — this is misleading but it is the alt text field). For gallery images, click each image individually and add a description.
Wix: Click the image, click "Settings" (or the gear icon), and add alt text in the "What's in the image?" field. Wix calls it "Image alt text" in accessibility settings.
Testing Your Fix
After adding alt text, verify it works correctly with these methods:
Browser DevTools (quickest):
- Right-click the image and select "Inspect" (or press F12)
- In the Elements panel, look for the
altattribute on the<img>tag - In Chrome, open the Accessibility tab in the right panel — it shows the computed accessible name
- In Firefox, the Accessibility Inspector (F12 → Accessibility tab) displays the accessible name and role for every element
Run your scanner again:
- In Passiro, rescan the page and confirm the image-alt violations are resolved
- For a quick local check, open Chrome DevTools, go to the Lighthouse tab, run an accessibility audit, and look for "Image elements do not have [alt] attributes"
- Install the axe DevTools browser extension for detailed per-element results
Screen reader testing (most reliable):
- macOS: Press Cmd+F5 to activate VoiceOver. Navigate to the image with VO+Right Arrow (Ctrl+Option+Right). Listen to what is announced. Press Cmd+F5 again to deactivate.
- Windows: Press Win+Ctrl+Enter to start Narrator (built-in) or download NVDA (free). Navigate with Tab or arrow keys and listen for image announcements.
- Mobile: On iOS, triple-click the side button for VoiceOver. On Android, open Settings → Accessibility → TalkBack.
What to listen for: The screen reader should announce the image role ("image" or "graphic") followed by your alt text. If it announces a filename or URL, the alt text is missing. If it announces nothing at all and the image is informative, your empty alt is incorrect. If it announces something unhelpful like "image" with no further description, the alt attribute is present but empty when it should not be.
Common Mistakes to Avoid
- Using the filename as alt text: "IMG_4872.jpg" or "hero-banner-final-v3.png" is not useful to anyone.
- Keyword stuffing: "Buy cheap shoes online best shoe store discount shoes free shipping" is spam, not alt text. Search engines penalize this and screen reader users will leave your site.
- Identical alt text on every image: If ten product images all say "product image," the user cannot distinguish between them.
- Extremely long alt text: If your alt text exceeds roughly 125 characters, consider whether the image is complex enough to need a long description via
aria-describedbyinstead. - Using title instead of alt: The
titleattribute creates a tooltip on hover — it is not a substitute foralt. Most screen readers ignoretitlewhenaltis present, and keyboard-only users never see tooltips.
Il-website tiegħek hija aċċessibbli?
Skannja l-website tiegħek b'xejn u ikseb il-punteggio WCAG tiegħek fi ftit minuti.
Skannja s-sit tiegħek b'xejn