skip to content

Better Screenreader Experiences with CSS

After an introduction to how we can navigate with screenreaders, Ben Myers will teach us how we can use CSS to influence what screenreaders will announce.

Full Transcript

Click to toggle the visibility of the transcript

Captions provided by White Coat Captioning ( Communication Access Realtime Translation (CART) is provided in order to facilitate communication accessibility and may not be a totally verbatim record of the proceedings.

JASON: Hello, everyone. And welcome to another episode of Learn with Jason! Today on the show we're bringing in Ben Myers. Ben, thank you so much for being here. How are you?

BEN: Howdy. Doing well. I'm super-excited about this. Always excited to talk about accessibility. I'm a big fan of the show. Two things I like very much.

JASON: Yeah. And you are a fellow streamer. You stream at SomeAnticsDev. I'll shout that out. You stream under SomeAntics?

BEN: Yes. Because someone took semantics. Always a pain point. It's a weekly stream, Tuesdays, 12 to 1 central where I usually focus on accessibility and other aspects of core web technologies. Less cutting edge Jamstacky stuff and mostly the basics of getting an accessible site out there.

JASON: Cool. For folks not familiar with you outside of your blog. Do you want to talk about your background?

BEN: Absolutely. Hi, I'm Ben. I'm a frontend developer at USAA, working on the bank side. And I'm a big accessibility advocate inside and outside of work. I blog about accessibility, we talked about the SomAntics stream. You'll find me excited around where all the accessibility stuff is, you'll find me there. Yeah. That's basically me.

JASON: Very cool.

BEN: If there's accessibility stuff, it's the Bat signal for me.

JASON: I like that. Let's talk a little bit about, specifically today, we're gonna try to tackle something that I'll be honest, kind of surprised me. Which is you said that we're gonna learn how we can use CSS to improve screenreader experiences. And, this surprised me for a couple reasons, and I'm gonna assume, well, actually, I'm going to caveat this by say, I'm pretty sure it's because I've made some incorrect assumptions here. The assumption that I had made is that CSS doesn't affect screenreaders because CSS is visual. And I think I'm wrong.

BEN: I -- so, you're walking into exactly the same assumptions I made. And so, part of what we're going to get to later, I'm going to show you some demos that flipped that mental model that I have, that you had, and warped it beyond recognition. Just absolutely shattered. But, yeah. I know that many people come to web development through many different paths. I -- the first time I really started learning it, I took a class in college that focused on HTML, CSS and JavaScript with a helping of jQuery. Not that jQuery was even relevant then, as, like, I don't know. It was starting to be on its way out. But when I was going through that, like I took -- I took this class, and one of the things they hammered home is this theme of like separation of content and presentation. That was the big thing with HTML5. Take out tags like center. That was presentational. You can think of HTML as your content, and structure and semantics. It's the foundation of all of this. Then there's your CSS which can be the presentation. And never the twain shall meet.

JASON: Never!

BEN: Never, right if and then you get into accessibility and you start playing around with screenreaders. Which by the way, that word is murder for me to pronounce. I'm an accessibility advocate, and I cannot say screenreaders to save my life. But all screenreaders are purely content and semantics. Thank you Ximena.

JASON: Thank you.

BEN: With CSS, it's pure presentation, and screenreaders only care about the content. They should never meet. That's why this is surprising and I'm excited to dive into this today.

JASON: Yeah. Okay. So, just thinking about it from the standpoint of like, what are the parts of CSS that affect screenreaders? So, I have a couple theories off the bat. The first one is I think the display property is gonna affect a screenreader. So, if I set it to display none, it won't get read.

BEN: Yes. And that's actually the first thing we're gonna see. Because it's led to some accessibility work arounds. We will see the visual utility class. That's one of them. We're gonna see that -- it's all precipitate the on this notion that like CSS sometimes is content. As much as we say otherwise, CSS is content sometimes. And as such, it impacts sighted users' experiences of what the content even is, and it also impacts screenreader users of what the content is.

JASON: Oh, yeah.

BEN: Yeah. And also, before we dive into that, like we're gonna like -- I just kind of this caveat of like everything that we see today is not a bug. Everything that we see today is totally intentional. Even if it's unintuitive to developers such as us. So, yeah. That's kind of what to look forward to is when CSS impacts content in some way, how does that, in turn, impact the screenreader experience?

JASON: Sure. Okay. All right. Well, I think instead of talking about it in the abstract, maybe we should just start looking at some code. Why don't we go ahead and flip over to the pair programming view. We will start by doing a quick shoutout. This episode, like all episodes, we have Amanda here today writing down the junk I say and the smart things Ben says. There's through White Coat Captioning, made possible through Netlify, Fauna, Auth0 and Hasura. Making this show more accessible to more people. Which is important to me. And make sure you go follow Ben on the Tweeter. Do a little Tweet, Tweet, get those things going. And as we mentioned already, you can find Ben on Twitch as well as SomeAnticsDev. Ben, if we want to get started here, kind of what's our first step? How do we even get a frame of reference for what we're trying to do?

BEN: Absolutely. I realize that going in guns a blazing, saying, hey, CSS can impact your screenreader experience is going to be terrifying, frankly. Horrifying, especially if you aren't familiar with screenreaders. I thought we could spend some time playing around with screenreaders, getting familiarity with the basic experience that we might expect for them. How we can navigate using screenreaders and then we can dive into how we can actually change the experience using CSS.

JASON: Nice.

BEN: You're on a Mac, so, we'll be using VoiceOver today.


BEN: And while VoiceOver is the screenreader I'm most familiar with as well, even if every screenreader has different shortcuts, everything here is broadly transferable between different screenreaders. Whether you're using VoiceOver or JAWS, Orca, is that one?

JASON: Three truths and a lie is what we're playing right new.

BEN: Right? Man, you always wonder how they decide to name the screenreaders. VoiceOver, talkback. JAWS, seems you're a little into the shark aesthetic, perhaps. So, yeah, so, we're gonna use VoiceOver today. And I want to walk you through some of the basic interaction modes using VoiceOver. And before I do, before I show you how to start VoiceOver, I would like to tell you how to turn off VoiceOver. I would like to give you an escape hatch.

JASON: [Laughing]

BEN: I have introduced enough people to screenreaders, the moment their computer starts yammering at them. It's like, oh, god, panic, panic, yammer, yammer, how do I turn this off? I like to give escape hatches. VoiceOver has a dialogue box that reads aloud. In the top left corner, you have a small white X. It looks decorative. It's not actually decorative. It's a turn off button. That's the easiest way I've found to turn it off. And yeah, there is an option to pause the announcement at any moment, which is control. So, these two keys.

JASON: Okay.

BEN: These two things are our escape hatch.

JASON: Okay.

BEN: So, yeah. Let's go ahead and now I guess turn on VoiceOver. There's several ways to do this. The one that I find most memorable is going into your accessibility settings. I usually open up the Spotlight and search for accessibility.

JASON: Can I move this over? There it is. I'm going to go to accessibility.

BEN: There's an option on the left called VoiceOver. There's check box. You're gonna turn this on. And because you're stream, it's gonna take a while to think. I've learned this. It takes a while whenever you're streaming. At some point, it's going yell at us.

JASON: And thank you, Prismic for the raid. I hope you had a good stream. And he just figured out that SomeAntics is a pun of semantics.

BEN: This is one of those things, I'm a pun-driven developer. The moment I come up with a punny name for something. That has to become reality. I came up with the same SomeAntics before streaming. I need to do something with this, I guess I'll start streaming?

JASON: Kindred spirit.

Accessibility features, VoiceOver, selected, keyboard focus. You are currently on a table, press control, option, shift, down Arkansas row.

BEN: Left to its own devices, it's going to just talk. You need to be quick on the control trigger to get it to pause because otherwise you can't hear either of us. So, all right. We've turned on VoiceOver. You can see that there's a small little X in the top left.

JASON: This is my escape hatch.

BEN: That's your panic button, yes. That's your escape hatch. Now that we've got that, we're going to go ahead and -- we're going to peruse the Learn with Jason site.

Learn with Jason, learn something new in 90 minutes. Microsoft Edge --

BEN: There we go. That was control. There we go. All right. The first thing to show off is going to be fairly straightforward and intuitive for most developers. Which is that we are very used to tabbing. This is something that is like, many of us are power users of technology. Tabbing is something we're used to. So, tabbing will take you from interactive element to interactive element. These are usually links, buttons and form fields. There's probably other exceptions, but those are the main things. You can tab forward using tab.

Learn with Jason --

JASON: Wait, where am I going? Where am I leaving to, computer?

BEN: But it is -- so, it was, I believe, actually on the tab, like the browser tab.

JASON: Oh! Okay.

BEN: One of the things I find helpful is just to prime VoiceOver by clicking in the browser window. Which is a little cheating, perhaps. But it's quicker, it's easier.

Link, link, about, navigation, Microsoft Edge has a new window. You are currently on a link. Socket studio. Black --

JASON: Oh! Oh, it's reading my chat.

BEN: Oh!

JASON: That's gonna be fun. Okay.

BEN: Oh, is it -- oh, man. Yeah. Wow, that's a fun one. That's a fun one. Okay. We -- yeah. So, if you just kind of tab through a couple times, we'll see some interactive stuff.

Learn with Jason on Twitch, visited link, Jason YouTube, Learn with Jason on Twitter. You are currently on a link -- link -- you are currently on a link.

JASON: Oh, it's reading this.

BEN: Yes.

On a link inside of a frame. You are --

JASON: Oh, no. I did a bad, look.

BEN: No, you highlighted the text inside -- you're good.

JASON: Okay.

You are currently on a link.

JASON: Okay. All right. So, it's doing things, it's showing me what's going on. And that one was actually useful. Which that makes me feel better.

BEN: Yeah. It's -- yeah, it's fun stuff. So, tabbing is very intuitive for us as developers. This is, you know, oftentimes how we navigate the web. However, it is like the least-commonly used navigation mode for assistive technologies.

JASON: Okay.

BEN: Because it's really only for the interactive stuff. Only for links, buttons and other stuff. You notice, we completely skipped over the text, learn from brilliant teachers, live captioning by, et cetera. We skipped over anything static. We would have skipped over any images that aren't inside links. Stuff like that, right? So, if tabbing were the only mechanism that we had, we would miss out on a lot of content.

JASON: Right.

BEN: Like I highlight this because I sometimes introduce people to screenreaders and they come back a few months later and they have been like, so, panic. We can't get to any of our paragraphs. We're trying to tab to it. And we can't get to any of them.

JASON: Oh, yeah. You know what? That's a good thing -- like I hadn't really considered that. But I would have done that. That absolutely would have been me.

BEN: Yeah. And because of the mental models that we built up on this. We build up this notion of, oh, keyboard navigation means hitting the tab button, right? If we can't get to something, we assume something must be broken. And not we're using an inaccurate navigation mode.

JASON: Sure.

BEN: So, tabbing is useful, but it's not the only way to navigate. And in fact, we're going to want to also get our static content. Like that's especially important on like a blog post, right? Where, you know, there's very few links and very much text. So, the -- if tabbing is the first navigation mode in screenreaders, the second one is going to be what we call the virtual cursor. And this is gonna take you to everything. Would you mind clicking in -- for instance, where it says interactive SVG animations. Yeah, click that. I did not realize that was a link.

Microsoft Edge has a new window.

JASON: What new window do you have? You don't have a new window.

BEN: You went to a new page.

JASON: Oh! That's what that means. Okay.

BEN: You're good. This, we're going to use the virtual cursor.

JASON: Okay.

BEN: To do this, you're going need to use three keys at once. I hope your keyboard hands are ready. And these are -- you're going hold down control and option can then you're going to use the left and right arrow keys.

Interactive SVG animations --

BEN: Okay. So, sometimes I find it helpful to click somewhere in the window and that usually gets me on the level.

Interactive SVG animations --

BEN: Try tabbing.

Using Greensock selected. You are currently on heading level 1.

JASON: Okay. And so, now --

BEN: Now we should be --

Cassy Evans, interactive whimsy and -- to our websites. In this episode, Cassy Evans will teach us how to use Greensock --

JASON: That's great. Microsoft Edge, you got a lot of new windows. Call on down.

BEN: Who knows. Microsoft Edge does as Microsoft Edge does. And so, this virtual cursor that we've seen here, this takes us to everything, static element, dynamic elements, stuff like that. You could keep going. You could go to the demo link.

Demo, visited link, visited code. Resources and links. List 12 items. You are currently in a list.

BEN: We're in a list. Let's navigate through the list. It tells us how many elements are in the list. That's relevant later. You're in a list, 12 items in the list. Control option right.

JASON: Oh, need to make my links better.

BEN: That would be helpful in this case because that is a very long link. If you keep going and linger on a link long enough, it should tell you which list item you're on. So, it will say one of 12.

JASON: Let's see if we can find one that's a little shorter.

Link [reading link] 3 of 12.

JASON: 3 of 12.

You are currently on a link. To click this link, press control option.

BEN: Using the virtual cursor, this is the super power of screenreaders. This is how you get to all the things. But super-manual. Right? You're having to click a whole bunch. That's whole bunch of nodes and stuff in there, it can be a bit of a hassle. What if we just want to, you know, start reading and just have it be automatically reading from there? Well, for this, we're going to use continuous reading mode.

JASON: Okay.

BEN: Before we do this, remember that your escape hatch is hitting control.

Learn with Jason --

JASON: Or maybe the about page.

Loading about learn with Jason. Web content. You are currently on -- how it works, selected. You are currently heading level 2.

BEN: There we go. To activate continuous reading mode, do control option A.

Heading level two, how it works. Twice a week we get a live lesson from an expert and follow along as Jason -- something completely different in 90 minutes or less. We start from scratch --

JASON: This is fun. I like this. I notice it's calling out some markup like a link, but it's skipping like an emphasis tag.

BEN: Yes. So, they're -- when you're in continuous reading mode, the idea is you're trying to get through the content as fast as possible. Your screenreader will remove a lot of the more crust Jiya explanations of things because it's trying to get you through the content as fast as it can.

JASON: Yeah.

BEN: Also worth calling out that most screenreader users who use it full-time. So, like most blind people or low vision people, or even many dyslexic people who use screenreaders will have it go much faster than today.

JASON: Yeah, if you want to see that -- let's --

You are currently on a text field. VoiceOver off.

JASON: Just for a minute. Let's go find Leonie Watson. She's an incredible speaker and she does a lot of stuff with -- let's see. Does she have talks? Get a talk where -- oh. No, are they gone? Oh, no. Okay. So, let's -- let's go to YouTube and we'll find a Leonie Watson talk. When she runs her screenreader, it is the fastest thing I have ever seen.

BEN: Yes.

JASON: So, I'm trying to remember which one. A voice of its own? Is this going to be a screenshot? Or a screenreader? �

Loop. So, we've had a complete -- �

JASON: I'm going to assume that this is one so that we don't spend the whole time watching one of our talks. While it would be a great use of our time to watch a Leonie Watson talk, check out her stuff. First of all, she's a brilliant speaker, and you will learn a lot. And second of all, you will see how somebody who actually uses screenreaders uses screenreaders. That's how she navigates. It is very different from what I'm doing by futzing around today.

VoiceOver on system preferences, accessibility, window, accessibility features.

BEN: We killed Chrome. We killed Edge.

Microsoft Edge, how it work, selected.

JASON: How it work!

BEN: So, you know, just as you use control option right arrow to go forward with the virtual cursor, you can use control option left arrow to go backwards.

JASON: Great.

BEN: There's still more we can do. And I would love to introduce you to a power user part of the screenreaders. One thing that doesn't come up in test, but it's fantastic. So, every screenreader -- I told you I couldn't say it. Every screenreader provides a didn't way to navigate between elements of the same type. So, go from links to links to links or buttons to buttons, or headings to headings or tables to tables.

JASON: And headings is really the thing I'm interested in here. I can imagine if I'm on a page, the way that I read content as a sighted user is I skim headings and find the one I'm interested in and read that content.

BEN: Yes. Yeah. But if you're using a screenreader and you're using like the virtual cursor, you don't have that skimming option with the virtual cursor. You have to get through the all the content to decide if this is the content you care about. Headings in particular, this is huge. So, if you're using JAWS. They have a whole bunch of keyboard shortcuts that you have to remember. I don't remember them. But I really love how VoiceOver implement this is. Which is a feature called the rotor. You can now thumb up and down with your arrow keys.

JASON: Skip to content, visited link, home. Visited link, episodes, visited -- visited link, Jason. Watch live on Twitch.

BEN: When you find a link you want, you can hit enter and now you'll be focused on that.

JASON: Okay. Let's go --

Link, link, visited link. Visited link. Source code.

JASON: It popped right up.

You are on a link.

BEN: All right. But, you know, that was just links. There's other rotor menus. Open up, control option U, and now use the left and right arrow keys.

Headings menu.

BEN: There we go. Look at this.

Heading level 1, about Learn with Jason.

JASON: Nice.

BEN: You know a thing or two about the markup you have written for the site, what do you notice about the headings here?

JASON: It's showing me level two, the importance. That's the name of the page. Now I have the section, two items in that section. That's cool.

How it works. Heading 2, two items, stay up to date!

BEN: So, we talk about how headings -- your H1 through 6 tags, how they form kind of a document outline for assistive technology users. That's how. We just saw that in action. That's what it's doing. That's what it's exposing there. And that's really neat. I love the rotor. It's a super-cool feature and one you have to validate for. Because it introduces new levels of complexity. For instance, question just saw how with the links menu, all of our links were taken out of context.

JASON: Yes, this is actually --

Heading menu, links menu.

JASON: This is where I see why you wouldn't want to link here. Or this.

BEN: Yes.

JASON: Because it doesn't make any sense.

BEN: Click here, or read more. Yeah, those links can totally be taken out of context. It is a totally valid navigation experience to hop directly to a link without seeing any of its surrounding text.


JASON: Actually, let's go to the blog.

Visited link, blog.

JASON: And I can --

Visited link, visited link, blog.

JASON: Oh, I need to actually click. I do.

You are currently -- loading -- learn with -- learn something new -- links menu, link -- heading level two. Use promise.all -- use -- slash wait, links menu, headings menu. You are currently in a VoiceOver menu. To navigate, closing links menu. Use promise.links menu. You are currently in a VoiceOver menu. This is a list of options.

JASON: I can okay.

BEN: You did all right.

JASON: I was worried there would be a lot of this and here. But I can see why this is important, right? You know, this is -- but also, I'm seeing how that doesn't really make sense as a link.

BEN: Well, I mean, yeah, but also it maybe could, right? Because I presume if I click -- I think you were focusing on the like promise one or whatever. I can presume I would learn more about promises there.

JASON: Sure.

BEN: Where this matters is on your home page, you have a whole bunch of links that are episodes, resources and transcripts, right? That means that your home page, if you don't provide any other context, is just a wall of --

Microsoft Edge has a new window.

BEN: A wall of identical links, right? Or maybe it's like your schedule link or something like that. But, yeah. So,

JASON: Oh, you're right. It does. Wait, did I make this better?

Loading complete.

JASON: Did you fix this for me?

BEN: I might have fixed that for you, yes.

JASON: Let's look at this and see what's wrong. Episode details, episode details, this is not great. This would be super unintuitive. But because Ben took pity on me and opened a pull request. Look at it!

Episode details for better screenreader experiences with CSS.

JASON: Ben opened a PR that added extra details so that there is an actual set up here. You can see what these links are despite the fact that visually they're not there. What did button did I just push?

BEN: I don't know,

VoiceOver off.

JASON: And so, I'm gonna look at the source on this real quick. Because I forget how you did it.

BEN: I either did that with hidden text or ARIA labels. Let's find out. I did it with hidden text. There's hidden text with the name of the episode in there. It's a dream come true, Jason, we're getting drowned.

JASON: Welcome, Cassidy, I see you are here. How to do which piece? The hidden text or the --

BEN: Yeah, the idea is it's all done with the markup. So, the link, it has a node that's the details, then it has an extra node in there. But hidden from sighted users. But not hidden from screenreader users. Such as for and then the episode title. That's how I added extra content to your links so that every link would actually be unique, like be very clear about the -- god, we're getting so drowned.

JASON: This is going to prove that the screenreader is usable.

BEN: This is the test. If the screenreader works, we can be drowned in boops all the you need because you will get the equivalent experience.

JASON: Head over here. All right, you're busy.


JASON: All right, VoiceOver, I'll come back later.

Links, menu, visited link. Headings menu. Heading level 3, better screenreader experiences with CSS. Heading level 3, JavaScript level complete. PRs --

BEN: Excellent. Yeah.

GitHub Actions -- what's new in -- Brian Douglas will teach us all about fine -- GitHub magistrate --

BEN: All right.

Forked PRS.

JASON: We did it! We did it! We just navigated a page, couldn't see a dang thing. I was under water in boops the whole time.

BEN: Yeah, the whole time. We saw different ways to navigate with the screenreader. We could tab to get to the interactive stuff. If it's interactive with the mouse, it could be interactive with the keyboard. Little tip there. We were able to tab. We were able to manipulate the virtual cursor and start continuous reading so we didn't have to have the cursor. And go from element to element using the rotor. Those are the main navigation nodes I use doing screenreader testing.

JASON: Yeah. It's outstanding. Like I can see how -- I didn't feel like I wasn't able to do anything. And there's a bunch of stuff that I don't know how to do because I don't know the tool. But, you know, I can see when you watch somebody like Leonie Watson, she's using that screenreader faster than I use my eyes. She's so fast at navigating everything. She's so, so fast. It's not like a different version of the web, it's the same web, just presented in a different way.

BEN: Absolutely. Cool. So, yeah, that is -- that is the just general friendly introduction to screenreaders. We saw the different navigation modes. Jason, if you don't mind, I would like to do some hijinks.

JASON: I'm so ready for hijinks.

BEN: Let's do it. Let's do some hijinks.

JASON: Somebody clip that. I need that to be a sound effect. I would like to do some hijinks. That's so good.

BEN: All right. So, if we're looking down and to the left of me, you can see the title of this episode is better screenreaders with CSS. Thus far we have not done CSS. Let's go ahead and do CSS. We talked a bit about our mental models. Yeah, kill voiceover. It's going to be a hassle in VSCode. So, we have talked about our mental models and intuitions that doesn't seem like CSS doesn't seem like it would be able to impact assistive technology or screenreaders. But I want to show you the like, I've got a few demos that actually broke my understanding of --

JASON: Yes, let's do it.

BEN: Yeah. So, I gave you some code to do. And we've got a few pages. 3 HTML pages. Shoutout to Stephanie in the chat. I first demoed these demos on her stream a couple weeks ago and I'm super-grateful for that. Yeah.

JASON: Let's get this one.

BEN: All right.

JASON: Let's install the dependencies and then we'll open this thing right up.

BEN: Right. And for people who are unfamiliar with this repo. I straight up cloned a base that Jason used a long time ago for a lot of sites. I wanted to get something quick up and running. Just because I wanted something that looked basically nice, but wasn't overly styled already just so that we could verify the stuff that we're doing has impact.

JASON: Yes. We'll do that later.

BEN: There should be three HTML files.

JASON: Okay.

BEN: All right. And maybe go ahead and pull up in the browser, that first one, the 1-hiding.

JASON: Okay. We'll run ntl Dev to start it. That's how I avoid having to remember how to start different frameworks.

BEN: Happen of my projects are npm run Dev, and half are npm start. This gets me every time. I can't remember whether I'm in an npm run Dev or npm start project.

JASON: Yeah. I know. Where am I?

BEN: It's Eleventy and going directly into a directory.


BEN: it's 1-hiding, HTML. Had to put in Eleventy. This is not the most-styled page, but it's got some stuff. This is the table here. This is real data by the way. Comes from WebAIM, screenreader survey. I highly recommend reading through this. The new one, the results are supposed to come out later in the fall.

JASON: Nice.

BEN: Yes, Stephanie, I did say Eleventy. So, yeah, this is real data. But we can see that we've got a table here. And this table has some columns and lows as tables do. And oh, we're gonna get to that, don't worry. So, yeah. So, if you inspect the markup for this table, I put this directly into that HTML file in the Eleventy project. We'll see a few things.

JASON: Okay. So, I am inspecting -- here's the HTML.

BEN: So, I'm using like the full range of semantic markup provided to us by tables, by HTML for tables. So, we've got our table head, we've got a table row with table head -- like TH header cells, stuff like that. I actually want to highlight this caption up here. Because this is a thing that's often missed with tables is that you can use the caption element. If the caption is the first child of a table, then it provides like an accessible label for the table. So, when the use navigates into the table, they'll be told, you know, this table is whatever is inside your caption.

JASON: Got it.

BEN: As we navigate in VoiceOver, which we will see shortly, we can be told it's the comfort with screen reader detection table. Maybe we can play around with VoiceOver. We haven't done tables yet.

JASON: Yeah, let's do it. I'm going get back in here. Are you going to tell me you're busy again?

Microsoft Edge busy. VoiceOver loading web content. Demo, Learn with Jason, web content. You are currently -- tool bar, tab -- demo of the demo, Learn with Jason. Item was removed -- link. Screenreader users. Screenreader survey --

JASON: Oh, god, okay. Let's go into the --

BEN: Okay.

Landmarks menu. You are currently -- articles menu.

JASON: Oh, god, what have I done?

BEN: I'm just letting you have fun here.

Visited link, visited link, screenreader users --

JASON: Tell me what to do. I got lost.

BEN: Let's go ahead and scroll to the top and let's just select a bit of our header up at the top just so that we can be like before the table.

How comfortable would you be --

BEN: All right. And here we're just going to use our virtual cursor. Because tables are static elements. We're going to control option right arrow.

JASON: And so, we can see it was going to say table 3, column, 6 rows.

BEN: And just keep going through the virtual cursor.

Response, column one of three. You are currently on a text element inside of a cell.

BEN: Here's a fun one now. Because we're in a table and it knows this is a table. We get two dimensional navigation. You can use the virtual cursor, up, down, left, right. And it will go through the table.


Row two of six, very comfortable. You are currently on a text element inside of a cell. Percent of respondents, 39.2% -- number of --

JASON: It pulled in the header.

BEN: Yeah.

You are currently on the text element --

BEN: It told you the header.

Somewhat comfortable. Number of respondents, 280.

JASON: That's super-handy, okay.

BEN: Yeah. You constantly, assuming you're using semantic markup, which, use semantic markup.

Web content.

JASON: [panicking]

BEN: Yeah. Dev tools and screenreaders, not a match made in heaven. Assuming you're using semantic markup, your table helps users navigate through, and going from row to row, you're in the number of respondents column. Or you're in row four of six now. And so, this is usually how we navigate tables. That's fine. The first thing I wanted to show you, because we're coming up on time here, we haven't done a lot of CSS. I wanted to show you, if you read through the contents of the page, it's pretty plainly clear --

Developer tools.

BEN: That this table is about comfort with detection. Is that caption there for sighted users? I'm going to say it's redundant. We can disagree with that. But for the purposes of today, we're going to declare that's redundant. The context is made clear bit surroundings. It's helpful to have the caption. Yeah. Providing that caption, let us name the table so that screenreader users knew what they were getting into it. If you wanted to the the caption and not show it to anyone, what would you do? What styles would you apply?

JASON: I have -- maybe I would just say like, no.

BEN: Yeah. Let's try it. Let's see. Let's go ahead and turn VoiceOver on and let's navigate back into the table.

VoiceOver on, Microsoft Edge. Demo of the demo, learn with Jason. Web content. You are -- demo of the demo --

JASON: There we go.

BEN: There we go.

Six rows. You are currently in a table top navigate the cells -- response --

JASON: It's gone.

You are on a text element inside of a cell.

BEN: Okay.

System preferences, VoiceOver off.

JASON: Toggle voiceover, quickly press touch ID three times while holding the command key?

BEN: I've seen this. That's totally a thing you can do. I am terrified to do that on a stream because I always feel like I'm going it turn off my computer mid-stream.

JASON: That's also my computer is way up here so I have to reach without hitting my -- yeah.

BEN: Yes. So, we -- we just saw, though, how just one CSS rule was able to change the screenreader output. So, you know, myth proven, right? And it turns out, display none isn't the only property that does this. Visibility hidden will also do that same thing. As the setting opacity to zero. Or setting width and height to zero. Basically, all the tricks you can think of to make content invisible, right? Keep it in the markup, but not show it. All of these trips will do this. They will completely nuke the caption as far as screenreaders are concerned and so, this is why, yeah, this is why in accessibility circles, we kind of pass around like a note being passed around in the back of the classroom. A utility class that's usually called various things. I believe Bootstrap and tail wind call it SR-only. I call it visually hidden. And I can never remember this off of my head. I Scott's inclusively hidden blog post.

JASON: Go inclusively hidden. Here it is.

BEN: I just look for -- I think he calls it visually hidden. It shows you how to hide things and what it means. And close to the bottom, there's a -- yeah, there we go. This class right here.

JASON: This is interesting.

BEN: Yeah. So, this is helpful for, because you don't want to hide a link, right? Because a sighted user might still tab. So, some people include skip links which I think you have on learn with Jason. They like to do this thing where it's hidden until you tab to it.

JASON: I can do that.

BEN: I think so. Probably. Oh, Jason.

JASON: So, it's -- it's selected, but I can't see it. So, it would work. There it goes. Dang it. I think I did this on Jason AF, though.

BEN: Okay.

JASON: Definitely did not do this on Jason AF. One of my websites has it. I don't remember which one.

BEN: Putting the call action in the chat. Someone go put a pull request on Jason's websites.

JASON: Please!

BEN: yep. Okay. We have got those sometimes in there. And let's I guess -- did we save?

JASON: I didn't put these in yet. Let's drop them in.

BEN: There we go.

JASON: And then what I need to do is actually apply this class to more caption.

BEN: Yes.

JASON: That is done. We're gonna go back out to here. When I refresh the page, it's gone, right? But now we're gonna -- actually, okay, let's try it. I have to hit command, go out in the rain, jump up and down four times. Touch ID three times while holding the command key. Did it work?

BEN: Looks like it did. It will come up.

VoiceOver, Microsoft Edge. Comfort with screenreader detection.

JASON: Now it's back.

BEN: Yeah. So, the element is still in there. And it's still providing the table with its accessible name. Screenreaders aren't forgetting this is a thing that exists. But it's hidden from sighted users. And so, actually, when we talk about like the episode notes links earlier, I mentioned I had included an extra node inside those links that had a title. That's also visually hidden with the same styles. That way, the link for sighted users doesn't have the clutter of the title. But the node inside the link still provides the full name of the episode for screenreader users.

JASON: This is the same thing that we did on the links on the Learn with side. Where for a sighted user, there's enough context of like there's this episode, and you've got, you know, the title's there, the description's there, and it says details, you know that's a button that will show details. But for someone tabbing through links, that's not as useful because it's just say episode details, episode details. We have a hidden class.

BEN: Tabbing through links or using the rotor. So, yeah, this is, I guess, way number one in which CSS can impact screenreader experiences, right? Is we were able to use display none to cause our screenreader to entirely forget that an element existed. Which is, I don't know, a bit of chaos. It's frustrating, right? Because display none feels like it should be the magic charm.

JASON: It does feel like something that should be -- like, it's a good point. This is a bummer this isn't just something you can do.

Learn with Jason screenreader experiences. Window, 1-hiding, HTML, any HTML -- system preferences --

JASON: Couldn't turn it off.

BEN: Yeah. So, it begs the question of why does display none behave in this way? This is intentional. It's because -- actually, do you want to take a guess?

JASON: I'm going to take a guess which is that in a lot of cases you do want that content to be invisible. Like if I have a -- an expanded section --

BEN: Yeah.

JASON: Unless you click the "See more" you wouldn't want to tread. That's opt in content.

BEN: Exactly. Display none used to be the efficient way to toggle whether something was shown or hidden at all. There's tons of sights out there -- nowadays we can use the hidden attribute -- but there's tons of sites out there that would handle that by toggling display none. When content is hidden using display none, nine times out of ten, it's because no one was intended to use that content. Sighted users shouldn't get it, but screenreader users totally should. That screenreader case is actually considered kind of the edge case in this sense.

JASON: Right. It makes me want a visibility screenreader-only option.

BEN: Yes.

JASON: That seems like it would be a great way. That makes sense to me. You have a CSS property where you're explicitly saying I'm using this to create accessible text, but I don't need it to be visually present.

BEN: Agree. I'm right there with you. And maybe there's something in the works in the specs for that. I'm not sure. But even if it is, you have to wait for things to be supported.

JASON: And what I found especially when you're talking about specs is that something that sounds so, oh, you're like, oh, of course, they should do that. But what a simple thing. And then look at the downstream effects and all the things on the Internet that would break. Like the working groups for CSS, they do so much work to make sure that we don't accidently break the Internet. So, it should not be taken lightly. If I make a thing, they should just fix that. Don't go talk crap to the CSS WG about this.

BEN: Yeah. And the -- the other thing to note, right? Is that first of all, many screenreader users have very strong feelings about specifically like things that provide like screenreader detection or screenreader-like explicit support. Because there are worries in the past about, oh, you're gonna use this to create a separate, but equal, quote, quote, quote scenario.


BEN: That detection is uncomfortable for many. Yes, today is about screenreaders. Screenreaders are not the only assistive technology, right? In fact, another one that's impacted but a lot of the same stuff is speech control, or voice control. Where you can tell your computer, click on this link. Right? So, now we have to consider, like, oh, are we hiding things for everyone except screenreader users? Or are we hiding except for assistive technology users. That's complex. It's hard. As much as I would love to have a native way to do this with one attribute or one CSS rule, yeah, there are tons of reasons why that would be just incredibly difficult. Oh, no.

JASON: Sorry, I have to do some vocabulary work.

BEN: The math behind how many combinations.

JASON: Come on lil computer, you can do it.

BEN: How do I redeem --

Combinations of objects

BEN: Did I redeem it? I did it. Causing chaos on my own guest stream. Excellent.

JASON: I wholly endorse it. I love it. Okay. Yeah. So, we not only did we learn immediately like I was like this would be so simple and you immediately pointed out why it's not simple. I also got to learn a new word today.

BEN: Yeah.

JASON: We're batting a thousand, y'all. What's up? How are you feeling, chat? Are you learning things today? Give us -- like a -- what's it -- it's F in the chat when things go wrong, what's a good thing? W in the chat. Let's get a W in the chat.

BEN: And also, let me know how you're feeling. Because if you're feeling any sort of emotion over this. Or especially if that emotion is outrage, I genuinely want to hear it. I think that's part of the story here. We are challenging mental models here. Challenging our intuitions about how assistive technologies on the web work. And I would like to get that feedback as to like, hang on, is this frightening? Is this frustrating? Like I want that. So, yeah. Thank you, Michael Chan is in the chat providing even more context. That's a good link right there that he's shared. Yeah.

JASON: There you go. Tons of things -- tons of good things you can do with this. But the overall -- so, the principle of how this -- this utility class is working. Because there's really two approaches for visually hiding things is that people have used. There's one approach which is like less -- like studying minus 999 pixels, off to the left. Or this, which is saying, okay we're going to make the window so see the element through far too small and then overflow hidden it. It is a hack. But there are reasons for the hack. Because we don't natively have a way to expose things only to assistive technologies.

JASON: So, for someone who is feeling frustrated that this isn't built into the browser, I encourage you to go look at the CSS spec. I can almost guarantee somebody has opened this proposal and there's a whole list of all of the considerations, the stuff that Ben was just talking about, and probably a whole bunch of additional things that we have to consider and get right to make sure we don't accidently create -- I mean, I hadn't even considered that you could use accessibility features as a way to sniff and separate people into a different Internet. That's a terrible outcome.

BEN: Yeah.

JASON: I hadn't thought about that. And, you know, there's a thing. My partner Marissa has this thing she says all about is, you have to design for the asshole. When you create user personas, one of your personas has to be the asshole. Who is the person using this to do the worst possible thing? If you're not designing that use case, you have the Facebook scenario. We have no idea people were gonna do this and we have no idea how to fix it.

BEN: People used our app to be terrible to people? Eric has a talk, be the villain, it talks about how one of your personas has to be the person who can and will. The vindictive ex. These absolutely terrible people who are going to find a way to use like tools to just absolutely like cause harm, yeah. So, yeah, that's the visually hidden. That's the visually hidden rule and why it's necessary. Why we can't just use something like display none or visibility hidden. Because oftentimes those are used to legitimately remove content from everyone's experience. And, unfortunately, yes. This is a hack. It's the best we've got. I highly doubt browsers are gonna break this hack any time soon, though. Because that would be super-dangerous, right? You would break accessibility for a lot of things. This hack is good for the future.

JASON: Right. Right, right. Yeah. That's always good news. I think we've got two more that we want to get through.

BEN: Yeah, I've got a few more pages. So, let's go to the second page here.

JASON: We've got 2-list. Let's go take a look at it.

BEN: And, yes. We're gonna actually end up doing a few things in here.

JASON: I love that you brought in the sandwich -- yes!

BEN: I told you I was gonna. I told you I was gonna. In the chat, I'm threatening to do this. Also, my button's not the prettiest. But I had very little time to put this together.

JASON: This is a perfect button. The button is perfect just the way it is.

BEN: We've got a list here. It's a list of the eventual menu for JAMstack the food truck the musical.


BEN: All right. We're actually going to do a few things here. The first is I'm going to be your product owner/your design partner here.

JASON: Okay.

BEN: Let's see what the experience is first.

JASON: Okay. Let me turn it on. Here we go.

VoiceOver on, Microsoft Edge, demo of the demo -- Reuben on Rails. You are on a text -- three items, toast, two of three, bullet, steamed YAMLs. You are currently on text end of list. Add button, you are currently on a button, press, press, add button.

BEN: All right. Yeah. So, that's the experience, pretty straight forward. So things to call out.

System preference, VoiceOver off.

BEN: We were told that was a list. We were told how many items in the list, list three items. And bullet, Reuben on Rails, bullet one of three. It told us how far in the list we were, and even started off with bullet. Cool stuff. So, I'm gonna be your product owner, Jason.

JASON: Okay.

BEN: Or your designer partners or whatever. I'm gonna say, we were -- this is the golden age of minimalism, Jane.

JASON: The golden age.

BEN: Bullets are so yester-decade. Minimalism is in. #minimalism. We need to remove the bullets.

JASON: Okay. So, I remember this is --

BEN: Yes.

JASON: I didn't realize this was going to be a technical interview. Do you remember how to remove bullets?

BEN: The way I typically do is on the UL proper. I think it works on the LI. Cool. This demo, we're actually going to specifically have to do in Safari. And meanwhile, I'm going to find an excellent thread because I'm going to want to put that into the chat very soon. But, yeah. So --

JASON: One of these is Safari. Is this Safari? That's Safari. Okay. So, let me go back here. Get this demo link. Let's head over here, drop it in. I'm in.

BEN: All right. Would you just kind of plow over that with VoiceOver for me, please.

JASON: Yes, I can.

VoiceOver, selected. You are currently on a text element. Main. You are currently on -- Reuben on Rails. Toast, you are currently on a text element. Steamed Y-AMLs.

JASON: It lost my list.

BEN: We used CSS to make the screenreader entirely forget element semantics. No big deal.


BEN: This is actually intentional. This is only a thing in WebKit. I wanted to put a thread in the chat for y'all. So, this is intentional. Basically, this is -- this is the case --

System preferences, Microsoft -- VoiceOver off.

JASON: I'm here, getting this link. That's what we're doing.

BEN: Yes. So, this is an intentional decision that exists inside WebKit. Basically, at one point developers got tired of being told not to use so many divs. And so, many of them started using lists. That then there were lists everywhere. For things that happened to be next to each other, right? But we saw how lists can create a bunch of announcements, right?

JASON: Right.

BEN: The list and extra stuff. This thread documents WebKit's decision to say, hey, if you specifically style your list so that it doesn't look like a list, IE, list style none, then as far as Safari is concerned, it's not actually a list. And so, we're not going to expose this with the technologies as a list.

JASON: Okay.

BEN: Which, you know, given that it's intentional. It's weird, it's frustrating. It's like, I shouldn't -- I feel like -- this is a moment where I wonder, is semantics dead to me? Is semantic markup dead to me? If CSS can make it forget that it list is a list. That shouldn't be doable. My HTML says it's a list. Let it be a list. But here it's totally intentional. If you style your list so that it doesn't look like a bulleted list, Safari will no longer expose it to assistive technologies as a list. And that's fine. This is the intended behavior. Because consistency across sites on a -- on a browser, right? Is the kind of accessible, familiar, relatable experience that we're going for, right? We don't want to hijack stuff that's different on page versus other pages. We want consistent user experiences across the sites they're going to.

JASON: Okay.

BEN: If you felt like it was really important that this specifically be announced as a list, you could go to line 19 which has our unordered list and you could add role equals list. I'm only going to recommend this if you absolutely know that this needs to be announced as a list. You're saying, I know better than the browser in this case. Sometimes as developers, we should just let browsers use their heuristics for things.

JASON: Having done that, back to Safari.

BEN: Should work.

Demo, on Rails. You are on a list, three items. Reuben -- you are on a text element.

JASON: This makes sense. In this instance, if we were making -- this is our list of sandwiches, or list of food items because I don't know what -- steamed YAMLs on a sandwich.

BEN: Put them between bread, it counts as a sandwich.

JASON: Exactly. Everything's a sandwich, right? But we would like -- we would want you to know that you are looking at a list of sandwiches so that you could skip it if you wanted to.

BEN: That is a big advantage of having it be registered as a list. What it was doing when we didn't have the role equals list, it was treating it as a bunch of different text notes. You're right. That loses the skipability. Treating it as a list treats it like a big block that the user could totally skip over if they wanted.

JASON: Yeah.

BEN: Just to reiterate, I don't think this is something to panic about. It's the browser implementing heuristics on the user's testing based on the vast majority I have websites out there.

JASON: Something I would also point out, what we would also be doing as Devs writing semantic markup is we would be putting in headings, for example. If you're looking in a more complete site, there would be like a sandwich menu. If it doesn't announce it as a list, I have my landmark. I know that I hit my heading, it's a list of sandwiches, I'm going to skip to the next thing. You still get skipability, you're not losing the ability to do that. But it reiterates the importance of using that semantic markup. Because if I make a paragraph and I make that paragraph big and bold and use my heading font on it. It looks like a heading to me. But it's not. And so, the screenreader won't see it in the rotor.

BEN: Exactly.

JASON: And so, that's -- this is one of the reasons that I'm always like -- I like to write my HTML with no style so that it's like -- can I read this as a plain text document? Does it make sense to me? If so, then I style it up. That tends to help me a lot with thinking about it. Because if it's legible as a plain text document, it's probably ledge to believe a screenreader or other assistive text. It's probably more true than hey, add some divs until it looks right.

BEN: All right. I think we can get weirder, though.

JASON: You want to get weirder. This is my favorite time of day. Oops.

BEN: I didn't know you could resize that.

JASON: I didn't either. I thought was moving it.

Code, HTML, learn with Safari. System preferences, VoiceOver off.

JASON: Gentle, gentle...

BEN: So far we have seen CSS to make an element forget it's that element. Which is terrifying. We have been using CSS to make screenreaders forget that an element exists all together. You would like to now have CSS inject content into the page. And a we're actually -- we're going to keep doing there on our second page, the one with the list and the buttons.

JASON: On the list page. All right. I'm ready.

BEN: Yeah. I would like to start inserting content. I as your designer, we have done the user feedback, we have done the research, the user testing. We have gotten it. People don't know that the add button is for adding. You know, it would be really helpful to add a plus in the beginning. Like plus add. So, you know, let's add in a plus. And now as a developer, we recognize that that's probably a very presentational decision and should be handled in the CSS rather than the markup. How do we go about adding a plus in there?

JASON: So, add -- do some content. Whoa. What did you --

BEN: Wow.

JASON: I don't know if that was autocomplete or if I hit the wrong button. But that got weird in a hurry. Let's try it like this and see what happens. Look at that!

BEN: It's added a little plus. We could make the formatting nicer. Jason, you and I are very diligent accessibility testers. Here's the thing, this shouldn't have broken anything. Pseudo-elements, not part of the DOM. Famously.

JASON: Famously. I'm ready. Is this going to upset me?

BEN: It might upset you.

VoiceOver on, Microsoft Edge. Reuben on Rails, streamed -- end of list. Add button. You are currently on a button, to click this button, Safari, demo -- learn -- toast, steamed --

BEN: There we go.

You are currently on a button. To click this button, press control.

JASON: There are inconsistencies. You have to test it in multiple browsers because it's going to work differently.

Microsoft Edge, system preferences. VoiceOver off.

BEN: That was Safari we were doing this in?

JASON: Safari picked up the plus, Edge did not.

BEN: So, that's bizarre, right? The fact that we were -- again, we, like, if your intuition is screenreaders are reading the DOM or reading the markup, it never in a million years should it have of picked up the plus. That pseudo element is not part of the DOM. It's -- like it purely exists as a function of the CSS. And yet we were able to use CSS to inject content into our screenreader announcement. So, that's bizarre. But it's a thing to keep in mind. And, you know, maybe this isn't the end of the world. Or maybe you would take this as a reason to put a plus SVG in there instead of text.

JASON: Right. Yeah, because what we could do is like if -- how would we do that? Like we could do, I want to think about how we could make this work. If we did it like SVG, is this gonna work? Text plus. That's still gonna yet read, isn't it?

BEN: Yes.

JASON: We couldn't use text. We have to make a plus sign in SVG like an icon. I'm not going to do that. We know that would work. Totally work.

BEN: I'm not confident enough in my SVG skills to just free style that in the middle of a stream. Just to call out, we were able to use CSS to inject content into the screenreader announcements. Which is very terrifying. And so, we kind of talked about like how CSS is sometimes content. And this is a prime example, right? Because our sighted users don't care whether a plus is pseudo content or not. Our sighted users don't know, they don't care. But it is a part of their experience. That plus is a part of their experience. And so, in some cases, the powers that be have decided that plus constitutes content that needs to be exposed to assistive technology.

JASON: And eco in the chat just I gave a good suggestion. We could also do span ARIA-hidden = true and put our plus here.

BEN: Yes, you totally could.

JASON: And then we could drop this out. And then we get that, but if I turn on the thingy. Which is the official -- it's the industry name for it.

VoiceOver on Safari, on Rails -- selected -- add button.

BEN: Yeah.

Current end of list, add button.

JASON: Now it works. So, I just followed that without a lot of knowledge. What did we just do? What is an ARIA -- what does that mean?

BEN: Excellent. So, yeah. We are going to dive into this just a little bit later, this concept of the accessibility tree. But as a preview --

JASON: Got it.

BEN: Your screenreader isn't reading the DOM. Nor is it reading the CSS . it's not reading either of those. It's reading an alternate part of the DOM exposed. This is called the accessibility tree. Would you like to see it?


BEN: One of your Chromium browsers. If you've got Edge, let's use Edge. And let's go ahead and right click on that button and we're going to inspect it. So, you'll see where you've got your styles tab and computed tab and this is in the layout on the right. And in the other tabs, there's one called accessibility. And this right here.

JASON: Oooo...

BEN: This is one of the hidden secrets of browser Dev tools is the accessibility tree. Your web browser is doing a lot of work to assemble the web page not just into the DOM, but a version of the DOM that can specifically expose to assistive technologies. That is this. We can see where it's pulling from. You can see the contents, add, getting it from its content. But when we use ARIA, ARIA attributes. There are I think 31 ARIA attributes, they all have the prefix ARIA. These are set of HTML traits that specifically and only curate the accessibility tree. So, ARIA-hidden true, what we did is we said this element, don't include is in the accessibility tree at all. Don't expose it to them at all.

JASON: And I take this out, it will have --

BEN: Yes.

JASON: Delete that. Save it here. Let's take a peek. Hey, look at that.

BEN: Yep.

JASON: And that comes from an inline text box.

BEN: And if we went back to using the plus in our pseudo content, we would see the name of the button would still be plus add. At least in browsers that do that. Which I believe was Safari. And I don't know that Safari shows the accessibility tree in DevTools at all.

JASON: Okay.

BEN: That's what's happening. The browser is thinking, I have the button. What should I name the button? It has an algorithm, specced out by W3C. But as part of the algorithm, do I have any pseudo elements in here? That's content that should be exposed to assistive technology users. The browser looks at the button, and how to present the but then in a way that screenreaders can look at. And come peoples into an accessibility tree. It exposed the page to the operating system.

JASON: Nice.

BEN: And the screenreader asks the operating system, what accessibility tree should I be looking at? What application should I care about? That's how the screenreader knows. Which I think is super-cool.

JASON: That is super-cool. We've got about 15 minutes left and I think we have one more demo to do. I'm gonna nudge us right on ahead if you don't mind.

BEN: All right. Cool. This right here, this is my favorite demo. It's the weirdest one. Let's go ahead and just run over this page with VoiceOver real quick. Specifically, the table.

JASON: Okay. I'm ready.

VoiceOver on, Microsoft Edge, Learn with Jason, Microsoft Edge, personal window, tab bar, tab group.

JASON: You good?

Screenreader, selected. You are currently on its response. You are currently -- response. You are currently -- number --

JASON: Yo, where's my table?

BEN: Let's talk about this. Let's take a look at the markup.

Visual studio code. VoiceOver off.

BEN: There we go. So, as we look --

JASON: That's a table.

BEN: It is. It sure it. But we're not using the full fledge of table markup. Don't have a table head, body or foot. For the most part, the table is using default styles for the engine.

JASON: Yeah.

BEN: And so, remember like how the browser is spending, it's using its heuristics to curate the accessibility tree. And at this moment, oh, you have an unstable table? I think chances are good you're using this as a layout table.

JASON: Interesting. Okay.

BEN: And not a data table. And so, you know, lay out tables, now that we've got CSS grid, we don't tend to use layout tables a whole lot. But this used to be a really common pattern in web Dev and still exists in legacy sites. You shouldn't, but you could use a table to lay out your entire page in a grid-like way.

JASON: Okay.

BEN: And so, the browser is looking at this and going, well, if we think that this is a layout table, then we shouldn't expose it as a table. Because that's going to make a very clunky experience for screenreader users. So, we're going to treat it as a bunch of text nodes. And weirdly enough, it does this as the default for the table. There's ways to fix this. But I want to show you my favorite way. Which is, Jason, oh, no.

JASON: I have fears about what you're about to tell me. Let's do it.

BEN: Do you know how to zebra stripe?

JASON: I do. So, if I go to TR, nth-child, odd, is that right? And then do a back ground of -- we'll do like a light gray.

BEN: All right. Okay. We're good.

JASON: I have zebra striped.

BEN: You have zebra striped. You sure have. Let's go ahead and run over this with VoiceOver.

JASON: Come on.

VoiceOver on, system pressing, accessibility features, table, VoiceOver, selected, has keyboard focus. Microsoft Edge reader selected. Table, three columns, six rows.

JASON: Come on! Get out of here.

Row two of six, three of six, 280.

JASON: Okay. So, it's still not as good --

BEN: Yes.

JASON: Our previous table because it's not including the number of respondents or anything. But I am able to navigate it as a table. And this is horrifying because --

BEN: Yes!

JASON: So, what I'm getting from this is that the browser Devs were like, I don't know. People who don't do table markup right. So, if they zebra stripe it, it's probably meant to be a table, treat it like a table.

BEN: There's a ton of other heuristics, if you added borders around the cells. I've looked in the source code, Chromium has this, they all have this, the line of code. Do we think this is zebra striped? Okay. It's probably a table, table. It's horrifying.

JASON: Absolutely cursed, I agree.

BEN: It's horrifying because you're using markup. You're using table markup. This is table data. Maybe we're not using the full range of table markup available to us.

VoiceOver off.

BEN: Like it should be fine. But no, zebra striping fixes tables. Again, there are other ways to do this. The way I would recommend, semantic markup. Always go to semantic markup.

JASON: Before we do that, we have like 5 minutes left, anything else you want to show or fix the markup on this table?

BEN: Show one more item of chaos.

JASON: Yes, please.

BEN: In Safari, go to a website called

JASON: What have I done?

BEN: This is fine. You're gonna hate this, but trust me, it's fine. Using the virtual cursor, navigate to Lengsdorf.

Powered by boops, window. Jason -- headings menu, ed hadding level on three items. Drawing of two arrows. Drawing of two arrows pointing in --

JASON: Hello?

You are on a button.

BEN: Just select the text Lengstorf.

JASON: I'm trying so hard. What have I done?

BEN: What have you done?

JASON: I don't know. Did I somehow take this not clickable? What did I do?

Closing menu, drawing of two arrows. Tagline --

JASON: What?

To click this button -- boops, style equaling height. 100% left, span, 11 items. Menu, 11 items, you are on a menu item. To choose --

JASON: Oh, jeez. Help!

BEN: Okay.

To enter in table, press control.

BEN: There's another way to do this, go back to the second demo and I can show you the same effect. We had this button called add. What if you just capitalize -- I'm going to be the product owner here. What if you just capitalize add in your styles.

JASON: Okay.

BEN: Like all caps. Bigger, more impressive.

JASON: Bigger! Better!

BEN: Let's do this with CSS. That's what we're demoing here.

JASON: Right. So, text-transform: Uppercase. Computer, don't you dare.

BEN: There we go.

JASON: All right.

BEN: We have previously seen this as plus add, or just simply add.

VoiceOver on Safari, demo, Reuben on Rails, end of list. ADD button. You are currently on a button top click this button, press control option space.

BEN: All right. So, first of all, this doesn't happen whether you capitalize every word. It only happens for words that your screenreader doesn't recognize or that could be abbreviations.

JASON: ADD is a common acronym.

BEN: Yeah, attention deficit disorder. The screenreader is receiving, thanks to the accessibility tree, the developer capitalized this word. That's part of the content. I'm going to send the capitalized words. The screenreader receives a-d-d, and knew is it add or attention deficit disorder?

JASON: If I take this --

You are currently on a text area. Text transform, Safari, demo of a demo, are you selected.

JASON: Okay.

Three items,

JASON: It doesn't do it for words that are common acronyms.

BEN: Or if it doesn't recognize the word, might be a common acronym. The reason I wanted you to check out Jason AF, Lengsdorf is picked up as an acronym by screenreaders.

JASON: That's too bad.

BEN: That's one of the reasons I wanted to end on this note. That's fine. That's fine. Screenreader users, first of all, there's such a variety of browsers and screenreaders out there that you're never gonna be able to optimize for all of them. And also, screenreader users, if they're confused about what it is you're trying to say, they can read back character-by-character. But if you're confused by the pronunciation. I work at USAA, some screenreaders pronounce it as "oosa". But if they're confused, they can go back and read character by character. It's like if I'm driving and using a GPS, if it mispronounces the secret name, it's not the end of the world. If you use this day in and day out, you'll understand.

JASON: I understand my computer friend when they tell me how to get places and call a street something hilarious.

BEN: I bring this up because I think everything I've shown you today, it's helpful to understand. But it's also not the thing I want people to walk away being alarmed about. Oh, CSS is impacting my screenreaders. Do I need to worry about every line of CSS? Just do testing and don't worry about it. It's fine. Make sure the content is there that needs to be there. Make sure it's announced roughly allow it should be announced. But I don't know, much like the Hitchhiker's Guide to the Galaxy, don't panic.

JASON: Don't panic. That's the thing that's maybe most important here. Any effort is better than no effort. And so, your efforts here shouldn't be like I have to get this perfect or don't bother at all. With accessibility, the point is to do what you can. And respond to feedback. If somebody points something out. Like whether you opened that pull request and said, hey, your episode details need extra text. You were kind enough to open a PR. If you hadn't, I would have opened it myself. It's a thing to do to make the experience better for more people. It's the same reason we have live captioning on the show. Is this the most accessible show? No, I don't have somebody doing ASL interpretation. I don't have a bunch of things they should have for total accessibility. But I'm doing what I can with the budget and scope available to me. So, it's on us to do as much as we can, but not to panic if we can't do it all. We're not gonna be perfect. But we should be better.

BEN: And test -- test as close as possible to the ways your users are actually gonna be using them. Because, you know, people who are blind, low vision, dyslexic, people who use screenreaders, they're not hypothetical, theoretical abstracts --

JASON: Sorry. I did not mean to cut off your points.

BEN: You're good. These are real people who are really using these tools to access your site. If you're experiencing the world in at least somewhat closer of the way they are. Right? So, test like a power user of assistive technology, because your users are power users of assistive technologies. And it's on you to understand what it is they're experiencing.

JASON: Yeah. There's a question in the chat about how long these take to upload to YouTube? This will be available on YouTube tomorrow. There's a 24-hour holding period on Twitch. Look forward to tomorrow. Go to the Learn with site, subscribe on Twitter and you'll get a notice when it goes live. We are out of time. Ben, where should someone go. Make sure you head over to that Tweeter and you give a little click to that follow. You know? Like smash that subscribe button. Where else should someone go if they wanted to keep up with this?

BEN: Okay. I stream about accessibility every week, every Tuesday, 12 to 1 central, which is in the middle of Learn with Jason usually. But if you're in the mood for some accessibility learnings, why not be a traitor to the cause and go to mine instead? I have the platform. I'm going to use it. I stream about accessibility. It's a lot of fun. And also, I occasionally blog about accessibility at Ben Myers Dev.

JASON: I might have broken it. My poor browser is trying very hard.

BEN: I have one about my favorite HTML element, and we have a stampede just in time.

JASON: Just in time. Thank you so much for hanging out. We have had Amanda with us today doing live captioning from White Coat Captioning and you can always find that on the home page of the website. Keep in mind, that is made possible by our sponsors. We've got Netlify, Fauna, Auth0, and Hasura to make the show more access to believe more people. We have Sarah Dayan coming on to teach us about autocomplete, and Brian Douglas, forked PRs. And Abel, flutter flow, Blitz.js, CLIs in Rust. Some good things. And a bunch of stuff that I have been too lazy to put up on the site. Keep your eyes peeled and hit this add on Google calendar button so you can see those right in your calendar when they get added. With that, Ben, thank you so much for hanging out with us today. It has been an absolute pleasure.

BEN: Thank you for having me on.

JASON: Chat -- any time. I had a blast. Chat, stay tuned, we're going to find somebody to raid, maybe. What's going on? Why won't you let me? Hello? Am I like... did you forget how everything works? What are you doing, chat? Leave me alone. I don't know what's going on. Maybe we'll find somebody to raid. If we can't find -- oh, I know what I did. There it is. Let's go find somebody to raid. Thank you all very much. And we will see you next time!

BEN: Bye!

Closed captioning and more are made possible by our sponsors: