Building Accessible SVG Icons: ARIA Roles, Titles & Screen Readers
Key Architectural Takeaways
- Decorative icons must be hidden from assistive technologies using aria-hidden="true".
- Interactive icons (such as buttons without text) require aria-label or an internal <title> element.
- Add role="img" to SVGs to ensure screen readers recognize vectors as semantic graphics.
- Ensure sufficient color contrast ratios between icon strokes and backgrounds.
Why Icon Accessibility Matters
Icons are shorthand for complex actions: a magnifying glass indicates search, a shopping bag represents checkout, and a gear icon represents settings. However, without proper semantic markup, screen readers and assistive technology will either skip the icon entirely or announce confusing raw file paths and cryptic vector coordinates.
Following WCAG 2.2 guidelines ensures that every user, regardless of visual ability, can navigate and interact with your web application.
Category 1: Decorative Icons (Hide Them)
If an icon is accompanied by visible text that already describes the action, the icon is decorative. In this scenario, assistive technology should ignore the icon to avoid redundant announcements:
<!-- Correct: Icon is hidden because text provides full context -->
<button class="btn">
<svg aria-hidden="true" focusable="false" width="16" height="16">
<use href="#icon-cart"></use>
</svg>
<span>Add to Cart</span>
</button>Notice the inclusion of focusable="false": this prevents older versions of Internet Explorer and certain screen readers from placing a redundant keyboard tab stop on the SVG itself.
Category 2: Standalone Interactive Icons (Label Them)
When an icon button has no visible text (for example, a close button or a heart button), you must provide a clear text label for screen readers:
<!-- Approach A: Using aria-label on the parent interactive element -->
<button aria-label="Close dialog" class="btn-close">
<svg aria-hidden="true" width="20" height="20">
<use href="#icon-close"></use>
</svg>
</button>
<!-- Approach B: Using role="img" and an internal <title> element -->
<svg role="img" aria-labelledby="delete-title" width="20" height="20">
<title id="delete-title">Delete this item</title>
<path d="..."/>
</svg>Color Contrast Guidelines
Under WCAG 2.1 Level AA, non-text contrast (which includes user interface components and graphical objects) must have a contrast ratio of at least **3:1** against adjacent background colors. For active states and interactive controls, a 4.5:1 ratio is strongly recommended.
Try the Corresponding Browser Utility
Automate your vector optimization, sprite bundling, and recoloring with our free online suite.