A common problem I see on the Web these days is the inaccessible Icon button, so today we're going to learn how to create more accessible buttons using HTML and CSS. I've got three buttons on the screen. If I use the keyboard to try and reach them, I can get to the first two but the third one I skip right on by.
Let's fire up VoiceOver, the screen reader for Mac, to see what happens there.
VoiceOver on Chrome. Help button. Main two items button. Leaving HTML content. VoiceOver off.
The screen reader counted two buttons, and it couldn't reach the third one, so clearly something is going on there to make it inaccessible. If we open up this demo page, we'll see we have two button elements and a div with a class of button.
There are so many different ways to code an HTML button that I've seen all of these in the wild. The regular button element with text in it is accessible because it's reachable from a keyboard, and a screen reader, and it has text in it, so the first one's fine.
The second element is a button. It's reachable, but its contents are an i element with some CSS representing an Icon. There's no text in there for a screen reader to know what this element is for. The third button is a div with some SVG in it, so it's not reachable from the keyboard. It doesn't have a role of button, so clearly, that one's not going to work.
How can we fix these up? Well, the first button, I'll show you a technique that I use sometimes, which is to add a visually hidden class. If I add a span element and give it a class of visually hidden, and then put the text in it, in my CSS I can paste the visually hidden class from HTML5 boilerplate that essentially makes texts render to a screen reader, but it's visually hidden from view.
The next step is we need to put an ARIA hidden attribute on the i element representing the Icon and give it a true value because this element is purely decorative. It doesn't really make sense for a screen reader. We're providing text instead. Our second button is good to go.
We need to work on this third button that's created out of a div. The first thing that we need to do, if there's some reason why we can't change it to a native button, we can still make it work.
We can add a role of button to tell a screen reader what this element is actually for, and then we can add a tab index value of zero. That means that it will be reachable from a keyboard and a screen reader, but it will be kept in its original tab order.
Because the Icon artwork is represented in an SVG, a common best practice is to use the title element. We'll put some text in it. The title element also needs a unique ID. We'll give it an ID of SVG title. Then, because Chrome actually has a bug in it still, it's been fixed but it hasn't made it into the main release, we need to give this SVG element a little bit of help.
We're going to add an ARIA labeled by attribute and point it to the SVG title. All that means is that this SVG will get the proper mapping so that it will expose this title as its accessible name.
Now we've got everything we need to create accessible buttons. Let's go back to our browser and open up VoiceOver again.
VoiceOver on Chrome. Button demo window. Button demo each Help. Button main three items. Help button. Help button. VoiceOver off.
That's how you can create accessible Icon buttons using HTML and CSS. Be sure to always test with the keyboard and a screen reader, if possible, to know whether your elements are accessible to people with disabilities.