Accessible SVG Icons: aria-label and role
Simple rules to make SVG icons accessible in buttons, links, and status UI. Includes practical code patterns you can copy.
Most SVG icon accessibility bugs are easy to fix once you separate decorative icons from meaningful icons.
Quick rules
- Decorative icon: add
aria-hidden="true"and no label. - Icon-only button: keep icon hidden and label the button.
- Meaningful standalone icon: add accessible name with
aria-label. - Do not rely on color/icon shape alone for critical meaning.1
Decorative icons
<p>
<svg aria-hidden="true" viewBox="0 0 24 24" width="16" height="16">...</svg>
Settings
</p>
Icon-only buttons
<button type="button" aria-label="Search">
<svg aria-hidden="true" viewBox="0 0 24 24" width="20" height="20">...</svg>
</button>
Label the control, not the icon. Screen readers should announce the action, not the graphic.
Standalone meaningful icons
<svg
role="img"
aria-label="Success"
viewBox="0 0 24 24"
width="20"
height="20"
>
<path d="..." />
</svg>
React pattern
type IconProps = {
title?: string;
decorative?: boolean;
};
export function StatusIcon({ title = 'Status', decorative = false }: IconProps) {
if (decorative) {
return <svg aria-hidden="true" viewBox="0 0 24 24">{/* ... */}</svg>;
}
return (
<svg role="img" aria-label={title} viewBox="0 0 24 24">
{/* ... */}
</svg>
);
}
Test checklist
- Tab to every icon button and check announced label.
- Run Lighthouse or Axe and clear name/role warnings.
- Verify success/error states include text, not icon-only feedback.2
Icons to test
Related guides
- How to Use SVG Icons: A Practical Guide for Modern Web Apps
- How to Animate SVG Icons Without Making UI Feel Janky
Accessibility test routine
For release-level quality, pair manual checks with automated scans:
- Keyboard navigate icon-only controls.
- Use a screen reader to confirm announced labels.
- Run Axe/Lighthouse and fix ARIA naming issues.
- Verify status icons are not the only feedback channel.
Team defaults
- decorative icons are hidden from assistive tech
- icon-only controls always have explicit
aria-label - critical states always include visible text
These defaults remove most icon-related accessibility bugs.
Accessibility pitfalls in real products
Even teams with good ARIA habits miss edge cases:
- icon buttons inside composite controls with duplicated labels
- status-only icons inside toasts without readable text
- hidden labels that do not update when state changes
Reviewing these patterns during component QA improves real assistive-tech outcomes more than one-time lint cleanup.
Final note
Accessible icon patterns are simple when treated as defaults in components. Bake them into shared UI primitives, not one-off pages.
Document these accessibility defaults in your component library so every new feature inherits them automatically.
The goal is repeatable clarity, not one-time compliance checks.
Additional source references: 3.