Creating accessible tags 1/2
Associated themes:- Component
Publication date
Update of the article from
Preamble
In this article, we will create accessible tags — you know, these buttons we use to categorize content or add a list of recipients, etc.
Final design
Here is an example of the expected design:
HTML structure
Tags usually come in an HTML list. Thus, a user browsing with a screen reader will directly hear the number of tags on display: 'List of X elements...'.
<ul> <li>Alcatel</li> <li>Doro</li> <li>Apple</li> <li>LG</li> <li>Sony</li> </ul>
Removing a tag
One must be able to remove a tag. We will add a 'Remove' button on each element in our list. For users who cannot see the screen and browse with a screen reader, a plain 'Remove' button is not sufficient. We will add the tag name to the button's label to disambiguate, i.e., 'Remove Sony from the list.'
The use of a real button makes this functionality accessible to the screen reader, but also to people who cannot use a mouse and rely on a keyboard to move the focus (with the Tab key). A button can indeed be focused naturally.
<ul> <li>Alcatel<button>Remove Alcatel from the list</button></li> <li>Doro<button>Remove Doro from the list</button></li> <li>Apple<button>Remove Apple from the list</button></li> <li>LG<button>Remove LG from the list</button></li> <li>Sony<button>Remove Sony from the list</button></li> </ul>
Here we present simple and accessible tags. Admittedly, their appearance is not particularly appealing at this stage.
Let's decorate
Now that our tags are accessible, we can decorate them. The ideal solution would be to make them look like the first illustration at the beginning of this article. We have several solutions.
For example, we can start by replacing the button's text by an 'X' or a cross-shaped icon.
<ul> <li>Alcatel<button>X</button></li> </ul>
But wait, we've just lost screen reader users. The buttons are now vocalized as 'X'. We can fix this by giving a proper accessible name to these buttons, for example, by using the
aria-label
attribute.<ul> <li>Alcatel<button aria-label="Remove Alcatel from the list">X</button></li> </ul>
We'll add some CSS to hide the button background and borders.
button { background-color: transparent; border: none; color: #fff; font-weight: bold; }
Optimisation
It works, but it's not perfect. You have to aim precisely to remove a tag because the cross-shaped button is a bit small. It's not very user-friendly and could be a problem for people with a trembling hand or those who have difficulties using a mouse.
Since we know that removing is the only possible action, we could extend the clickable zone to the whole tag. Hence, even if you slightly miss the target, the remove action will be taken into account.
<ul> <li><button aria-label="Remove Alcatel from the list">Alcatel</button></li> </ul>
We add the cross via CSS:
li button:after { content: "x"; margin: .25rem .25rem .25rem .75rem; padding-left: .4rem; border-left: .15rem solid #fff; }
It's better. Visually, we can see two things in each tag: the label and a remove button. However, with a screen reader, we currently only hear for the moment 'Remove x from the list'. To correct this, we add a
span
containing the tag's label. To prevent it from being displayed on screen (this would double the information), we add to it an accessible hiding class (visually-hidden
). The text will only be read by screen readers.<ul> <li><span class="visually-hidden">Alcatel</span><button aria-label="Remove Alcatel from the list">Alcatel</button></li> </ul>
With a screen reader, we now hear each tag's label, then a button to remove it.
We still have one last problem: if we navigate the page with a keyboard (moving the focus with the Tab key), we don't know on which button the focus is.
We add a bit of CSS to give emphasis to the focus. We also take the opportunity to do the same for hover.
button:hover, button:focus { background-color: #f16e00; color: #000; }
Optimisation (again)
Our tags are accessible. However, when we remove one tag with the keyboard, the focus stays on the vanished tag; thus we don't know where the focus is. This can be easily fixed with a bit of JavaScript. We can focus on the previous element, for example:
$("button").on("click", function () { $(this).parent().prev().find("button").focus(); $(this).parent().remove(); });
When a tag is removed, we see it disappear from the screen. However, if we want a screen reader user to be sure that the tag was removed, we'll have to vocalize a confirmation message to the user.
To manage this, we can use our JavaScript srSpeak function, which uses ARIA to make the screen reader speak.
$("button").on("click", function () { $(this).parent().prev().find("button").focus(); $(this).parent().remove(); srSpeak($(this).text() + "removed"); });
This time, our tags are genuinely accessible for mouse, keyboard, and screen reader users.