View contents
Alt Text Implementation Guide: Complete Technical Reference
Introduction
This comprehensive guide covers the technical implementation of alt text across all image types and contexts. From simple decorative images to complex infographics, you’ll learn the specific techniques required for WCAG compliance and optimal accessibility.
Image Categories and Techniques
The WAI Images Decision Tree
┌─────────────────────────────────────────────────────────┐
│ WAI IMAGE ACCESSIBILITY DECISION │
├─────────────────────────────────────────────────────────┤
│ │
│ 1. Does the image contain text? │
│ └─ YES → Include text in alt │
│ │
│ 2. Is the image used in a link or button? │
│ └─ YES → Describe function/destination │
│ │
│ 3. Does the image contribute meaning to context? │
│ └─ YES → Describe informational content │
│ │
│ 4. Is the image purely decorative? │
│ └─ YES → Use null alt (alt="") │
│ │
│ 5. Is the image complex (charts, diagrams)? │
│ └─ YES → Provide long description │
│ │
└─────────────────────────────────────────────────────────┘
Implementation by Image Type
1. Informative Images
Images that convey information or concepts:
<!-- Simple informative image -->
<img
src="warning-icon.png"
alt="Warning: This action cannot be undone"
>
<!-- Photo with context -->
<img
src="office-building.jpg"
alt="Modern glass office building with company logo at entrance"
>
<!-- Data visualization -->
<img
src="trend.png"
alt="Upward trending arrow indicating growth"
>
2. Decorative Images
Images that add no information content:
<!-- Method 1: Empty alt attribute (preferred) -->
<img src="decorative-border.png" alt="">
<!-- Method 2: CSS background (truly decorative) -->
<style>
.hero {
background-image: url('abstract-pattern.png');
}
</style>
<!-- Method 3: Role presentation (ARIA) -->
<img src="flourish.svg" alt="" role="presentation">
When is an image decorative?
- Background patterns and textures
- Spacer or design elements
- Icons next to text that says the same thing
- Mood/atmosphere images that don’t add information
3. Functional Images
Images used as links, buttons, or controls:
<!-- Linked logo -->
<a href="/">
<img src="logo.png" alt="Company Name - Go to homepage">
</a>
<!-- Image button -->
<button type="submit">
<img src="search-icon.svg" alt="Search">
</button>
<!-- Image link -->
<a href="/cart">
<img src="cart-icon.svg" alt="Shopping cart (3 items)">
</a>
<!-- Print button -->
<button onclick="window.print()">
<img src="print.svg" alt="Print this page">
</button>
4. Images of Text
Images containing readable text:
<!-- Logo with text -->
<img src="logo.png" alt="Acme Corporation">
<!-- Banner with message -->
<img
src="sale-banner.jpg"
alt="Summer Sale: 50% off all items through August 31"
>
<!-- Stylized heading -->
<img
src="welcome-text.png"
alt="Welcome to Our Store"
>
Best Practice: Use actual text with CSS styling instead of images of text when possible.
5. Complex Images
Charts, diagrams, graphs, and infographics:
<!-- Method 1: Brief alt + longdesc attribute -->
<img
src="org-chart.png"
alt="Organization chart showing company structure"
longdesc="org-chart-description.html"
>
<!-- Method 2: Brief alt + adjacent text description -->
<figure>
<img
src="sales-chart.png"
alt="Quarterly sales chart - details in table below"
>
<figcaption>
<details>
<summary>Sales data description</summary>
<p>Q1: $1.2M, Q2: $1.5M, Q3: $1.8M, Q4: $2.1M.
Total growth of 75% year-over-year.</p>
</details>
</figcaption>
</figure>
<!-- Method 3: aria-describedby -->
<img
src="process-flow.png"
alt="5-step checkout process"
aria-describedby="process-description"
>
<div id="process-description" class="sr-only">
Step 1: Add items to cart.
Step 2: Enter shipping address.
Step 3: Select shipping method.
Step 4: Enter payment information.
Step 5: Review and confirm order.
</div>
6. Groups of Images
Multiple images conveying a single piece of information:
<!-- Star rating -->
<div role="img" aria-label="Rating: 4 out of 5 stars">
<img src="star-filled.svg" alt="">
<img src="star-filled.svg" alt="">
<img src="star-filled.svg" alt="">
<img src="star-filled.svg" alt="">
<img src="star-empty.svg" alt="">
</div>
<!-- Image collection -->
<figure role="group" aria-label="Product views">
<img src="front.jpg" alt="Blue dress - front view">
<img src="back.jpg" alt="Blue dress - back view">
<img src="detail.jpg" alt="Blue dress - fabric detail">
</figure>
7. Image Maps
Clickable regions within an image:
<img
src="office-floor-plan.png"
alt="Office floor plan with clickable departments"
usemap="#floor-map"
>
<map name="floor-map">
<area
shape="rect"
coords="0,0,100,100"
href="/sales"
alt="Sales Department"
>
<area
shape="rect"
coords="100,0,200,100"
href="/engineering"
alt="Engineering Department"
>
<area
shape="rect"
coords="200,0,300,100"
href="/hr"
alt="Human Resources"
>
</map>
Framework-Specific Implementation
React/Next.js
// Standard image with alt
function ProductImage({ product }) {
return (
<img
src={product.imageUrl}
alt={`${product.name} - ${product.color} ${product.category}`}
/>
);
}
// Next.js Image component
import Image from 'next/image';
function HeroImage() {
return (
<Image
src="/hero.jpg"
alt="Team collaborating on a design project"
width={1200}
height={600}
priority
/>
);
}
// Decorative image in React
function DecorativeDivider() {
return (
<img
src="/divider.svg"
alt=""
role="presentation"
aria-hidden="true"
/>
);
}
Vue.js
<template>
<!-- Informative image -->
<img
:src="product.image"
:alt="`${product.name} - ${product.description}`"
/>
<!-- Decorative image -->
<img
src="/decorative.svg"
alt=""
aria-hidden="true"
/>
<!-- Complex image with description -->
<figure>
<img
:src="chart.src"
:alt="chart.briefDescription"
:aria-describedby="`chart-desc-${chart.id}`"
/>
<figcaption :id="`chart-desc-${chart.id}`">
{{ chart.longDescription }}
</figcaption>
</figure>
</template>
SVG Accessibility
<!-- Decorative SVG -->
<svg aria-hidden="true" focusable="false">
<!-- ... -->
</svg>
<!-- Informative SVG -->
<svg role="img" aria-labelledby="svg-title svg-desc">
<title id="svg-title">User Statistics</title>
<desc id="svg-desc">Bar chart showing user growth over 12 months</desc>
<!-- ... -->
</svg>
<!-- Interactive SVG -->
<svg role="img" aria-label="Navigation menu">
<!-- ... -->
</svg>
Testing Alt Text
Automated Testing
// Cypress with axe-core
describe('Image Accessibility', () => {
it('should have proper alt text on all images', () => {
cy.visit('/');
cy.injectAxe();
cy.checkA11y(null, {
rules: {
'image-alt': { enabled: true },
'input-image-alt': { enabled: true },
'area-alt': { enabled: true }
}
});
});
});
// Jest with jest-axe
import { axe, toHaveNoViolations } from 'jest-axe';
expect.extend(toHaveNoViolations);
test('images have alt text', async () => {
const html = render(<ProductPage />);
const results = await axe(html.container);
expect(results).toHaveNoViolations();
});
Manual Testing Checklist
## Alt Text Audit Checklist
### For Each Image:
- [ ] Has alt attribute (never missing)
- [ ] Alt text describes purpose, not appearance
- [ ] Alt is concise (under 125 characters when possible)
- [ ] Decorative images use alt=""
- [ ] Linked images describe destination
- [ ] Complex images have long descriptions
### Page-Level Checks:
- [ ] Disable images - is content understandable?
- [ ] Screen reader test - do images make sense?
- [ ] No duplicate alt text on different images
- [ ] No images of text (use real text instead)
Screen Reader Testing Commands
VoiceOver (macOS):
- VO + Command + I → List all images on page
- VO + Right Arrow → Navigate to next element
NVDA (Windows):
- G → Jump to next graphic
- Shift + G → Jump to previous graphic
- NVDA + F7 → Elements list (select Images)
JAWS (Windows):
- G → Jump to next graphic
- Shift + G → Jump to previous graphic
- Insert + F7 → Graphics list
CMS and Platform Considerations
WordPress
// Force alt text requirement
add_filter('attachment_fields_to_edit', function($fields, $post) {
$fields['alt_text_required'] = array(
'label' => 'Alt Text (Required)',
'input' => 'text',
'value' => get_post_meta($post->ID, '_wp_attachment_image_alt', true),
'helps' => 'Describe this image for accessibility'
);
return $fields;
}, 10, 2);
Shopify
{% comment %} Product image with dynamic alt {% endcomment %}
<img
src="{{ product.featured_image | img_url: 'large' }}"
alt="{{ product.featured_image.alt | default: product.title }}"
loading="lazy"
>
Common Patterns
E-commerce Product Images
<!-- Main product image -->
<img
src="product-main.jpg"
alt="Blue denim jacket, front view, sizes XS-XXL"
>
<!-- Thumbnail gallery -->
<div role="group" aria-label="Product image gallery">
<button aria-pressed="true">
<img src="thumb-1.jpg" alt="Front view">
</button>
<button aria-pressed="false">
<img src="thumb-2.jpg" alt="Back view">
</button>
<button aria-pressed="false">
<img src="thumb-3.jpg" alt="Side view showing pockets">
</button>
</div>
User Avatars
<!-- With user name -->
<img
src="avatar.jpg"
alt=""
aria-hidden="true"
>
<span>John Smith</span>
<!-- Standalone avatar -->
<img
src="avatar.jpg"
alt="John Smith's profile photo"
>
Icons with Text
<!-- Icon + visible text (icon is decorative) -->
<button>
<img src="save-icon.svg" alt="" aria-hidden="true">
<span>Save Document</span>
</button>
<!-- Icon only (icon is functional) -->
<button aria-label="Save document">
<img src="save-icon.svg" alt="">
</button>
Quality Guidelines
Alt Text Length
| Context | Recommended Length | Example |
|---|---|---|
| Simple image | 10-50 characters | “Red warning icon” |
| Product photo | 50-100 characters | “Blue wireless headphones with noise cancellation” |
| Complex chart | Brief alt + longer description | “Sales chart - see table below for data” |
| Decorative | 0 characters | alt=“” |
Writing Quality Alt Text
Good Examples:
<img alt="Graph showing 150% revenue increase from January to December 2024">
<img alt="Dr. Sarah Chen presenting at the annual tech conference">
<img alt="Step 3: Click the blue Submit button in the top right corner">
Bad Examples:
<img alt="graph"> <!-- Too vague -->
<img alt="image"> <!-- Meaningless -->
<img alt="photo of person"> <!-- Who? Doing what? -->
<img alt="IMG_2847.jpg"> <!-- Filename, not description -->
Related Articles
- Alt Text Explained - Introduction to alt text
- WCAG Compliance Hub - Full accessibility guide
- ARIA Labels Guide - Advanced labeling techniques
References
- W3C - WCAG 2.2 SC 1.1.1 Non-text Content
- W3C - WAI Images Tutorial
- W3C - ARIA Images Pattern
- WebAIM - Alternative Text
- Deque - Image Accessibility