Anatomy of an Accessible Navigation Menu
I'm glad to be here with you. Hope you guys are all enjoying WordCamp this year. I'm here today to talk about the anatomy of an accessible navigation menu. We're going to dive into some of the reasons why we need an accessible navigation menu. And we're going to geek out a little bit and we're going to dive in to some code examples. Like I said, my name Steve Jones.
I'm CTO of Equalize Digital and let's get started. Why is an accessible navigation menu important? Number one, it's inclusive. When you create an accessible navigation menu, you're creating a navigation menu for everybody, regardless of their abilities. There's legal requirements.
There may be policy requirements at your organization as well. Certain government entities, universities require you to meet certain levels. This is not a legal talk, so I won't go in depth on that. But it's there and it's a requirement for certain people.
I like to take a step further than the legal requirements, and I like to say that there's an ethical responsibility, especially for us WordPress developers, when we're generating WordPress websites and moreover WordPress products, we're generating content producing code. If we create code that generates inaccessible code, that can be a real problem for a platform such as WordPress that powers over 40% of the Internet. An accessible navigation menu defines the structure of a website. When you come to a website, the navigation menu tells you what all is on this website, what all the pages are. It gives you context to what's there and to what the structure of the website is. It avoids abandonment.
So if you create a navigation menu that's not accessible to keyboard users and they tab through and it just bypasses navigation menu. The what's going to happen is that keyboard user is likely done with your website and they're moving on. And if you're putting investment into creating content or products or things to sell, you don't want to lose those customers by not having an accessible navigation menu. At our organization, we tried to adopt this monster when it comes to development.
If it's not accessible, it's broken. Accessibility becomes a crucial part of the development process. Code does not get approved. Does not get through code review unless it's accessible. And that is a top requirement, just as all of the feature requirements accessible navigation menus.
How have semantic structuring semantic markup is using HTML elements for their given meaning, not just for their appearance? We use for a navigation menu. We're going to use the the NAV landmark. We're going to use unordered list or ordered lists in code. You will see sometimes that list can be used and abused for many things just because of their markup and people can target them. We want to use them for their intended purpose and accessible navigation. Menu. Is it that adaptive and adapts to the viewport responsive websites as it scales down or up? The menu adapts adapts to magnification.
Some users have a hard time seeing small time. They will increase the zoom on their browser. It needs to adapt to that, and it's adapted to assistive technologies such as screen readers. So let's jump into some code. We're going to start with an HTML on unordered list.
So menu items that are not in a specific order will use an unordered list. This is your typical navigation menu. I have a code box here that shows an unordered list with four list items and they say home about shopping contact. Those can be reordered in any order and it doesn't really matter. So we're going to use an unordered list if your navigation menu does have an order, we're going to use an ordered list.
I have a code example here that shows an ordered list with five lists items and they are in this order. The first list item Download the Accessibility Checker plugin. The second one upload the plug in to your website. The third one activate the plugin, fourth one, scan a post and the third one fix Accessibility issues. The order of this matters. If I flip those around, it gets kind of weird.
So we talked about semantic HTML. We want to identify the menu with an HTML5 landmark, and in this case we're using the NAV landmark. And when using the nav landmarks such as nav, a side header footer, we want to use those for the proper context as well. So next we want to label the menu. We have two options here. We can label it with an ARIA label attribute or we want to label it with an aria labeled by attribute.
I have a code box here with two examples. The first option is to just add the aria labeled equals Main to the NAV landmark. The second option we can use an aria labeled by equals the ID of a heading in this case. So below that I have an H two with an ID of main menu labeled, which is the same as the value for the aria labeled by and the heading is main menu, so it will pull that heading and use that as the title for your navigation menu.
Next, we want to indicate the current menu To do so, we use in the ARIA current equals page. Fortunately for us WordPress developers, WordPress does this for us out of the box and later on we will target this ARIA current with some CSS. So here's a rendered example of what we just went through. We have a very basic navigation menu, but we've set it up properly for accessibility. I'm going to do my best to run a screen reader and hopefully you guys can hear it. VOICEOVER on Great Anatomy of an Accessible Navigation Menu Great Window Anatomy of an Accessible Navigation Entering Anatomy of an Accessible Navigation Menu Web Content Current Page Link List for items you are currently on a link to.
Click this link Press Control Option Space. So that gave the screen reader a lot of information. Since we used private semantics and we created a list, it told them how many.
You list items. We're here. It told us that this was the current link and it gave instructions on how to use it. Link about.
So I currently on the link to click this link press control auction space. So as I go through, you can see these are just regular links. They're not the current link because they do not have the area labeled link chart. You are currently on a link to click this link. Press Control Auction Space Voice over off. So that's the voiceover example.
So now we have our markup. So now we move on to menu styling. Then the styling is displayed in a conventional location, such as a page header or the left sidebar. We like to get creative sometimes and we like to do creative things in our navigation menus. But for accessibility, we typically want to place menus where they're expected, and they're generally expected in the header in the sidebar. And in occasion we have them in the footer.
This is easily identified as a menu through proper markup and styling, and that's what we're here going through. We have our proper markup now and we will work on our styling next. The menu adapts to varying text and viewport sizes, avoids line breaks, uppercase text and hyphens has adequate whitespace and generous click areas.
Hover and focus. State changing hover and focus states gives us visual guidance when navigating a menu. I have a code example here where I'm targeting the NAV landmark and the link inside of that with the hover state and a focus state. I'm making the link blue, the background white, the text decoration underlined. I also have an additional style here where I'm targeting the focus state and I'm setting the outline to solid two pixels and the blue color.
I'm also adding an outline offset of two pixels. So this is for the focus state. When a keyboard navigates to the link. We next want to style the active state of the navigation item. Changing the activated state helps you identify when a menu item they've clicked on is active.
So I have a code example here. I'm targeting the NAV element again and the link inside of that and it's active state. I'm setting the color to dark blue, the background to yellow, and I'm setting the text declaration to underlined. Finally, we want to style the current state visually indicating the active menu item helps users identify the current page. I have a code example here where I'm targeting the NAB element again and I'm targeting the ARIA current Eagles page attribute. Setting the background to yellow.
Setting the color to dark blue and I'm adding an additional border bottom to it. So now that we've gone through those styles, we can see an example here. So this is for a visual user. So when I hover over the active link, you can see I get a change. There's a noticeable change there. And the same with the the inactive links.
The active link has its own styling of the yellow and the border bottom. And if I press and hold, there's a state there as well. If I use my keyboard, I get the outline and this is the two pixel outline. With the two pixel offset.
And I get an outline. So it's different for every state fly out menus, which we call submenus or dropdown downs. In many cases they do. They help define the hierarchy of the website. As we discussed, that reduces multiple page loads.
And it's also helpful to repeat submenus on the current page. So let's go through the markup of a Flyout menu. File menus are nested under their parent list item. I have a code example here where I'm showing the navigation menu that we've already created and we're adding an additional unordered list inside the parents list item, and then we're adding those submenu links just as we did in the parent menu. So in this case, I have a parent venue called Shop. And I've added a sub menu item called Cart, and one called my account.
So flyout functionality for keyboard users, our approach is to add a button toggle with an area has pop up equal to menu. The button toggle with an area expanded a hidden screen reader text labeled with the parent menu name and submenu expanded. I have a code example here where you can see on the parent menu item. I've added a button and there's my area. Expanded equals false and my area pop up equals true. Inside that button I have screen reader text that says Shop submenu.
Now your notice when we go in to do some screen reader testing here in a minute that this may be a little verbose, may be a little too much information for the screen reader having this screen reader text in here, because in the context of the screen, you're going through the navigation menu. There's there's a lot of context that you're already inside of a navigation menu that you're already on a parent link, and that the screen reader is calling out that it is a submenu. The reason why I think I'm still going to stick with this is because the the tab order is not always top to top to left right.
So you can enter into a menu tab in reverse. If you tab in reverse and you hit, the first thing you're going to hit is the submenu button. And you may know that that a submenu, but there's no context to what that parent link is. So now we get into some of the complicated stuff or kind of complicated.
So this is just toggling the attributes so that it reads out the proper stuff in the screen reader when on a submenu pressing the escape closes the submenu and sets the expanded attribute to force and returns focus back to the submenu. So we've given them the ability to quickly keyboard navigate right through the parent menu items. But if they choose to go into a submenu, right.
So we open and we toggle open the submenu, we tab down through those list items. We could go into a next level and tap through those and the keyboard user wants to get back, right? We don't want to make them have to hit shift tab or whatever they're using to navigate to get back to the main menu. We want them to be able to quickly just be able to hit the escape key and jump right, right back to. That main menu item when honest and only allow one submenu open anytime we do this for. For visual users when you hover, it's only one at a time. We should do the same for keyboard users.
So mobile menu. If we're making a menu that is adaptive to all the viewport, we want to create a mobile menu as well. Use a button to toggle the menu visibility. This is in our audits and remediations that we do at our company a lot of times. This is probably one of the biggest things or the most common things we see is that the little hamburger menu on your mobile navigation is not a button. It's a span, It's a div, it's a link.
It needs to be a button. And it should have an expanded attribute on the menu toggle button and set area controls to the menu ID attribute. So the button has has area controls set to the same exact ID that we set on our nav menu. I have a code example of that here. You can see the button with the area attributes. You can see the NAV landmark with the ID and the ARIA label equals menu.
All right. So let's jump in to a live example here and try to do some screen reader testing. So just to be kind and to be fair, I'm going to do this on our own website so that we're not calling anybody out, making anybody feel uncomfortable. So I'm going to turn on the voiceover on great equalizer Digital vertical line website Accessibility Audits, Remediation and consulting Entering Equalize digital website accessibility. I visited Link my account link checked visited link services List five items you are currently on a link to click this link. Press Control Option Space.
All right. So just as before, it's reading out. Since I used a semantic list that I'm on a list, it tells me that there's the number of items that there are. So if I tab one more time Services Submenu menu pop up the last button you are currently on a button to display a list of options. Press Control Option Space. So it told me that it says it's the services submenu and it called out that it's a button.
So as as a screen reader user, I now know what this is. I know what it does. I have contacts. I did state that that text, that screen reader text may be a little bit verbose for a screen reader user. And some screen reader users are very they're power users and in the speed that I have this reading out is like, like super slow.
They do it so fast, I can't even understand what it's saying. It's like speed reading for screen readers Services, submenu menu pop up expanded button. So I toggled open the submenu here and now I can I can tab down through the websites, lists seven items level to visit it, link accessibility on it. Let me jump back ignoring next keep this link catalog visited visited l services visited link bespoke websites lists seven items level two. Yeah, this is currently on a link to click this link.
Press Control Option Space. This is what I wanted to get to that that even on the submenus it calls out how many there are. So if you have like 52 items in here, you know the screen screen for two years and maybe like I don't want to read through these visited links so we can hit the escape key. You are currently on a link to click this link. Press Control Option Space Services Submenu Menu Pop up Collapse button.
You are currently on a button to display a list of options. Press Control Option Space. So I hit the escape there and it dropped me back to that toggle button and set the area states back to their original values. Visited Link Accessibility Checker.
You are currently on a link to click this link. Press Control Option Space VOICEOVER off. So what I want to do is with the voiceover of I want to quickly jump through some of these. So as we stated, when you go through this navigation menu, like I can tab straight across, I don't have to go through all the sub menu items unless I really want to.
Let's see, do what did we not get? We didn't get the active state. Let's get the let's get the active state to read out here. VOICEOVER on Great Services Archive Equalizer Digital Great Window Anatomy visited Link Current Page Visited Link Services List five items you are currently on the link to Click this link. Press Control Option State. So we got since this is the current menu item and we added that Ariella, that Aria attribute.
It reached out to the screen reader that this is the current page. So I'm most likely if I'm here, I probably am not. Don't need I don't need to click on that because I know it's the current page and I can move on. Accessibility Checker. You are currently on a link to click this link. Press Control option Stays.
Let me turn off voiceover. VOICEOVER. Okay.
And also we have our for visual users, we have all the styles that we spoke about. We have an active state. We have a hover state on the active state that shows that we're hovering and we have a different. So I'm pressing and holding on this that we have active state and then we have, as we tap through, we have an outline on it. And we typically use the two pixels with a two pixel offset and we try to match color contrast. We run these through color contrast checker to make sure that our text and our backgrounds on our buttons all meet color.
Contrast. So we're checking all the buttons and we've made it. You guys created an accessible navigation menu. But let's get let's get real nerdy for a little bit since we're at a WordCamp. Let's talk about some code.
I have a just on GitHub that I'm going to go through real quick with you. This is a link to that guest and give you guys a moment to copy that down. Yes, I can read it.
It is a bit dot ly forward slash a 11 y nav everybody good. All right, so let's jump over and look at some code. So we've written this code. This is not very visible. Zoom in.
Is that helpful at all? Yes. Okay. I like dark mode, so I probably should switch this beforehand. But so we've written this code and a lot of people have already utilized this. It's it's on GitHub here.
And I welcome anybody to add comments to this to help us make it better. But I'll run through it a little bit. So I have our page up here where WordPress developer So this is kind of set up for WordPress. And you can see I have I have the markup here that we spoke about. I have a wrapper menu container and this is because of the mobile menu. I need a wrap around everything and then I can.
How's my hamburger mobile menu button and the actual menu inside of there. So, so like I stated, we have the toggle button for the mobile menu, and then underneath that there is our WordPress menu. I'm using the WP nav class here, which gives us several options.
There's many more options than I even have listed here. We have the theme location, which I've got said to primary. We've got the container which I have set.
We, we if the menu, if it has a menu, a menu toggle button, we set up its behaviors. So we have listeners in here, we have we toggle the visual state of the the button for the menu. We determine the new expanded state of the ARIA label. And then finally we update the ARIA add. Abuse. So I'm running through this kind of quick for the sake of this talk.
But like I said, there's codes out there. Feel free to review it on your own. And, you know, message me and we can improve upon it.
So we set the ARIA label for accessibility. We insert the dropdown button after the menu item. We set our behavior when the dropdown button is clicked. So we're determining whether it should be expanded or not. And then we, we toggle it state, so we toggle the dropdown behavior. So when that toggle button is clicked, we then need to open those buttons.
We can't just set the CSRs to it because we wanted to stay open. So I don't know if you noticed when when I open an avenue like this, I can move my mouse away and it stays open. But I will say this that only one stays open at a time. So we're we're toggling the expanded area state of that, and then we have we're closed. Like, this is what I said.
We're closing other navigation menus. We're closing other navigation menus when the new one is opened. And we have we have considerations for the escape key. So when you go into a submenu, you hit escape key returns.
Focus back to the toggle button and says, the ARIA states back and I've recently updated this to account for multiple levels of navigation menus. You go to your first submenu, you go to your second submenu. If you had the gate key on the second submenu it returns focus to the first submenu toggle item that open that one and then you hit escape again and it returns it to the parent. So the following functions are considerations for the keyboard. So we have keyboard handling for the escape. So close the dropdown for the main menu and we went we went a little bit further, which is not necessary, is that we added in some arrow key functionality.
So we added the ability for the left arrow, the right arrow down arrow and the up arrow to work as they're navigating across the navigation menu and up and down through the subsub menu items. I can show that real quick too. You can't really see what key on pressing, but I'm tabbing. So I've tabbed to the services link here in the navigation menu and now I'm hitting the right arrow key and the left arrow key if I have a if I have a submenu open, I can use the down arrow key and the up arrow key. This just adds an extra level of functionality to it. A little bit of icing on the cake.
So finally in this guest, I have some styles, so of course we need styles to make this work. I'm not going to go through all of these styles here in this talk, but of course we just have some basic styling and most of the styles in this file are for the functionality. I don't have all of the styling that you would need on your website. This is like a barebones. Add it to your theme, add your own styles to make it look the way you want it to look.
Then I will note that I have styles for for responsiveness, which we've yet to look at. So if I size the website down at the tablet level, 768 pixels viewport or menu collapses down to a mobile menu. And you can see we have the hamburger menu and I can tab to that.
And the styling that we did on the NAV menu items applies to this. Button as well. We want to give all the visual indicators there as well.
If I hit the return key, it opens and this is the same menu. It's just the styles have changed the look of it. And then I can toggle these open just the same. And in the escape key works just the same as it did on the desktop view. I can I can turn screen ring around for this to real quick since we have a little bit of time. VOICEOVER Andre Services Archive Equalize Digital Rate with Entering Services Archive Equalize digital Web content Menu Collapsed Button Group Enter.
You are currently on the Button group to click this button. Press Control Option Space Menu Expanded Button Group there. So we're using a proper button. We have the proper area attributes on the page.
Visited link services List seven items you are currently on a link to Click this link. Press Control Option Space Services Submenu Menu. Pop up the last button you are Services Submenu menu Pop up expanded button.
There we go. So we have all the same functionality that we had on the desktop view and we have a proper button that opens and closes the mobile menu. So with that, that's my talk.
You can find me in most places Twitter, LinkedIn, GitHub at Steve Jones Devs we've run a meet up. The link to that is as digital icons slash events, we have a Facebook group as well. It's Facebook.com forward slash group's forward slash WordPress dot accessibility. And finally we have a podcast called Accessibility Craft where we we sample craft beverage on a Friday afternoon and we, we talk about accessibility and then we try to continue on work in the afternoon and depending on how much sampling we do and how much work gets done, it can vary. But
so with that, I have I think I have a few minutes for some Q&A. Yep. So since this is a topic about accessibility and keeping with that theme, do not line up at the stands, Raise your hand and I will bring them back to you starting right here. Okay.
Hi, this is Kevin Andrews from Georgetown University. Wow. I sound weird on a microphone. I had a couple like, two, actually. One. This was a great talk. Thank you so much. I love getting into the code.
I have no idea. It may not be the code that I wrote here is a couple of years old, but I think it still applies. I don't know, like in my testing as a sighted user, just using the tab key, the arrow keys don't work for me and out of the box I think I would have to set certain accessibility settings in my preferences so things can.
Hi, Simon Wilson from Hocking Bay, California. And you tested there on screen on voiceover. What other screen readers do you think it's important to test on because.
Yeah. There's like if you're on a PC, there's jaws, there's NVDA on Mac, which is what I use as voiceover. I'm sure there's more. But really, if if you're thinking about that as as accessible as you can be. I would, I would try to get it tested on as many as you can. You know, find good friends like Kevin or like Alex Stein that can do some really in-depth testing for you because, like, you know, our good friend Alex Stein, we gave some feedback on this.
He did some testing and he came back with this stuff and I was kind of, well, I think I need to have this on here. Right. And why is he saying this isn't needed? It's like such as some of the verbose text. And at first I'm like, well, I mean, the spec says I should have this, but I would say I don't need this. So in my head, I go.
But what's Alex seeing in his mind? You know, he's seeing something that I'm not seeing. Right. So it's really good to have have blind user testers test this out. Yeah.
So now you write all the way in the back. I'm. Hi. I'm Christopher Anderton and from Northeastern University.
I just had, again, two questions here. One, I'm interested on the in your example, you had a screen reader class on there, and I'm interested in the if you have a general guideline for using a screenwriter class versus using an ARIA label on the element. And my other question is with when you do aero navigation and what what the expected behavior would be for somebody who is a non sighted user, maybe they have no visual experience whatsoever. And so what do you expect? My my first guest, being a sighted person would be left, right would be expand collapse and up down would be traverse of the menu. But I don't know, and I'm wondering if you had any insight on that. Okay.
So first question is screen reader text. It's two ways to do it. Using ARIA label or use a screen reader class that you then set up some courses to handle so it doesn't display on the front end. Is one better than the other? Maybe the ARIA labels are great and they help us do a lot of things. But, you know, I've heard that the best aria to use is no aria. So here we go.
Kevin approves, And if you can achieve it without the aria, I think you should go that route. If the ARIA label helps you achieve it. I'll default back to the ARIA label sometimes if I have like, icons in there that I don't want to have to.
Like this is a real edge use case and if I have like a pseudo element in there, I can't do certain things with pseudo elements. Like if I have a pseudo element icon. So I'll use the ARIA label so I don't have to do weirdness to try to get that pseudo element icon.
Not to show for a screen reader because it'll show like as a question mark on the the output and I'm blanking on your second question, it was, oh, the arrow keys, I got it, I got arrow keys. So the expected behavior is. So I think the arrow keys are used in can in conjunction with like the tab key or the control option space.
I don't always use those, but it's used in conjunction with the other keys as well. So as you saw me navigate to the the parent menu item, like a tab to get to the menu, of course. And then once I was on the menu, I could use my left and right and up and down, but I cannot use the up and down until I open the submenu. And for me, I just hit the return key to open the submenu. But, you know, depending on the screen reader to use a different key command and actually have one more kind of follow up question that this seems, that would be a bad idea to me.
But just thinking about it, what what any sort of like helper text sort of guidance I guess for navigation be helpful. I mean, it seems like it would kind of go against a site being intuitive to use, but like if you had special keys for doing things, maybe, maybe have some sort of screen your thing that said, press this button to get a list of commands or something like that. I mean, that'd be a special use case. But yeah, I think it would introduce like verbosity.
I think that you want the screen reader to do its thing. We don't want to add to what the screenwriter is trying to do, because the screenwriters in some way are a standard, right? You know, people like Kevin or Alex, they're going to their power users. They know how to use it. They know what they're looking for.
And, you know, they breed it out at lightning speed. You know, so they're looking for speed, I think, most of the time. And if we add in some text that they've never heard or instructions, I mean, they're just going to get annoyed and just move on. Right.
So it's probably not a great idea to think how we're doing it, but one more question. All right. Hi, I'm Lauren from San Antonio. Hello. I'm for as far as accessibility and navigation. So anchor links.
Does that is that not an issue with screen readers or just seeing how it's calling out? Like if you're going to a separate page with anchor links, keeping you on the same page, is that not good practice to use as in menus accessibility wise, or is it not an issue at all? I mean, I think it's I think it's okay, but like, it's going to it might create a little bit of a disjointed experience. So you're saying you go into a navigation menu and you have like hash tag some ID, right? You're jumping down to a section on the same page. Yes. And I'd like to do some testing on that to make sure I give you the right answer. That's fine.
Kevin says it's cool, so I'm going to go with Kevin. He says it's cool. In my head, I'm thinking it's good that the screen reader is going to handle that jump for you. Like it'll read out what happened to them.
It can do some weird things for screen readers. So how are you doing on time? Okay, that is all for this talk. Thank you so much, Mr. Steve. Thank you.