Creating accessible “tags” 1/2

Associated themes :


In this example 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:

Screenshot of several tags in a web page

HTML structure

As tags do not wander on their own, we will create an HTML list. Thus a user browsing with a screen reader will directly hear the number of tags on display. “List of X elements…”.


Example 1

 Open example 1 (new window)

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 in 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.

    <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>

Example 2

Open example 2 (new window)

And voilà! Simple and accessible tags. OK, it’s not very beautiful so far.

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.


Example 3

Open example 3 (new window)

But wait, we’ve just lost screen reader users. The buttons are now vocalized as “X”. We can fix this for example with the aria-label attribute.

    <li>Alcatel<button aria-label="Remove Alcatel from the list">X</button></li>

We’ll add some CSS to hide the button background and borders.

button {
    background-color: transparent;
    border: none;
    color: #fff;
    font-weight: bold;

Example 4

Open example 4 (new window)


It works but it’s not perfect. You have to aim precisely to remove a tag, because the cross-shaped button is not that big. It’s not very nice to use and may really be a problem for people with a trembling hand or 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.

    <li><button aria-label="Remove Alcatel from the list">Alcatel</button></li>

We add the cross via CSS:

  li button:after {
    content: "x";
    margin: .25rem .25rem .25rem .75rem;
    padding-left: .4rem;
    border-left: .15rem solid #fff;

Example 5

Open example 5 (new window)

It’s better. Visually, we can see two things in each tag, the label and a remove button. Yet with a screen reader we only hear for the moment “Remove XXX 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.

    <li><span class="visually-hidden">Alcatel</span><button aria-label="Remove Alcatel from the list">Alcatel</button></li>

With a screen reader, we now hear each tag’s label, then a button to remove it.

Example 6

Open example 6 (new window)

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;

Example 7

Open example 7 (new window)

Optimisation (again)

Our tags are accessible. Yet when we remove one tag with the keyboard, the focus stays on the vanished tag; so we don’t know where the focus is. This can be easily fixed with a bit of Javascript. We can focus the previous element, for example:

  $("button").on("click", function () {

Example 8

Open example 8 (new window)

When a tag is removed, we see it disappears from the screen. But if we want a screen reader user to be sure that the tag was removed, we’ll have to vocalise 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 () {
      srSpeak($(this).text() + "removed");

Example 9

Open example 9 (new window)

This time, our “tags” are genuinely accessible to the mouse, to the keyboard and to the screen reader.