How to Make Icon-Only Buttons Accessible with ARIA
Icon-only buttons are a staple of modern user interface design, offering clean visual aesthetics and saving screen real estate, but they often present significant barriers for users relying on assistive technologies. Without a text node inside the element, screen readers cannot determine the purpose of the control. This guide outlines the core techniques to make icon-only buttons accessible using ARIA labels, semantic markup, and best practices to meet Web Content Accessibility Guidelines (WCAG).
The Core Accessibility Problem
When a screen reader encounters an HTML <button>
element containing only an <img>,
<svg>, or icon font, it attempts to read the
accessible name of the button. If that icon lacks textual context, the
screen reader may announce nothing, announce only the word "button," or
read aloud internal SVG path data or image filenames. Every interactive
control must have an accessible name that conveys its purpose.
Method 1: Using the
aria-label Attribute
The most direct way to provide an accessible name for an icon-only
button is the aria-label attribute. Placed directly on the
<button> element, it overrides any child elements to
provide a clear, invisible text label for assistive devices.
<button type="button" aria-label="Close modal">
<svg aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 24 24">
<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>
</svg>
</button>Key Considerations:
- Hide the icon: Always add
aria-hidden="true"to the inner SVG or icon element so screen readers ignore the graphic itself. - Remove focusability: On SVGs, include
focusable="false"to prevent older browsers (like Internet Explorer) from adding redundant tab stops.
Method 2: Using Visually Hidden Text
An alternative to aria-label is including real HTML text
wrapped in a CSS class that hides the text visually while leaving it
accessible to the DOM tree and screen readers (often named
.sr-only or .visually-hidden).
<button type="button">
<svg aria-hidden="true" focusable="false" width="16" height="16">
<!-- Icon path -->
</svg>
<span class="sr-only">Search catalog</span>
</button>.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;
}This method is often preferred in internationalized applications
because standard in-page translation tools (such as Google Translate)
handle visible DOM text nodes more reliably than attributes like
aria-label.
Method 3: Using
aria-labelledby
When visible text that describes the button’s action already exists
elsewhere on the page, you can use aria-labelledby to
associate the button with that text's unique ID.
<h2 id="settings-heading">Account Settings</h2>
<button type="button" aria-labelledby="settings-heading">
<svg aria-hidden="true" focusable="false"><!-- Gear Icon --></svg>
</button>In this scenario, a screen reader will read the button as "Account Settings, button."
Best Practices for Icon-Only Button Labels
- Label actions, not visuals: Never describe the icon itself. Use action-oriented labels like "Delete item" instead of "Trash can," or "Close dialog" instead of "X mark."
- Keep labels concise: Avoid redundant words like "button" or "click here." Screen readers automatically identify the role of the element.
- Handle toggle states dynamically: For buttons that
change state (e.g., mute/unmute, play/pause, bookmark/unbookmark),
ensure the
aria-labeloraria-pressedattribute updates dynamically via JavaScript as the state changes. - Include visible tooltips: Users without screen readers, including those with cognitive disabilities, may also struggle to decipher unfamiliar icons. Pair icon-only buttons with hover and focus tooltips that match the accessible label.