How To Make Divi Toggle Module Web Accessible

Following on from the post on making the Divi Accordion module web accessible, today we'll tackle the Divi Toggle module.

two Divi toggles on the front end of WordPress, with the first toggle open and the second closed

The functionality of the Toggle module is similar to the Accordion module. The main difference is each Toggle element stands alone.

Because of that, I think the Toggle module should follow the WAI-ARIA Disclosure Design Pattern. See the Disclosure design pattern example.

How to make the Divi Toggle Module web accessible: To make the Divi toggle module web accessible, add a script module with jQuery that adds a zero tabindex, connects the title and content of each toggle and switches the aria-expanded value based on the open state. You might also need to add a keyboard trigger and a focus outline.

We'll go through each part of the code below, but if you just want to copy and paste the code into your module, here it is.

<script type="text/javascript" async>
jQuery(document).ready(function($) {
  $(".et_pb_toggle").each(function(i) {
    var toggleID = "et_pb_toggle_" + i;
    $(this).attr("tabindex","0");
    $(this).children(".et_pb_toggle_content").attr({
      "id": toggleID,
      "aria-labelledby": toggleID + "-title",
      "role": "region"
    });
    var toggleText = $(this).children(".et_pb_toggle_title").text();
    $(this).children(".et_pb_toggle_title").html(
      "<span role='button' id='" + toggleID + "-title' aria-controls='" + toggleID + "'>" + toggleText + "</span>"
    );
  });

  update_toggle_aria();
  $(".et_pb_toggle").on("click", ".et_pb_toggle_title", function() {
    setTimeout(update_toggle_aria, 1500);
  });

  function update_toggle_aria() {
    $(".et_pb_toggle_open .et_pb_toggle_title span").attr("aria-expanded", "true");
    $(".et_pb_toggle_close .et_pb_toggle_title span").attr("aria-expanded", "false");
  }

  $(document).on('keyup', function(e) {
    if (e.which === 13 || e.which === 32) {
      $('.et_pb_toggle:focus .et_pb_toggle_title').trigger('click');
    }
  });
});
</script>

This code is compatible with the web accessible Accordion Module script we looked at in an earlier tutorial, so if you have both on the page or site, there's no issue with using both of them together.

Add the script to the page

If you've got a toggle on every page of your website, you might want to add the script to an external JavaScript file, but for the purposes of this tutorial, we're just going to add it as a Code module.

The code just needs to be somewhere on the same page.

Because the Code module is invisible on the frontend builder, I like to put it either directly below the toggle, or at the bottom of the page.

No matter how many Toggle modules you have on the page, you only need to add this script once.

Add a Code module.

Inserting a module on the Divi frontend builder with an arrow pointing to the Code module

Paste the script from above in the Code box, click the save module check icon and save the page.

The Divi frontend builder with a Code module open. In the code area is the code from this page.

Now everything should be working properly.

I'll go through the sections of the code in a minute, but we have one final thing to do, if you haven't already implemented it.

Add a focus outline in CSS

Divi doesn't automatically add a focus outline. This is important for keyboard navigation, because it lets the user know where they are on the page.

Go to either the Theme Customizer -> Advanced CSS or into Divi -> Theme Options and scroll to the bottom.

The Custom CSS section of Divi Theme Options with the focus outline code in the Custom CSS box.

Add this code:

*:focus {
  outline: 1px dotted #000;
}

You can customize the outline to suit your site.

1px refers to the width of the outline. Dotted will make it a dotted line. You could also use solid or dashed. #000 will make the line black. You can put any other hex color value there, but try to make it have enough contrast with the rest of your design.

What does the code do?

Let's have a look at the code that makes the Divi Toggle module web accessible.

<script type="text/javascript" async>
jQuery(document).ready(function($) {

[...]

});
</script>

This part sets up the script as jQuery. Think of it like the wrapper to tell the browser how to interpret the rest of the code.

Add code to each toggle

$(".et_pb_toggle").each(function(i) {
  var toggleID = "et_pb_toggle_" + i;
  $(this).attr("tabindex","0");
  $(this).children(".et_pb_toggle_content").attr({
    "id": toggleID,
    "aria-labelledby": toggleID + "-title",
    "role": "region"
  });
  var toggleText = $(this).children(".et_pb_toggle_title").text();
  $(this).children(".et_pb_toggle_title").html(
    "<span role='button' id='" + toggleID + "-title' aria-controls='" + toggleID + "'>" + toggleText + "</span>"
  );
});

Using each, we go through each toggle, in case there are multiple toggles on the page.

The i in function(i) is a counter starting at zero. Divi automatically creates a unique toggle number as a class for each toggle on a page, starting at zero. We can use the counter to do the same thing and avoid having to pull the unique number out using more complicated methods.

We add tabindex="0" to each toggle to add it to the list of elements the keyboard will tab through.

Next we add an ID to the toggle content, so the title can connect to it. We then tell the browser the ID of the title that connects to the content and set the role to "region".

In the next line, we grab the title text for use in the next step.

We wrap the title in a span to make it behave like a button. We give it an ID and tell the browser which content area this title controls.

Set the aria-expanded state

update_toggle_aria();
$(".et_pb_toggle").on("click", ".et_pb_toggle_title", function() {
  setTimeout(update_toggle_aria, 1500);
});

function update_toggle_aria() {
  $(".et_pb_toggle_open .et_pb_toggle_title span").attr("aria-expanded", "true");
  $(".et_pb_toggle_close .et_pb_toggle_title span").attr("aria-expanded", "false");
}

The first line tells the browser to run the update_toggle_aria() function. This adds the correct aria-expanded attribute to the toggle titles, base on whether the toggle is open or closed.

The $(".et_pb_toggle").on("click" etc line listens for a click on the toggle, waits for 1500 milliseconds and updates the state of aria-expanded on all the toggles.

We wait for that period because Divi takes a few milliseconds to open or close the toggle, before adding the CSS that our code is looking for to tell us whether it's open or closed.

Simulate mouse clicks with the keyboard

$(document).on('keyup', function(e) {
  if (e.which === 13 || e.which === 32) {
    $('.et_pb_toggle:focus .et_pb_toggle_title').trigger('click');
  }
});

The last piece of code listens for the Enter key (13) or Space bar (32) being pressed. If the toggle is in focus, it will simulate a mouse click on the toggle.

That does it for today, let me know in the comments how you go.

Leave a Comment