Check out a free preview of the full Enterprise Web App Accessibility (feat. React) course

The "Optimizing Slideshow Component Exercise" Lesson is part of the full, Enterprise Web App Accessibility (feat. React) course featured in this preview video. Here's what you'd learn in this lesson:

Marcy discusses a slideshow component and demonstrates how to make it more accessible for screen reader users. They explain the use of ARIA roles and attributes, such as aria-live and aria-label, to provide meaningful information and improve the user experience. The instructor also addresses questions from the audience regarding loading states and testing with screen readers.


Transcript from the "Optimizing Slideshow Component Exercise" Lesson

>> So just like before, we have a component on the page. These are some pictures I took in Hawaii a couple weeks ago. We also have a version of it on StackBlitz, if you want to play with it there. I am going to make some changes here on the actual site.

So there's this gallery. It has these pictures in it. And there are some captions, there's some dots down here to go around that may or may not be accessible. And then there's a full screen. So the full screen could be a good candidate for using the role of application.

A user has intentionally gone into this mode. It's a full screen slideshow. They're not gonna be trying to navigate by headings, there's just less on the page right now. So I think I could probably safely toggle this application rule on and off to make this work better in NVDA.

But I'm putting it Kind of behind this setting that gets going into full screen mode. That's a toggle that I can kind of use as a flag on whether I'm gonna use this application role or not. And so this is one instance where I could probably get away with it.

So let's play with this in NVDA real quick. See what it looks like before we do anything with it. [SOUND]
>> Exercise 3, slide show exercise.
>> So we've got our gallery here. I'm gonna tab.
>> And mark go full screen button and your full screen.
>> There's our button, can I get to any of the other buttons?

>> Look at the whole previous slide button.
>> Yeah, I can.
>> Next slide button.
>> So I can use these.
>> Grammatic light in sharks' code where the water reflections are broken up by rocks and families.
>> So it is doing a pretty good job of reading everything.

I actually want to check and see if this is the completed one or not. [LAUGH] But if I want to go into full scope screen mode.
>> Go full screen button and your full screen.
>> It tells me what that button does even though it's an icon button, it has a label on it that says enter full screen mode and I can hit Enter.

>> Image slideshow.
>> And it sent me into the full slideshow, or it opened it at least I don't know if it moved my focus or not kind of didn't sound like it. So if I use the arrow key Keys.
>> Three of five.
>> It is-
>> Four of five, the beach palm trees and canoes and wiki key.

>> It is actually advancing me.
>> Five of five sun sliding in late in the afternoon at Kyluma beach.
>> Cool, seems to be working okay. So let's go see what's going on with our code right now. So-
>> I mostly want you to know that NVDA and Windows testing is that easy.

Like that was so seamless. I could just go NVDA, open it up on my Mac, so that you can go and test stuff and make sure it works. So we saw the portal switcher. That component is under our components directory in slideshow.tsx. So this version of this might even be working better than it used to actually.

So we have a series of divs. We have a list of elements. These previous and next buttons are not very accessible. So this actually, I'm kind of wondering if we were seeing the wrong version. I'm gonna do a little check here to see which one, yeah, see that was the completed slideshow, I wondered.

That's why that was working so much better. I'm actually going to change it back. So, let's go look at NVDA again. We'll go see what it looks like before it has fixes in it. And this is the deployed version also. Let me see if I can open it up locally.

I thought that a link would work.
>> Slide show HTTP, HTML.
>> That's the one thing sometimes you have to be able to access what you're doing. I think it depends on what network I'm on, or demo might be foiled.
>> Refresh, loading complete. Slide show exercise.
>> Well, we know that this was working.

So, I am going to opt to show you what code I used for this. If I was better set up, we would be able to test them back to back. So, we really need to test it in Windows to see, but in a live demo, I'm a little bit caught.

So let's go over to our code. Let's look at what this completed version looks like. It'll kind of help with time, anyways. So this completed version, it is under completed components. So we've got some state variables. We have what slide we're on, managing that with react-use-state. We've got a full-screen mode.

So that is that state that I can hinge off of how I want to make this work in a screen reader. I've got some logic here to increment or decrement the slides in either direction. Our buttons can do that. They call a function to change the current slide index.

Here's some code to enter full screen. So when I enter full screen mode, when the user clicks that button, I can send focus into the slideshow content. And here's that ref again, another ref. So the slideshow ref is on the container with the images in it. So I'm sending you directly to that element.

And it has a time index of -1, to just make sure that we can catch that focus event. The way that those images were actually announcing was that it hasn't already a live attribute of polite on it. So whenever the content changes, it was announcing that to you.

It has this aria-role description of image slide show. So you can't make up roles, you can't can use aria-role description and you can put whatever you want in there. So if this is like a special type of element, because this one I'm switching between a role of application in full full screen mode, or a roll of region, which is a little bit better than a dev.

It actually is a sectioning element, we can label, but it's not super descriptive. So I opted to put aria-role description on here to say this widget, this custom widget is an image slide show. I could put a label that says that I opted to use aria-role description. And so this application mode is what is allowing me to actually go through those images.

Because if you're not in the right mode, if my focus is on a div, I'm not on an input or a button. I'm gonna be in browse mode, so those arrow keys are not actually going. It's not gonna pass that through to the browser. It's going to try and navigate me through the content.

And so the way that that slideshow was actually working is that application mode, but I don't want to leave it on all the time. So I toggle it. So let's see what else? We have a button like a reachable operable button to close full screen mode. We also have a way to escape.

So we come up here, we've got a key handler, it handles multiple things. So it's got the close on escape. We've got arrow right and arrow left, or arrow right and arrow down, increment and arrow left and arrow up, we're gonna decrement the slideshow. But without the application role that I wish I could show you a little bit better.

That just wouldn't work. We would just get stuck cuz we're in browse mode, right? So I can kick the user automatically into focus mode, but the application role, but I'm being very selective with it to be, I don't know, careful [LAUGH]. So let's see, what else were there gems do we find in here?

So each image, we're iterating over a list of images here. That's the the slideshow content and each image is marked up as a figure. It has an aria labeled by of the image, let's see the image alt text and it has extra text for a caption. So there's alt text and a caption.

The alt text is more specific, like what's in the image. The caption is more of a description of it, almost marketing copy. So they're slightly different. So I included them both, and I used the figure to announce what are you saying? So you could kinda hear both pieces of content for each image.

And so, that uses figure and fig caption, the regular image tag. There's also a counter in there. So anytime this content is changing, the screen reader is picking it up and reading it aloud. That's what that aria-live was doing. And then we have our previous and next buttons.

I think the original version, these were divs or they didn't have labels on them. And then our dots at the bottom. I can't tell you how many slideshows I've seen where the dots to control it are just little divs that have click events on them. So those should be accessible too.

And these are buttons. They're for their labels. It says, go to slide, and then I'm using the same iterable over the map of images. It's like an array of objects, I think. So I can count those and use that same way of mapping over an array of objects to give these little dot buttons unique names.

So we've got our button. So let's focus into it. See if it works in a Mac environment. I don't know how I'm missing. This is the inaccessible version. [LAUGH] I'm like, why can't I click on this? This version locally is the one that's not accessible at all, that you have to click on everything.

The version that we saw in NVDA works better. We can actually reach-
>> Image slideshow.
>> We can go into it.
>> One to five Sun streaks through the clouds at a beach on the Oahu North Shore.
>> So it just announces everything.
>> Like in shark's Cove button go.

>> And that use a combination of factors, so aria-live. Changing the content and side of there, yeah, we went over that. So any questions on this one? I know there's a lot of stuff going on with this slideshow.
>> Would the aria-role description work on web components so I can custom describe all my components?

>> Potentially yep, I think it's a good tool to reach for. I would say, check the aria specification for what it taught, like read up on it. [LAUGH] Read the requirements for it first, and then yeah, see if it can work for your use cases.
>> Another question.

If in your example the images were delayed content, imagination, etc. What would be the loading skeleton for the screen reader?
>> Good question. So if you're dynamically loading content that takes a second, you're fetching asynchronous data maybe. You could have a loading state that, if it has a loading spinner on it, you could put an aria-live region on the loading spinner that says loading.

And that way the screen reader user will be notified that there's content loading. It would be nice if you could centralize that in your code base somehow, because if you had a bunch of components all loading asynchronously, it would be like loading, loading, loading. So you kind of need announcement manager almost like loading somehow.

One per page I guess would be probably ideal because a bunch of loading announcements might be kind of annoying. But that's a great question about skeleton loaders with performance if we can announce that something's loading, that'd be awesome. I've seen on airline sites when they'll have a loading page, they'll send focus to the loader that will announce it if it has alt text on it.

And then it'll load and go to the next page or the next view. So there's various techniques, but it is great call out that we should announce that stuff is loading.
>> For the [INAUDIBLE]
>> MVDA. Ask for a license to parallels or something, because MVDA itself is free.

And I know for a lot of developers, we don't have Windows machines necessarily, but you can get a VM. There is also this thing called Assistive Labs that you can use to test in the cloud. So that could be a service you could look into. I haven't really worked with it myself, but I know a lot of people really love it.

And so it could be a good option for your team.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now