• 6 hours
  • Medium

Free online content available in this course.

course.header.alt.is_certifying

Got it!

Last updated on 4/1/22

Make Your Modals and Carousels Accessible

Modal windows and carousels are used on many sites. In this chapter, you will learn more about ARIA attributes as they relate to these interactions. 

Make Your Modal Windows Accessible

Before working on our modal dialog, you should know that making an accessible modal requires quite a bit of work. You need to think about modal controls, how to show assistive technologies that it is open, and how to control focus.

To help you, here is a list of things to consider when creating a modal:

  • When a modal opens, it obstructs the content in the background visually. It is important to hide the rest of the HTML page from assistive technologies when the modal is open. To do this, you’ll need to add an aria-hidden attribute.

  • You must add a role attribute to your modal (role= “dialog”). You can also provide additional information through ARIA attributes. For example, you can use the  aria-modal=” true”  attribute to indicate that other content is inactive when the dialog is open. 

  • Allow keyboard users to close the modal by using the escape key or close button.

  • It is important to shift focus into your modal once it is open and constrain focus until it is closed (if the focus isn’t constrained, the user will return to the background content instead of remaining within the dialog).

  • It’s essential to hide the modal (both visually and from assistive technologies) when it is not open.

Let’s take a closer look at the modal dialog code.

Discover the Working Modal Dialog

This section will start from an existing modal dialog and focus on what makes it accessible.

Open this CodePen to find the HTML, CSS, and JavaScript code of the modal we will be working on. Feel free to test it to see how it works. 🙂

So what are the elements that make this modal accessible?

Add ARIA Roles and Attributes

Let’s recap a few essential rules that you must apply when a modal window is open:

  • The entire content of the document, apart from the modal, must be hidden.

  • The user must take action to close the modal and return to the initial state. For someone using assistive technology, this means hiding the entire page content outside of the modal window using an aria-hidden=”true”  attribute.

  • The modal window needs to be usable with the keyboard. To do this, you need to focus on the modal with JavaScript.

// Func
const onOpenModal = () => {
   $mainWrapper.attr('aria-hidden', 'true')
   $modal.attr('aria-hidden', 'false')
   $body.addClass('no-scroll')
   $modal.css('display', 'flex')
   $modalCloseBtn.focus()
}
 
const onCloseModal = () => {
   $mainWrapper.attr('aria-hidden', 'false')
   $modal.attr('aria-hidden', 'true')
   $body.removeClass('no-scroll')
   $modal.css('display', 'none')
   $openModalBtn.focus()
}

This code modifies  aria-hidden  attributes of the modal dialog in real-time.

Add a Role to Your Modal Dialog

To make a modal understandable to assistive technologies, you must first specify its role using the  role=dialog  attribute. It indicates that the block is a dialog and announces when it pops up on the screen.

<div class="modal" aria-hidden="true" role="dialog">
    <div>
    </div>
</div>
Describe the Status of Your Modal and Document With "aria-hidden" Attributes

A modal can have two states: open or closed. When the modal is open, the rest of your document must be hidden from assistive technologies.

You will be able to perform this operation with the  aria-hidden  attribute. 

<main id="main-wrapper" aria-hidden="false">
    <!-- Content of your web page goes here -->
    <h1>Your web page</h1>
    <p>
        <button class="open-modal-btn">Open modal</button>
    </p>
</main>
<div class="modal" aria-hidden="true" role="dialog">
    <div>
    </div>
</div>

In the snippet above, you can see that:

  • The modal is open, and your entire document is hidden from assistive technologies.

  • The modal is visible.

In contrast, when the model is not open, its content should be hidden from assistive technologies, and the content of the page should be visible.

Describe the Content of the Modal

You can indicate the purpose of the modal by using an  aria-describedby  attribute - for example, if it's a modal window dedicated to registration.

<div class="modal" aria-hidden="true" role="dialog" aria-describedby="modalTitle">
    <div>
        <header>
            <h2 id="modalTitle" class="modal-title">Modal title</h2>
        </header>
        <div>
            <p>Content of your modal window</p>
        </div>
        <button class="modal-close-btn">Close modal</button>
    </div>
</div>
Close the Modal

To close the modal dialog, you must remember to include a close button:

<button class="modal-close-btn">Close modal</button>

There is one last important thing we must do: manage the focus when the modal opens and closes.

Below is how we would use JavaScript to manage (a) the focus on the modal opening or closing button and (b) the keyboard keys - especially the Esc key:

const onOpenModal = () => {
   $mainWrapper.attr('aria-hidden', 'true')
   $modal.attr('aria-hidden', 'false')
   $body.addClass('no-scroll')
   $modal.css('display', 'flex')
   $modalCloseBtn.focus()
}

When the modal opens, in addition to updating the  aria-hidden  attributes, you shift the focus to the modal close button (which allows the user to close it with the space bar).

// Close modal when escape key is pressed
$(document).on('keydown', e => {
    const keyCode = e.keyCode ? e.keyCode : e.which
 
    if ($modal.attr('aria-hidden') == 'false' && keyCode === 27) {
        onCloseModal()
    }
})

Here, using JavaScript, the modal responds to keyboard keys so that a user can close the modal by pressing the Esc key.

Code an Accessible Carousel

Before starting this section, it’s worth mentioning that carousels have a negative reputation on the web. They are often used for marketing or commercial purposes, and research shows that site visitors rarely engage with their content.

Whether you like them or not, you need to learn how to create them in an accessible way, if you ever have to build one.

Who Is the Target Audiences?

There are several users to think about when creating accessible carousels. This list is by no means exhaustive, but it’s helpful to think about:

  • People with mobility limitations. Avoid carousels that scroll through slides automatically. The moving content makes it challenging to click on links within the carousel. 

  • People who use assistive technologies. They need to know that they are interacting with a carousel, what the current item displayed is, and how to switch between the slides.

  • People with vision problems. They may have trouble reading the text in a moving carousel. Once again, automatic scrolling is not recommended.

  • People with cognitive differences or attention disorders. Moving content can be a distraction, which is why you also need a pause button in your carousel. 

Create the Basic Carousel Structure

A carousel can be created using lists (ol  or  ul), or a series of  div  elements. Some assistive technologies can give the number of items contained in a list, so this approach is preferred.

<!-- Carousel with divs -->
<div>
    <ul class="carousel">
        <li class="carousel-item"></li>
        <li class="carousel-item"></li>
        <li class="carousel-item"></li>
    </ul>
</div>

Add a Title to the Carousel

A carousel is often structured around a common theme. There are several cooking recipes for March in the example below, so we’ve added an aria-label to describe the carousel’s purpose to assistive technologies. 

<body id="body">
    <main id="main-wrapper" aria-hidden="false">
        <h1>Your carousel</h1>
        <ul class="carousel" aria-label="Our selection of Recipes">
            <!-- ... -->
        </ul>
    </main>
</body>

Control the Carousel 

Here is a brief reminder of how to use a carousel:

  • You can let it scroll automatically (not recommended!).

  • You can control it with the mouse by clicking on the "next" and "previous" arrows.

  • You can tab to the “next” and “previous” buttons with the keyboard and press the Enter key to move to another slide. 

You can use a  button  for “next” and “previous” controls. If you are using another element, such as a  div  or a  span, you’ll need to add a  tabindex  value so it receives keyboard focus, and control the behavior of the button with JavaScript.

Carousels often have timed slides so that the content changes every few seconds. It is not a very good practice as it can be distracting and may not give users enough time to read the content. It can also make it more challenging for non-visual users to know what slide is in view, especially if the slides contain links.

This is why it is important to add a pause button. Users will be able to pause the carousel and go through it at their own pace.

Define Roles

Next, you need to communicate to assistive technology users that this content is a carousel.

There’s only one problem: there are no semantic HTML carousel elements, and ARIA doesn’t have roles dedicated to carousels either.

So what do we do?

You can use a  role=”region”  and  aria-roledescription . The region role will group all of your carousel content and  aria-roledescription  will provide specific information about the purpose of the region. This attribute is flexible because you can give it any value. But as much as possible, stick to simple, clear, and concise values. For the entire region, add  aria-roledescription=”carousel” , and for each slide add  aria-roledescription=”slide” . Have a look at an example of a carousel with these roles and attributes in action. 

Manage the States of Elements

Each item in the carousel that isn’t in view should also be hidden from assistive technologies. To do this you can use an  aria-hidden attribute, which should be set to  false  for the slide that is visible on the screen, and  true  for items that are out of view.

Here is an example of how the  aria-hidden  attribute can be changed via JavaScript:

const setNodeAttributes = (lastItem, currentItem) => {
   $(lastItem).css('display', 'none')
   $(currentItem).css('display', 'block')
   $(lastItem).attr('aria-hidden', 'true')
   $(currentItem).attr('aria-hidden', 'false')
}

Let’s Recap!

  • When a modal window is open, the  aria-hidden  attribute must be applied to the entire document, NOT including the modal window.

  • The dialog  role allows assistive technologies to know when a modal has been opened. 

  • A carousel must necessarily be controllable via both the keyboard and the mouse and may (or may not) offer automatic scrolling. Add a pause button if the content scrolls automatically.

  • Add  aria-hidden  attributes with the values  true  or  false  depending on whether a carousel slide appears on the screen or not. 

Next, let’s have a look at CSS practices that can be useful for accessibility. 

Example of certificate of achievement
Example of certificate of achievement