Skip to content

The Case for Having a Role

Custom Element’s Best Friend

I have been designing and building web components for the Bolt Design System and I found myself using this a lot: the role attribute.

What is a role?

According to W3C, the Role Attribute defined in this specification allows the author to annotate markup languages with machine-extractable semantic information about the purpose of an element. In other words, a role defines the semantic meaning of a particular element.

For example, I can assign a role attribute to a <div>:

<div role="banner">…</div>

And that will indicate the same semantic meaning as this:

<header>…</header>

The problem

I am building out web components, which means I am creating custom elements. More often than not, I don’t have the luxury to always use the proper HTML elements and that could lead to poor accessibility. Take a list for example, in plain HTML, I would write this:

<ul>
  <li>…</li>
  <li>…</li>
  <li>…</li>
</ul>

But as a web component, the markup becomes this:

<ds-list>
  <ds-list-item>…</ds-list-item>
  <ds-list-item>…</ds-list-item>
  <ds-list-item>…</ds-list-item>
</ds-list>

Now <ds-list> and <ds-list-item> do not carry any semantic meaning and screen readers would not be able to read the information as a list. This is where the role attribute comes to the rescue!

The solution

I fixed it by adding a few role attributes:

<ds-list role="list">
  <ds-list-item role="listitem">…</ds-list-item>
  <ds-list-item role="listitem">…</ds-list-item>
  <ds-list-item role="listitem">…</ds-list-item>
</ds-list>

That’s it! It’s so simple. This method can apply to all kinds of elements, for a list of available roles, reference the MDN docs. Now go and build your own accessible web components.