Accessible Images and Icons — Complete Guide
In this tutorial, you will learn about Accessible Images and Icons. We cover key concepts, practical examples, and best practices to help you master this topic.
Accessible images and icons require proper alt text strategies for different image types, SVG Accessibility patterns, icon font considerations, and responsive image techniques that serve all users regardless of device or ability.
What You'll Learn
- Alt text strategies for different image contexts
- Making SVGs accessible with role and aria-label
- Icon font accessibility issues and alternatives
- Responsive images with srcset and picture
- CSS images and when to use img versus background-image
Why It Matters
- Images and icons are everywhere on the web
- Inaccessible images exclude blind and low-vision users
- Icons without text labels are meaningless to screen reader users
- Responsive images ensure usability across devices
Real-World Use
- A weather app uses accessible weather icons with descriptions
- A dashboard uses accessible SVG charts with fallback text
- An e-commerce site uses responsive product images
- A navigation uses icon + text label patterns
flowchart LR
A[Visual Element] --> B{Type}
B --> C[Informative Image]
B --> D[Decorative Image]
B --> E[Icon]
B --> F[SVG Graphic]
C --> G[Alt Text]
D --> H[Null Alt]
E --> I[Text Label]
F --> J[role + aria-label]
Image Accessibility Patterns
Beyond basic alt text, images need consideration for context, responsiveness, and the medium through which they are delivered.
Context Matters for Alt Text
The same image needs different alt text in different contexts:
Context: E-commerce product page
alt="Handcrafted blue ceramic vase with white floral pattern, 12 inches tall, $45"
Context: Blog post about home decoration trends
alt="Blue ceramic vase with floral pattern on a pine wood table, surrounded by natural sunlight"
Context: Social media share
alt="Products: Handcrafted Blue Ceramic Vase"
SVG Accessibility
SVGs are inline graphics that can contain text. Unlike img elements, SVGs do not have implicit alt text. You must make them accessible explicitly.
Code Example: Accessible SVGs
<!-- Decorative SVG: hidden -->
<svg aria-hidden="true" focusable="false" width="24" height="24">
<path d="M12 2L2 7l10 5 10-5-10-5z"/>
</svg>
<!-- Informative SVG with title -->
<svg role="img" aria-labelledby="warning-title" focusable="false" width="24" height="24">
<title id="warning-title">Warning: Low battery</title>
<path d="M12 2L1 21h22L12 2zm-1 7h2v6h-2V9zm0 8h2v2h-2v-2z" fill="#C62828"/>
</svg>
<!-- Linked SVG with visible text -->
<a href="/dashboard" class="nav-link">
<svg aria-hidden="true" focusable="false" width="20" height="20">
<rect x="2" y="2" width="8" height="8" rx="1" fill="currentColor"/>
<rect x="12" y="2" width="8" height="8" rx="1" fill="currentColor"/>
<rect x="2" y="12" width="8" height="8" rx="1" fill="currentColor"/>
<rect x="12" y="12" width="8" height="8" rx="1" fill="currentColor"/>
</svg>
Dashboard
</a>
Expected output: Decorative SVGs are skipped by screen readers. Informative SVGs announce their title. Linked SVGs with visible text inherit the link's accessible name.
Code Example: Icon Fonts vs Inline SVGs
<!-- Icon font (problematic for accessibility) -->
<span class="icon icon-search" aria-hidden="true"></span>
<span class="icon-label">Search</span>
<!-- Inline SVG (more accessible) -->
<button aria-label="Search">
<svg aria-hidden="true" focusable="false" width="20" height="20">
<circle cx="8" cy="8" r="6" fill="none" stroke="currentColor" stroke-width="2"/>
<line x1="12" y1="12" x2="18" y2="18" stroke="currentColor" stroke-width="2"/>
</svg>
</button>
<!-- Icon + text pattern (most accessible) -->
<button>
<svg aria-hidden="true" focusable="false" width="20" height="20">
<path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/>
</svg>
Search
</button>
Expected output: Icon fonts use CSS-generated content that may not be accessible to all screen readers. Inline SVGs with aria-hidden and adjacent text labels provide reliable accessibility. The icon + text pattern works for all users.
Code Example: Responsive Images
<!-- srcset for different screen sizes -->
<img src="photo-800.jpg"
srcset="photo-400.jpg 400w,
photo-800.jpg 800w,
photo-1200.jpg 1200w"
sizes="(max-width: 600px) 100vw,
(max-width: 1024px) 50vw,
33vw"
alt="Mountain landscape at sunrise with snow-capped peaks">
<!-- picture element for art direction -->
<picture>
<source media="(max-width: 600px)" srcset="photo-mobile.jpg">
<source media="(max-width: 1024px)" srcset="photo-tablet.jpg">
<img src="photo-desktop.jpg"
alt="Team photo at the 2025 company retreat">
</picture>
<!-- High DPI display support -->
<img src="photo-1x.jpg"
srcset="photo-1x.jpg 1x, photo-2x.jpg 2x, photo-3x.jpg 3x"
alt="Product detail: handcrafted ceramic mug">
Expected output: The browser selects the appropriate image based on viewport size and device pixel ratio. All variants share the same alt text because the content is the same, just at different resolutions or crops.
Common Mistakes
- Icon-only buttons without accessible names — An icon button without aria-label or visible text is completely inaccessible. Screen readers may announce "button" with no context.
- Using CSS background-image for informative images — Background images are not in the accessibility tree. Informative images must be img elements with alt text.
- Missing focusable="false" on decorative SVGs — SVGs can receive focus in some browsers. Add focusable="false" and aria-hidden="true" for decorative SVGs.
- Icon fonts without aria-hidden — Icon fonts loaded via pseudo-elements can be announced by some screen readers. Always add aria-hidden="true" to icon font elements.
- Same alt text for different images — Every alt text must be unique and specific. "Product image" on 20 product pages provides no distinction.
- Not providing fallback for SVG — While rare, SVG failures happen. Consider adding a text fallback or using img with a PNG fallback inside a picture element.
- Spacer images — Using transparent GIFs for spacing is outdated. Use CSS margin and padding instead, and never include spacer images.
Practice Questions
- How do you make an inline SVG accessible? Add role="img" for informative SVGs, include a
element or aria-label for the description, and add aria-hidden="true" for decorative SVGs. - Why should icon fonts be avoided or handled carefully for accessibility? Icon fonts use CSS-generated content that may not be in the accessibility tree consistently across browsers and screen readers.
- What is the difference between srcset and the picture element? srcset provides different resolutions of the same image. picture provides different crops or aspect ratios (art direction) for different viewports.
- How should you handle a linked icon with text? The link text provides the accessible name. The icon inside the link should have aria-hidden="true" so the screen reader does not announce it separately.
- Challenge: Create an accessible weather widget that displays current conditions (temperature, humidity, wind) with icons. Use inline SVGs with proper aria attributes, text labels, and a fallback text description. Ensure the entire widget is keyboard navigable and screen reader accessible.
FAQ
{{< faq "Are icon fonts accessible?" "Icon fonts are not inherently accessible. They use CSS pseudo-elements which may not be exposed to the accessibility tree. If using icon fonts, add aria-hidden="true" to all icon elements and provide visible text labels." >}}
{{< faq "Should I use img or background-image for decorative images?" "Use background-image in CSS for truly decorative images (they are not in the accessibility tree). Use img with alt=\"\" for decorative images in the HTML that are part of content flow." >}} {{< faq "How do screen readers handle SVGs?" "Screen readers handle SVGs differently. Some read the SVG as an image, some access the text content inside. Use role=\"img\" to ensure consistent treatment and provide an accessible name." >}} {{< faq "What is the best practice for a logo image?" "The logo should be an img element. If it is a link to the homepage, provide alt=\"Home\" or alt=\"Company Name Home\". If it is not a link, provide alt=\"Company Name\" as the site title." >}}Mini Project
Build an accessible icon system for a dashboard application. Create 6 icons (dashboard, users, settings, analytics, notifications, logout) using inline SVGs. Each icon must: have aria-hidden="true" when paired with visible text, use role="img" with a
What's Next
Continue with Lesson 17: Accessible Navigation and Menus to learn how to build navigation systems that work for all users.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro