 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 into some code examples. Like I said, my name is Steve Jones. I'm CTO of Equalized 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 could be a real problem for a platform such as WordPress that powers over 40 percent 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. If you create a navigation menu that's not accessible to keyboard users, and they tab through, and it just bypasses navigation menu, what's going to happen is that keyboard user is likely done with your website and they're moving on. 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 try to adopt this mantra 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 the feature requirements. Accessible navigation menus have semantic structuring. Semantic markup is using HTML elements for their given meaning, not just for their appearance. We use, for our navigation menu, we're going to use the nav landmark. We're going to use unordered list or ordered lists. In code, you will see sometimes that lists 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. An accessible navigation menu is adaptive. It adapts to the viewport, responsive websites. As it scales down or up, the menu adapts. It adapts the magnification. Some users have a hard time seeing small type. They will increase the zoom on their browser and 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 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, shop and 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 list items and they are in this order. The first list item, download the accessibility checker plugin. The second one, upload the plugin to your website. The third one, activate the plugin. Fourth one, scan a post. And the fifth 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 nav landmarks such as nav, aside, 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 label 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 H2 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 an 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 gonna do my best to run a screen reader and hopefully you guys can hear it. Voice over on break anatomy of an accessible navigation menu break window anatomy of an accessible navigation entering anatomy of an accessible navigation menu web content. Current page, link, home, list four items. You are currently on a link to click this link, press control, auction space. So that gave the screen reader a lot of information. Since we used the proper semantics and we created a list, it told them how many list items were here. It told us that this was the current link and it gave instructions on how to use it. Link about, you are currently on a 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 aria label. Link, shop, you are currently on a link to click this link, press control, auction space. Voice over off. So that's the voice over example. So now we have our markup. So now we move on to menu styling. Menu 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 with our navigation menus but for accessibility, we typically want to place menus where they're expected and they're generally expected in the header and the sidebar and in occasion, we have them in the footer. It's easy as 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 white space 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 a 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 a 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 users 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 and I'm setting color to dark blue, the background to yellow and I'm setting the text decoration 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 nav element again and I'm targeting the aria current equals 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 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 outline. So it's different for every state. Flyout menus which we call sub menus or drop downs in many cases. They help define the hierarchy of the website as we discussed. That reduces multiple page loads and it's also helpful to repeat sub menus on the current page. So let's go through the markup of a flyout menu. Flyout 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 parent list item and then we're adding those sub menu links just as we did in the parent menu. So in this case I have a parent menu called shop and I've added a sub menu item called cart and one called my account. So flyout functionality for mouse users. When parent menu item is a hovered we should show the sub menu. So additional JavaScript can be used to add a closed delay. So with pure CSS alone when we set the display to none and we set the display to block it's just gonna pop on and pop off. If a user has imprecise mouse movements they may slide off of that sub menu for a second and it closes. You can go the extra step to add a delay to that with JavaScript so that it's a little forgiving for people that are imprecise with their mouse. 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 sub menu 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 sub menu. Now you'll notice when we go in to do some screen reader testing here in a minute that this may be a little verbose it 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 reader going to the navigation menu 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 sub menu. The reason why I think I'm still gonna stick with this is because the tab order is not always top to left. So you can enter into a menu tabbing in reverse. If you tab in reverse and you hit the first thing you're gonna hit is the sub menu button and you may know that that's a sub menu but there's no context to what that parent link is. So now we get into some of the complicated stuff or kinda complicated I don't wanna scare you away but so fly out functionality JavaScript. So these are our requirements or this is what we're trying to achieve with the JavaScript. Keyboard user can navigate through the parent menu items without having to navigate to all the sub menu items. So without writing custom JavaScript for this if you have just a regular navigation menu and you've gone through and you've created the proper semantic markup that we discussed earlier the keyboard user will still have to navigate through every one of those sub menu items. So if you have a large menu with lots of sub menus or multi-level sub menus they're have to tab to that parent menu item and then down through all of those sub menus before they're redirected back to the next parent menu item. So our approach is to allow a keyboard user to tab straight through all the parent menu items without having to go through the sub menu items unless they choose to do so. On sub menu button click or key press toggle the sub menu visibility and toggle the area expanded attribute. So this is just toggling the attributes so that it reads out the proper stuff in the screen reader. When on a sub menu pressing the escape key closes the sub menu and sets the area expanded attribute to false and returns focus back to the sub menu. 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 sub menu, right? So we open, we toggle open the sub menu 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 back to that main menu item. And only allow one sub menu open at a time. We do this for visual users and 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 aria expanded attribute on the menu toggle button. And set aria controls to the menu ID attribute. So the button has aria 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 aria attributes. You can see the nav landmark with the ID and the aria label equals menu. All right, so let's jump into a live example here and try to do some screen reader testing. So just to be kind and to be fair I'm gonna do this on our own website so that we're not calling anybody out, making anybody feel uncomfortable. So I'm gonna turn on the voiceover on break. Equalize digital vertical line website accessibility audits, remediation and consulting. Entering equalized digital website accessibility audited link, my account link, check 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 collapse button. You are currently on a button to options, press control space. So it told me that it's services submenu and it called out that it's a button. So as the screen reader user I now know what this is. I know what it does. I have contacts. I did state 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 the speed that I have this reading out is 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 toggle to open the submenu here. And now I can tap down through the. List seven items, level two, visited link. Accessibility audits. Let me jump back. Ignoring next key press. Link, caps lock, visited, visited. Oh, yeah. Services, visited, link, bespoke websites. List seven items, level two. Yeah, this is. You are currently on a link to click this link, press control, option space. This is what I wanted to get to that even on the submenus it calls out how many there are. So if you have like 52 items in here, you know, screen reader years and maybe like, I don't want to read through these. Visited, link. 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 collapsed button. You are currently on a button to display a list of options. Press control, option space. So I hit the escape key there and it dropped me back to that toggle button and set the aria states back to their original values. Visited, link, accessibility checker. You are currently on a link to click this link, press control, option space. Voice over off. So what I want to do is with the voice over off, 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 those submenu items unless I really want to. Let's see, what did we not get? We didn't get the active state. Let's get the active state to read out here. Voice over on braid, services archive, equalize digital, braid, window, anatomy, visited, link, current page, visited, link, services, list five items. You are currently on a link to click this link, press control, option space. There, so we got, since this is the current menu item and we added that aria attribute. It reads 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 space. Let me turn off the voice over. Okay. And also we have our, for us visual users, we have all the styling 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 an 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 a 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 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 gonna go through real quick with you. This is a link to that gist. I'll give you guys a moment to copy that down. Yes, I can read it. It is bit.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. Let me zoom in. Is that helpful at all? Okay. I like dark mode. So I probably should have switched this out beforehand. So we've written this code and a lot of people have already utilized this. 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 PHP here, we're WordPress developers. So this is kind of set up for WordPress. And you can see 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 wrapper around everything and then I can house my hamburger mobile menu button and the actual menu inside of there. 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 set to primary. We've got the container which I have set to nav. This is the nav landmark. So it outputs nav. You can use div but you want to set the role to nav but the landmarks are so widely supported nowadays you should just use the nav landmark. I have a container class and I have a container ID and then this function actually allows us to add an aria label as well. So I have container underscore aria underscore label equals primary menu. So let's move on to some of the JavaScript which may look a little like a lot but a lot of the code in here is for keyboard functionality. So we've got some vanilla JavaScript here. We basically wait for the DOM to load. We get the main menu elements. We set if the menu, if it has a menu toggle button we set up its behaviors. So we have listeners in here. We toggle the visual state of the button for the menu. We determine the new expanded state of the aria label and then finally we update the aria attributes. So I'm running through this kind of quick for the sake of this talk but like I said, this code's out there. Feel free to review it on your own and message me and we can improve upon it. We set up the drop down toggle buttons for the menu item next. We create the drop down toggle. So since we're using WordPress, we're not actually, I'm not creating a custom nav walker where I'm then injecting the toggle buttons. I'm actually using JavaScript to inject those into the page. So we set the aria label for accessibility. We insert the drop down button after the menu item. We set up behavior when the drop down button is clicked. So we're determining whether it should be expanded or not and then we toggle its state. So we toggle the drop down behavior. So when that toggle button is clicked we then need to open those buttons. We can't just set the CSS to it because we want it to stay open. So I don't know if you notice when I open an admin you 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 toggling the expanded aria state of that. And then we have, like this is what I said, we're closing other navigation menus. We're closing other navigation menus when a new one is opened. And we have considerations for the escape key. So when you go into a sub-menu you hit the escape key it returns focus back to the toggle button and says the aria state's back. And I've recently updated this to account for multiple levels of navigation menus. You go to your first sub-menu, you go to your second sub-menu. If you hit the escape key on the second sub-menu it returns focus to the first sub-menu toggle item that opened that one and then you hit escape key 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 drop down for the main menu. And 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, the down arrow, and the up arrow to work as they're navigating across the navigation menu and up and down through the sub-menu items. I can show that real quick too. You can't really see what key I'm 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 sub-menu 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, guess I have some styles. So of course we need styles to make this work. I'm not gonna 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 bare bones, add it to your theme, add your own styles to make it look the way you want it to look. I will note that I have styles for responsiveness, which we've yet to look at. So if I size the website down at the tablet level 768 pixels viewport, our 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 wanna 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 the escape key works just the same as it did on the desktop view. I can turn screen reader out for this too, real quick, since we have a little bit of time. Voice over on Bray, services archive, equalize digital, Bray with entering services archive, equalize digital web content, menu collapsed button, group banner. You are currently on a 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 ARIA attributes on it. Group 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 collapsed 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 Dev. We run a meetup. The link to that is equalizedigital.com slash events. We have a Facebook group as well. It's facebook.com forward slash groups, forward slash wordpress.accessibility. And finally, we have a podcast called Accessibility Craft where we sample craft beverage on a Friday afternoon and 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. So with that, I think I have a few minutes for some Q and 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 the mic to you, starting right here. 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 as a practitioner. I was wondering if you could expand, upon intended, on the, we didn't hear a close button on the mobile menu for screen reader users and on an iPhone, for example, you can't hit escape if you're on your phone. And then the other question I had was, is JavaScript actually required to detect arrow presses? I didn't think so, but I'm happy to be corrected. Thank you. Yeah, so the first part, a close button on the mobile menu. The mobile menu is a, I have it set up as a toggle and I think you're correct, you can't hit the escape key on your iPhone. So the behavior that I would expect here is that you could tab back and escape. Now you would be much better at walking me through how this experience is on a mobile device and I'd be happy to sit down with you and go through that to see if there's anything we can do to update that for an actual iPhone device experience. And your second question, JavaScript. You know, that's a good question. I have no idea. It may not be. The code that I wrote here is a couple years old, but I think it still applies. I don't know, like in my testing, 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, thanks Kevin. Hi, Simon Welleson from Harpman Bay, California. You tested there on voiceover. What other screen readers do you think it's important to test on? Because I'm paranoid about adding JavaScript interactions to my site because I don't have a good idea for how I can test them in screeners and make sure that they work. Yeah, I think they should all be tested. So, are there any, like I haven't kept up with, what are the big names these days? What do I need to buy? Yeah, 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 you're thinking about as accessible as you can be, I would try to get tested on as many as you can. Find good friends like Kevin or like Alec Stein that can do some really in-depth testing for you because our good friend Alec Stein would give some feedback on this. He did some testing and he came back with some stuff and I was kind of like, well, I think I need to have this on here, right? I'm like, 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 specs says I should have this, but Alec's saying I don't need this. So in my head I go, but what's Alec seeing in his mind? He's seeing something that I'm not seeing, right? So it's really good to have blind user testers test this out. Yeah, so, yeah. All the way in the back. I'm, hi, I'm Christopher Anderton. I'm from Northeastern University. I just had, again, two questions here. One, I'm interested 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 screen reader class versus using an ARIA label on the element. And my other question is with, when you do arrow navigation, what the expected behavior would be for somebody who is a non-sided user, maybe they have no visual experience whatsoever and so what do you expect? My first guess, being a sighted person would be, left, right would be expand, collapse, and up, down would be traverse the menu, but I don't know and I was wondering if you had any insight on that. Okay, so first question is screen reader text. There's two ways to do it. Use an ARIA label or use a screen reader class that you then set up some CSS 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 I've heard that the best ARIA to use is no ARIA. So there 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 icons in there that I don't wanna have to, like this is a real edge use case and if I have 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 output. And I'm blanking on your second question. It was, oh, the arrow keys, I got it, I got it, arrow keys. So the expected behavior is, so I think the arrow keys are used 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 parent menu item, like I tabbed 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 couldn't use the up and down until I opened the sub menu. And for me, I just hit the return key to open the sub menu, but depending on the screen reader, you use a different key command. And I actually have one more kind of follow up question on that. This seems to be a bad idea to me, but just thinking about it would, would 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 have some sort of screen reader thing that said, press this button to get a list of commands or something like that. I mean, that would 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 screen reader is trying to do because the screen readers in some way are a standard, right? You know, people like Kevin or Alex, they're power users, they know how to use it. They know what they're looking for and they breed it out at lightning speed. 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 probably just gonna get annoyed and just move on, right? So it's probably not a great idea. Thanks. One more question? All right. Hi, I'm Lauren from San Antonio. For, as far as accessibility and navigation, so anchor links, 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 those in menus accessibility-wise or is it not an issue at all? I mean, I think it's okay, but like it's gonna, it might create a little bit of a disjointed experience. So you're saying you go into a navigation menu and you have like hashtag some ID, right? You're jumping down to a section on the same page. Yes. Man, I'd like to do some testing on that to make sure I give you the right answer. Kevin says it's cool. So I'm gonna go with Kevin. He says it's cool. In my head, I'm thinking it's good that the screen reader's gonna handle that jump for you. Like it'll read out what happened to them. And with his endorsement, I'm gonna go with him. I think we're good. Separate smooth scrolling. Separate smooth scrolling, yeah. Be careful about smooth scrolling, JavaScript, it can do some weird things for screen readers. So. How are we doing on time? Okay, that is all for this talk. Thank you so much, Mr. Steve. Thank you.