Optimizing screenreader accessibility for icon-only buttons
Aron Schüler
Published
Updated on
Buttons consisting only of an icon are a common design pattern throughout most websites. But what if the user is depending on a screenreader? You cannot change the design by just adding a text but having no text at all denies any accessibility. Well, there is a simple fix!
Using a <span>
next to your icon
The solution is really simple: We insert a text anyway, describing what the button does, but hide it so that it does not conflict with the design.
So, instead of writing a button with a svg like this (svg taken from Material Design Icons):
<button>
<svg style="width:24px;height:24px" viewBox="0 0 24 24">
<path
fill="currentColor"
d="M17,13H13V17H11V13H7V11H11V7H13V11H17M19,3H5C3.89,3 3,3.89 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3Z"
/>
</svg>
</button>
We add a span and style it with the class sr-only
(which is already defined if you use tailwind and does the same!):
<button>
<svg style="width:24px;height:24px" viewBox="0 0 24 24">
<path
fill="currentColor"
d="M17,13H13V17H11V13H7V11H11V7H13V11H17M19,3H5C3.89,3 3,3.89 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3Z"
/>
</svg>
<span class="sr-only"> Add a new item </span>
</button>
and style the sr-only
class like this:
span.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
}
Adding title
and aria-labeledby
to increase accessibility
Another additional way of increasing the accessibility would be to add the title
and aria-labeledby
attributes to the button
. These also provide a tooltip on hover, so users that don’t understand the direct purpose of your icon-only button can actually understand what the intention was.
To do so, I extended the button from above like this:
<button aria-labelledby="add-button-text" title="Add a new device">
<svg style="width: 24px; height: 24px;" viewBox="0 0 24 24">
<path
fill="currentColor"
d="M17,13H13V17H11V13H7V11H11V7H13V11H17M19,3H5C3.89,3 3,3.89 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3Z"
/>
</svg>
<span id="add-buton-text" class="sr-only">Add a new device</span>
</button>
Done!
Now, we can be sure that no one has problems accessing our still stylish buttons.
A complete example would look like this:
{{< codesandbox broken-night-k7erhz >}}