Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slick accessibility updates #5151

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

bpmcneilly
Copy link
Contributor

This PR provides an approach to increase the accessibility of our slick slider carousels.

The existing implementation of the slick "accessibility" features is definitely lacking. While, in the long run, we may need to switch away from slick, this PR would ensure that we have some of the most needed accessibility in place while we look for other slider options in the future.

Technical

The biggest issue with the "accessibility" features implemented by Slick are that they do not move keyboard focus appropriately for keyboard-only users, and their existing role of listbox isn't particularly valid for the type of control displayed. An ARIA listbox role is intended to be something similar to an HTML select element.

It's impossible to leave the "accessibility" features on & simply write over the existing content because whenever a user updates the slider the library will reimpose its default roles. So, for this PR I simply opted to turn off all the accessibility features & add on from there.

Doing this requires manually adding back in a few things we got "for free" previously, but the only thing of note is setting tabindex="-1" to the off-screen interactive elements in a slider to prevent them from receiving focus.

In terms of new features, this PR adds in:

  • Removing buttons with aria-disabled="true" from being in the tab order
  • Logical focus order updates when users activate the previous / next buttons in a slider
  • An updated role of list & listitem for the carousel & its contents, along with a programmatic label
    • This will expose the carousel contents as the "Classic Books list", along with the number of items displayed on-screen
    • Lists will also allow some AT users to navigate between items in the carousel with shortcuts

The biggest downside of this PR is that there is additional JS we will need to maintain & we have to manually set up a lot of the elements here. As an example, because the list role is being added with the main slider & the listitem roles get added locations, it's easy to miss content & create a list with no list items. I did this accidentally when I forgot to add role="listitem" to the categories slider.

Testing

  • Verify any book slides offscreen do not receive focus & are programmatically hidden with aria-hidden="true"
  • Ensure all carousels include both a role attribute with a value of list & that each carousel element has a role attribute with a value of listitem

Screenshot

Here's a sample animation of the updated focus movement when navigating via the keyboard:
A carousel labelled 'Classic Books' with a focus indicator tabbing through & navigating to previous content

Stakeholders

@mekarpeles

@bpmcneilly bpmcneilly added the Theme: Accessibility Work related to disability accessibility. [managed] label May 7, 2021

function accessibilitySetup() {

function setA11yAttributes() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this need to be embedded within the function? It doesnt' seem to use the closure...

@@ -178,6 +180,32 @@ const Carousel = {
}
});
}

function accessibilitySetup() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add documentation for the new method explaining its purpose


function setA11yAttributes() {
//Ensuring offscreen elements do not receive focus
$(`${selector} [aria-hidden="true"] a[href]`).attr('tabindex', -1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cache the result of the selector query before applying other queries to save DOM lookups.

$(`${selector} button.slick-next`).on('click', function () {
$(`${selector} button.slick-prev`).focus();
});
$(selector).on('afterChange', setA11yAttributes);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add an inline comment explaining the afterChange event, preferably pointing to some documentation.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't this bind multiple click events to the next and previous buttons?

});
$(selector).on('afterChange', setA11yAttributes);
}

}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new method MUST have a corresponding unit test.

@jdlrobson
Copy link
Collaborator

Please reassign me when you are ready for another review. Thanks!

@davidscotson
Copy link
Collaborator

See also https://accessible360.github.io/accessible-slick/ which is a fork of the slick library with various accessability enhancements baked in and the authors have good info on real world accessibility of carousels in their github repos.

@mekarpeles mekarpeles assigned RayBB and unassigned bpmcneilly Mar 18, 2024
@RayBB
Copy link
Collaborator

RayBB commented Mar 23, 2024

@bpmcneilly do you have any interest to continue working on this now? I assume not since it has been a while. I'd like to offer this issue up for someone to fork your branch and wrap it up. Thanks!

@mekarpeles
Copy link
Member

@RayBB yes please!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Theme: Accessibility Work related to disability accessibility. [managed]
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants