Check out a free preview of the full Enterprise Web App Accessibility (feat. React) course:
The "Visibility Methods" 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 various visibility methods in CSS. They cover techniques such as visually hidden or screen reader only classes, display none, visibility hidden, opacity, ARIA hidden, and the hidden attribute. The instructor explains how each method works, their effects on the rendered output, and potential use cases and pitfalls to watch out for. They also demonstrate how to inspect and test these visibility methods using Chrome Dev Tools and a screen reader.

Get Unlimited Access Now

Transcript from the "Visibility Methods" Lesson

[00:00:00]
>> All right, so visibility methods, there's a ton of ways to hide and show content. And I want you to know all of these techniques, because when you're debugging something, evaluating something, sometimes the CSS is what causes the issue. Or yeah, if you change the CSS slightly to another method, it might have a better outcome.

[00:00:21] So starting with the visually-hidden or screen reader-only CSS classes, sometimes sr-only, that's the one in Tailwind. Those are utility classes, I have them in every project I work on. And what they do, here's an example of the sr-only from Tailwind. They use absolute positioning, kind of clipping the content, overflow hidden, basically making it rendered.

[00:00:49] So it's in the rendered output, but you can't see it. And so this can be something to, if you have screen reader text in a button or an extra heading that's not part of the design, but you wanna add to the heading structure, you could use these classes.

[00:01:05] And so in our slides, we have some examples. So I've got sr-only on. I can turn it on and off, and we can see what it does to the content. So there's a button, I can toggle it. There's some content right after the piece that's updating, so you can see that it collapses the space.

[00:01:22] So it doesn't take up space. And when one of this is on, I can inspect it in Chrome DevTools. So under the Elements Inspector over here on the right where it says, Styles Computed, there's a little arrow. You can go to Accessibility and we can inspect what's the effect of these styles.

[00:01:42] So for sr-only, this has the sr-only class on it, and I can see in the styles panel that it is matching that CSS. When that is turned on, I can still see the content inside of here. So it says, widget content with a link in it. And if I try to tab, I should be going right past that content, or actually I'm not.

[00:02:10] That's something you wanna watch out for and why I put a link inside of the sr-only content so you can see what happens to a focusable elements. So with sr-only alone, it's not gonna keep me from tabbing onto interactive elements inside, so I have to handle those. I have to put probably tabindex of -1 on that, or display: none or something, I have to think about that.

[00:02:34] So that's sr-only. Display: none, this is the biggest hammer. This is a good tool to have in your toolbox, cuz it hide stuff from everybody. So for display: none, which its counterparts would be display: block, flex, or grid, inline block, table, there's a bunch of different display properties.

[00:02:55] I love them, they're awesome, especially grid and Flexbox. But when I turn on display: none, it's funny, I called it display: block, it should be display: none, it collapses the space, And when I inspect that content, it's got display: none for everybody and it is hidden from everybody.

[00:03:17] So the screen reader-only one, I can still see the information in the susceptibility tree, which we're gonna talk about in a little bit. But here's a little preview for you. When something has display: none on it, it's not rendered for anybody. I can't reach any of the links, or inputs, or anything inside, so it's very helpful.

[00:03:35] But it has no display, it's gone, it's hidden, that's what we wanted. You can't animate display: none directly, but you can kind of show it or hide it at the end of a keyframe animation. So some of these are animatable properties, some are not. Visibility: hidden is another one.

[00:03:57] I don't think this one's animatable either, but like display: none, it will hide something visually, it reserves the space. So that's different than display: none. So sometimes visibility: hidden is what you want so that your layouts don't get messed up. But something with visibility: hidden, if we go and inspect, let me get to it.

[00:04:23] Where am I? Here we go, so in Tailwind, that class is invisible. It puts on the CSS property of visibility: hidden. And when I go over to the Accessibility Inspector, it is ignored. So it's kind of like display: none, but it collapses the space, or sorry, reserves the space.

[00:04:42] So slightly different technique, which you have all these different tools in your toolbox. This one's helpful in select cases. So here's another one, opacity, this one is animatable. You can go from 0 to 1 and you can transition it, you can do all kinds of things. So opacity: 0, this one also reserves the space.

[00:05:10] Unlike visibility: hidden and display: none, I can tab onto items inside. So it's not gonna render any links inert inside or anything. So if you're using this to hide stuff, be aware that you're still gonna be able to reach focusable items inside without doing something extra. For this one, if I go to this opacity, I can see it has opacity: 0 and it is rendered.

[00:05:38] So I've got the information over here still. So a screen reader user will be able to interact with this content, reach this content, but you can't see it. So maybe it's just a transition thing going in and out, stuff's still reachable, it's still announced, unlike display: none or visibility: hidden.

[00:06:00] Aria-hidden, which is not actually CSS, but it is a visibility method for screen readers and assistive technologies. This is an attribute that you can put in your HTML with true or false, and it will mark that group of content, that subtree, it will tell a screen reader to ignore it.

[00:06:21] It will not affect anything focusable inside, kind of sr-only, except sr-only will keep something in the accessibility tree for a screen reader, aria-hidden will remove it. So the risk with this one, and why I'm telling you about it, is that anything focusable inside of here will have its accessibility information stripped away and it won't affect the display.

[00:06:44] So aria-only affects screen readers, it doesn't affect keyboard events, it doesn't affect the CSS or the display. You could use CSS attribute selectors and target it if you wanted to style it. But on its own, aria doesn't do anything that you'll be able to see. It is only gonna be effective in screen readers, which is why it's really, I don't know, full pitfalls.

[00:07:09] Cuz people are like, I'm gonna slap this on here and then you never test it. And it can be worse than if you didn't include it, but it can be an effective tool when used in the right circumstance. So if we go on and inspect this one, we can already see we can see it, we can focus on it.

[00:07:33] Element, okay, has already hidden true on it. When it's not present, it's the same as aria-hidden false, so it's ignored. We can see element is aria-hidden, it's not exposed, but it had that link inside. So I have to probably put tabindex and -1 on that link and any other element in there.

[00:07:53] There is something really helpful to know about and it's the inert attribute, it we'll do both of those things. It's the aria-hidden and the tabindex, and we dove pretty deep into that in the web app accessibility workshop. So if you're interested in that, we did a whole exercise of how to work with inert, especially in React, which is a little bit tricky right now.

[00:08:14] But talk about another spidey-sense thing, if you see aria-hidden true, it should be like, there's something I need to watch here. Are there focusable elements inside when it's aria-hidden true? That could be a problem, and AXE will actually flag that for you now. So it will help you identify these, cuz I mean, who really is gonna catch this with their own eyeballs?

[00:08:37] So it's helpful when the computer can point it out to us. I love that rule. So our last one is the hidden attribute. Yeah, question?
>> A quick question, Marcy. What instances would you actually want to use aria-hidden on? Because the impression I've gotten is basically try to avoid it.

[00:08:58]
>> Yeah, well, I think when you're doing modals, it is a component of making the background inert. But by itself, that's why I like the inert attribute and a polyfill is that it will handle all of the tabindex for you. The polyfill will actually block the DOM, go change all the tabindexes, tabindexes, and then when you take the inert attribute off, the DOM walker will go back up and reset everything.

[00:09:26] And I've had to write that myself, I did it in Angular, it is a pain. And it's also really hard to do, if you're trying to say your modal is buried in the DOM somewhere, you need a clear path up to the body to be able to set your siblings as inert.

[00:09:44] Otherwise, there's kinda no way to do it. So you always want your modals, the use case for aria-hidden and inert is easiest when your modal is a sibling to the content that you're gonna hide. So aria-hidden and tabindex kind of together are useful, but inert is just so much easier, it's less work.

[00:10:05] [LAUGH] But if you see this, yeah, I mostly want you to be aware of the pitfalls. Question?
>> In chat, someone said, aria-hidden is great to hide the presence of icons.
>> Yeah, that's a good point. Yeah, so say you've got a link that has screen reader-only text in it, but it also has an icon, you could put aria-hidden of true on the icon element.

[00:10:30] And it can suppress special characters and things in a screen reader as long as you're replacing it with something that can be super useful. What I see is people will put it in codebases for some reason and then they just don't replace it with anything. We have an example in a minute that you'll see was inspired by a real-life thing and it just kinda gets slapped on stuff without thinking about it.

[00:10:56] So watch out for it. And now you know what it does, so you can be more informed we probably just don't even need that. Test it in a screen reader. I think icons, that is a good use case cuz it's kinda limited in scope. And as long as the icons, there's some way to understand what the interface is doing.

[00:11:17] If it's in an icon button, if you have other text in it, then aria-hidden is fine on the icon. That's a great call out, thank you.