Task

Ensure accordions are keyboard navigable

Category: 
Keyboard
Where: 
Custom code
Check as complete

Accordion elements should use an ARIA attribute to communicate an open or closed status to screen readers and other assistive technology.

Accessible accordion components

A common way to build an accordion in Webflow consists of a trigger element that is a direct sibling to a content element. An interaction is set on the trigger element to show the sibling content element when clicked. We should also add some specific attributes that are toggled when the accordion is opened or closed in order to announce the state of the accordion to screen readers.

Reference the cloneable project below that uses the proper structure, attributes and code outlined in this task.

Structure & class names

<checks-richtext_class>accordion-item<checks-richtext_class>

<checks-richtext_class>accordion-trigger<checks-richtext_class>

<checks-richtext_class>accordion-content<checks-richtext_class>

Webflow Designer with accordion item selected and navigation panel open

Custom attributes

How to add custom attributes: https://university.webflow.com/lesson/custom-attributes

<checks-richtext_class>accordion-item<checks-richtext_class>

  • role= "region"

<checks-richtext_class>accordion-trigger<checks-richtext_class>

  • role="button"
  • aria-expanded="false"
  • aria-controls=”{id-of-accordion-content}”
  • tabindex="0" (Only needed if the trigger element isn’t already a link or button)

<checks-richtext_class>accordion-content<checks-richtext_class>

  • aria-hidden="true"
Webflow Designer with accordion trigger selected and the element settings panel open
Webflow Designer with accordion content selected and the element settings panel open

Custom code

Add the custom code below to the before </body> section of the page or project settings.

Note: the script uses the class of <checks-richtext_code>accordion-trigger<checks-richtext_code> on the trigger element, and the <checks-richtext_code>accordion-content<checks-richtext_code> on the content element. To use different classes, update the class names in the script as well.


<script>
$(document).ready(function () {
    var accordionToggleButton = $('.accordion-trigger');
    accordionToggleButton.on('keydown', function (e) {
        // Activate on spacebar and enter
        if (e.type === "keydown" && (e.which !== 13 && e.which !== 32)) {
            return;
        }
        e.preventDefault();

        // Simulate a mouseclick to trigger Webflow's IX2/Interactions
        var evt = document.createEvent("MouseEvents");
        evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
        $(this).get(0).dispatchEvent(evt);
    });

    accordionToggleButton.on('click touchend', function (e) {
        $(this).toggleAttrVal('aria-expanded', "false", "true"); //toggle trigger attribute
        $(this).parent().find('.accordion-content').toggleAttrVal('aria-hidden', "true", "false"); //toggle content attribute
    });

    // jquery toggle just the attribute value
    $.fn.toggleAttrVal = function (attr, val1, val2) {
        var test = $(this).attr(attr);
        if (test === val1) {
            $(this).attr(attr, val2);
            return this;
        }
        if (test === val2) {
            $(this).attr(attr, val1);
            return this;
        }
        // default to val1 if neither
        $(this).attr(attr, val1);
        return this;
    };
});
</script>
Copy codeCopied!
Back to checklist

Total progress

Congratulations on making the web a more accessible place. Celebrate your work on Twitter.
Celebration horn and streamer emoji
0 / 0
Hide progress
Show progress