A carousel is a prominent section of a page. It holds content important enough to warrant a landmark role. Of the 8 landmark roles, the only one a carousel can use is region.
This is why we marked up the carousel with a <section> element. (The <section> element has an implicit region role).
<section class="carousel">...</section>
Each landmark should have an accessible name. In this case, letâs use âCarouselâ as the accessible name.
Weâll set the accessible name with aria-label since the words âCarouselâ cannot be found on the page.
Users can change carousel slides by using the â and â keys. This method works perfectly for Voiceover users.
Unfortunately, this method wonât work for NVDA users. It doesnât work for NVDA because NVDA uses â to speak the next character and â to speak the previous character.
We need to create another method for NVDA users.
You might beat yourself up at this point. You might think youâve wasted time and energy, and you have to throw away the â and â functionality.
Donât beat yourself up. Our work is not wasted. Voiceover users and non-screen reader users can still use â and â keys. Think of it as an enhancement for them.
We simply have to create a fallback for NVDA users.
Allowing NVDA users to switch slides
We know we cannot use arrow keys for NVDA users. But we also cannot use control, alt, or shift modifiers with arrow keys. Theyâre all used for other commands.
Key
Command
Left
Say previous character
Right
Say next character
Control + Left
Say previous word
Control + Right
Say next word
Alt + Left
Previous page (browser shortcut)
Alt + Right
Next page (browser shortcut)
Shift + Left
Selects previous character (system shortcut)
Shift + Right
Select next character (system shortcut)
We need a simple way a user can understand and use the interface. The simplest way is let them use the previous and next buttons.
Using previous and next buttons
First, we need to remove the tabindex attribute on the previous and next button elements so users can access them.
Sighted users can see a change happening when they click (or hit Enter on) a button. They can see the carousel move. But blind users canât. We need to inform them of the change with a live region.
Letâs start by creating a live region within the carousel.
Weâll use an alert role because the information is important and time-sensitive. Users need feedback that something has changed.
Voiceover users would hear the slide live region perfectly:
Unfortunately, NVDA says âalertâ if we use the alert role.
This is more of a status change than an âalertâ. The âalertâ may throw users off. So weâll switch to a status role with aria-live set to assertive instead.
If a sighted NVDA user uses our carousel, they may try to use â and â keys to switch slides. Theyâll do this because we added instructions for them to do so.
But we know NVDA users cannot use â and â keys to switch slides. We need to remove this set of instructions for NVDA users.
Unfortunately, thereâs no way to detect whether a user is using a screen reader, much less which screen reader theyâre using. So we need to remove this set of instructions completely.
<!-- Remove this -->
<div class="carousel__overlay">
Use ← and → to switch slides.
</div>
/* Remove this */
.carousel__overlay { /* ... */ }
Normal users and Voiceover users wonât know about â and â keys. Theyâll have to discover the â and â shortcuts by themselves.
This is okay because the â and â shortcuts are enhancements. Itâs not critical for users to know about them.
Navigating with âNext Itemâ
Try navigating through a carousel with a screen readerâs âNext Itemâ command. The dots and slides will go out of sync.
This is normal.
It happens because screen readers donât send browsers any events when they use âNext Itemâ. As a result, browsers canât send us events too.
We can solve this sync issue by preventing screen readers from âhiddenâ slides. We can do by:
Setting aria-hidden="true" to other slides
Setting visibility: hidden to other slides
Setting aria-hidden to other slides
The first method is to set aria-hidden="true" true to other slides. When slides change, we switch the aria-hidden="true" property (like roving tabindex).
This works on NVDA.
But thereâs a bug on Safari. It shows the last slide.
Since aria-hidden doesnât solve the problem completely, weâll use the visibility: hidden method instead.
Setting visibility hidden to other slides
We can hide slides by adding visibility: hidden to them. Weâll only show the selected slide by changing visibility back to visible.
If you pay attention to NVDAâs message, youâll notice NVDA says: âList with one itemâ. But when we switch slides, it says âSlide X of 3â.
This is confusing. What does the carousel contain? List items or slides?
The best way to resolve this problem is to remove list semantics by setting role of the list to presentation or none. NVDA wonât say âList with one itemâ once we do this.
Each link should have an accessible name. This tells users where they will go to.
Normally, the accessible name is the linkâs text content. We donât have text content in this case so create the accessible name with the title attribute.