Improving website accessibility for screen readers (part 2)

In the previous part I wrote about why you should improve your web accessibility. I wrote about incorporating accessibility in your forms and labels using ARIA. In this part we will expand on ARIA and accessibility and how to apply it to buttons, navigation and dialogs. We'll start with the buttons.

The roles: button

As mentioned in part 1 in the chapter of Avoiding redundancy buttons automatically assume the role of a button. As such it does not need to be typed out.

Naturally, the button element should be used as your first option. Only use elements such as div or span as buttons if you have to.

There may be some cases where you for one reason or another have to use an element which natural role is not that of a button. As an example developers may use jQuery to register a click event on a div with the code:

<div id="not-a-button">Click here</div>

$( "#not-a-button" ).click(function() {
  alert( "A click occured." );

A screen reader will however not understand the intended meaning of the div#not-a-button element. Nor will your visitor understand it.

A better and more accessible way would be to set role="button" as such:

<div id="not-a-button" role="button" tabindex="0">Click here</div>

In order to make the div accessible by keyboard you have to set the tabindex attribute on elements which normally are not considered buttons, such as paragraphs (<p>) and the Document Division (<div>) element. A tabindex of 0 means the element is ordered by DOM position.

In the case of toggle buttons (on/off buttons) they need an extra attribute set to let screen readers know the button is pressed (toggled). The attribute is aria-pressed and has 4 possible values: true, false, mixed and undefined which also is the default. When undefined it means the button does not support being pressed.

<div id="toggle-button" role="button" aria-pressed="false">Click to toggle</div>

$( "#toggle-button" ).click(function() {
  $(this).attr('aria-pressed', $(this).attr('aria-pressed') === 'false' ? 'true' : 'false');

The roles: dialog

A dialog is a window or a modal which stands out from the rest of the web page, perhaps most often in the form of a modal.

Modals can be a bit tricky when it comes to making them accessible: the dialog requires certain pieces of contents (such as a title and description) to be set.

Your web page or web application also needs to handle keyboard input properly. For instance, the outsides of contents of a modal should not be reachable by keyboard until the modal is dismissed.

<div id="modal" aria-hidden="true" aria-labelledby="title" aria-describedby="description" role="dialog">
    <div role="document">
        <div id="description">
            Press escape to close this modal.
        <h1 id="title">Example modal</h1>

For a more complete example check out This repository also contains som good examples regarding keyboard focus (see the file modal-window.js).

The roles: navigation

Navigation is fairly easy.

The <nav> element requires no extra markup to be accessible.

        <li><a href="/">Home</a></li>

For other types of navigational you simply add the role navigation.

<div role="navigation"<>
        <li><a href="/">Home</a></li>

It is possible to have more than 1 navigation. As an example you may have one navigation elements. The first to navigate around between links on your website. The second to navigate around the current web page.