A Drupal Slider – Making it More Accessible

Anyone who has worked at making websites more accessible to visitors with disabilities knows that it is a process, not a one time, binary (yes/no) thing.

Some website features present extra challenges. Sliders, for example, are an eye-catching visual feature, but how do you make them more accessible to visitors with disabilities? This can be especially challenging when you are (as you probably should be) using an existing slider addon or plugin, and not creating it from scratch.

Let’s take a look at how Courtland recently made a slider in a client’s Drupal website more accessible.

Getting started

The go to slider for Drupal is probably Views Slideshow. So let’s look at tweaking this slider, using the “Carousel Concepts” tutorial from W3C as our guide. We’ll go through just the first few concepts, not all of them, for the sake of this article. Our goal will be to make the slider as accessible as possible, while minimizing structural changes as much as we can.

Structure

General Structure

[ https://www.w3.org/WAI/tutorials/carousels/structure/#general-structure ]

As a collection of content items, carousels are typically best represented as unordered lists, using <ul> and <li>. Depending on the context, other elements can also be used.

Views Slideshow uses article tags within div tags to present the slides, not <li> tags within a <ul> tag. It is structured HTML though, and the preamble to this guideline states that “Structural markup ensures that the content of a carousel can be used in a variety of situations. For example, a carousel with proper markup could be presented as a list of articles on a mobile device”. A list of actual article tags seems appropriate for this purpose.

Every carousel should be enclosed in a labeled region, to allow users to find the carousel easily. In the following example, a <section> element is used to define the region and aria-labelledby defines the heading that contains the label.

To satisfy this, we are going to have to override one of the templates used by Views Slideshow. Make a copy of views-view-slideshow.html.twig (from /modules/contrib/views_slideshow/templates/) and place it in your theme’s /templates/ directory.

In the override copy, we are going to change this:

{% if slideshow %}

  <div class="skin-{{ skin }}">

    {% if top_widget_rendered %}

      <div class="views-slideshow-controls-top clearfix">

        {{ top_widget_rendered }}

      </div>

    {% endif %}

To this:

{% if slideshow %}

  <div class="skin-{{ skin }}" aria-labelledby="sliderheading">

    <h3 id="sliderheading" class="visuallyhidden">Slider</h3>

    {% if top_widget_rendered %}

      <div class="views-slideshow-controls-top clearfix">

        {{ top_widget_rendered }}

      </div>

    {% endif %}

We then use CSS to hide (if desired) the “visuallyhidden” class from regular browser-based visitors, but not from assistive technology: https://a11yproject.com/posts/how-to-hide-content/

Carousel Items

[ https://www.w3.org/WAI/tutorials/carousels/structure/#carousel-items

In all cases, use appropriate markup to ensure that the structure and meaning of the content are conveyed clearly. Such markup may include headings, sections, lists, articles, and other elements as needed.

Views Slideshow does fairly well on this. For example, the slide title will by default be displayed within an h2 element which will itself be within a header element.

Functionality

Add Previous and Next buttons

[ https://www.w3.org/WAI/tutorials/carousels/functionality/#add-previous-and-next-buttons ]

Provide buttons to allow users to switch back and forth between items.

Views Slideshow does this out of the box, if you display “Controls” in top or bottom widgets.

Screenshot from Drupal Views Slideshow, showing how to enable Widgets

However:

The buttons created by Views Slideshow are not, ahem, button elements. However, they are <a> tags, which have a long history (since they predate button) of being used for controls. We can add an ARIA role, to indicate that these are functionally buttons.

We can make changes to the Previous and Next buttons much the same way that we did earlier to the slideshow container. For the Previous button, make a copy of views-slideshow-controls-text-previous.html.twig (from /modules/contrib/views_slideshow/templates/) and place it in your theme’s /templates/ directory. Editing the copy of the file, you can now add role=”button” to the <a> tag. Do likewise for the Next button by overriding views-slideshow-controls-text-next.html.twig.

Announce the current item

[ https://www.w3.org/WAI/tutorials/carousels/functionality/#announce-the-current-item ]

Use a WAI-ARIA live region to inform screen reader users what item is currently shown. In this example, a visually hidden, “polite” live region is used and added to the carousel when the carousel is loaded. Then, when clicking the previous or next buttons, the text “Item x of y” (with x for current item number and y for the number of items) is set to this live region. Capable screen readers will announce this text.

Views Slideshow already provides an “item x of y” region; we just need to sprinkle on the accessibility magic. Override views-slideshow-slide-counter.html.twig.

Change this:

<div id="views_slideshow_slide_counter_{{ vss_id }}" {{ attributes.addClass(classes) }}>

<span class="num">1</span> {{ 'of'|t }} <span class="total">{{ slide_count }}</span>

</div>

To this:

<div aria-live="polite" aria-atomic="true" class="liveregion visuallyhidden">
<div id="views_slideshow_slide_counter_{{ vss_id }}" {{ attributes.addClass(classes) }}> Item
<span class="num">1</span> {{ 'of'|t }} <span class="total">{{ slide_count }}</span>
</div>
</div>

Add navigation buttons

[ https://www.w3.org/WAI/tutorials/carousels/functionality/#add-navigation-buttons ]

Display buttons for each item in the carousel and highlight the current item. This allows users to get an overview of the carousel content, where they are in the sequence and will enable them to navigate directly to any item.

View Slideshow provides this in the form of a “pager”. It doesn’t use button elements though, so let’s add the button role and make these TAB-able . Override views-slideshow-pager-field-item.html.twig.

Change this:

<div id="views_slideshow_pager_field_item_{{ location }}_{{ vss_id }}_{{ count }}" {{ attributes.addClass(classes) }}>
{{ item }}
</div>

To this:

<div id="views_slideshow_pager_field_item_{{ location }}_{{ vss_id }}_{{ count }}" {{ attributes.addClass(classes) }} role="button" tabindex="0">
{{ item }}
</div>

Focus the selected carousel item 

[ https://www.w3.org/WAI/tutorials/carousels/functionality/#focus-the-selected-carousel-item ]

When users select an item with those navigation buttons, the focus should be set on the selected item {…} This makes interaction easier for keyboard and assistive technology users.

This one is tricky and possibly a little contradictory, as the guidance for the Next and Previous buttons says not to move the focus when those buttons are used to change slides.

We tabled this one for the time being.

Wrapping Up

There are two more sections to the carousel guidelines, Animations and Styling. We’ll leave those as an exercise for you! The previous examples just show the general approach.

The point of this article is not so much the specific changes that we made at one point in time to Views Slideshow (though if you found something helpful in that regard, that’s great!), but rather that we have more power than we might think that we do to make improvements to the accessibility of pre-existing complex components (especially if the component provides a nice templating system!).

So go forth and make the web more accessible!

If you need assistance making your website accessible, we’d love to help.