Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
When writing HTML5 condent describing to the reader how to navigate through a UI selection path (things like menus, tabs, and dialogs, where there are multiple choices at each step) like:
Options ▸ Configure… ▸ Keyboard Shortcuts
What kind of elements should the labels be?
What kind of elements are the separators, if any? (Or should they be inserted with CSS?)
What kind of element should the entire sequence be contained in?
Note that this is not a question about formatting, nor about interactive elements. It is purely about semantically correct markup in a static descriptive text.
Some things are still going to depend on the actual use cases but basically, you're using a <nav> and then a bunch of <ul><li>.
The toggles to open/close a part of the menu should be <button> with aria-expanded set to "true" or "false" for the open and close states.
The end items should either be <a> if they redirect to a different screen, or <button aria-pressed="true"> if they are just on/off toggles (with the aria-pressed changing depending on the state).
if the whole menu takes focus and/or visibility away from the rest of the app (kind of like a pop-in), you might want to wrap it inside <div role="dialog" aria-modal="true" aria-label="Menu"> <div role="document"> and add a "close" button as the first child.
Here's an example of what the full markup might look like:
<nav role="navigation" aria-label="Full menu">
<!--
the following is useful if the entire menu is behind a single button,
otherwise, you can start directly at the <ul>
-->
<button type="button" aria-expanded="true">
<span>Menu</span>
</button>
<!-- end of "single entry point" -->
<!--
the following is in case you're making a "pop-in" that obscures the rest of the page,
otherwise you can skip them
-->
<div role="dialog" aria-modal="true" aria-label="Menu">
<div role="document">
<button type="button" aria-label="Close menu">
<span>Close</span>
</button>
<!-- end of "pop-in" wrapper -->
<ul>
<li>
<button type="button" aria-expanded="true">
<span>Options</span>
</button>
<ul>
<li>
<button type="button" aria-expanded="true">
<span>Config</span>
</button>
<ul>
<li>
<!-- use <a> if you're redirecting to somewhere -->
keyboard
<!-- use <button> if it's just a toggle -->
<button type="button" aria-pressed="true">toggle Off</button>
</li>
<!-- other Options > Config > * -->
</ul>
</li>
<!-- other Options > * -->
</ul>
</li>
<li>
<button type="button" aria-expanded="false">
<span>Tools</span>
</button>
<ul>
<!-- all Tools > * menu items -->
</ul>
</li>
<!-- other menu categories -->
</ul>
</div>
</div>
</nav>
Tbh, depending on how you need it to look, it might be a pain to style because for it to be properly semantic, you need to have this "recursive" structure of <ul><li> and the <button aria-expanded> should be directly followed by the <ul> they are expanding.
Bonus issue: you can't use the CSS display: contents otherwise the browsers will lose the semantics.
To strictly answer your questions:
What kind of elements should the labels be?
Basically, <button type="button"> with the proper aria attributes. Sometimes <a> for the end items if they redirect the user to another page.
What kind of elements are the separators, if any? (Or should they be inserted with CSS?)
CSS is probably best, the DOM will be separation enough from a semantics point of view. If you need your separators in the markup, try and add aria-hidden="true" if they contain some "readable" elements (span, svg, img, ...).
What kind of element should the entire sequence be contained in?
It should be a <nav role="navigation"> even though the specs state that nav shouldn't have a role attribute because it's intrinsically navigation, but not all browsers implement that properly.
Related
I'm having a hard time with a custom dropdown menu I made. I'm trying to make it keyboard accessible, but I'm not having much luck with the listbox option. I'm following the instructions I find under WCAG pages, but I'm not having any luck. Here's one of the dropdowns on my page:
<ul class="custom__options dropdown story-selector" id="storyFilter">
<li class="custom__option selected" data-type="all" tabindex="0">All</li>
<li class="custom__option" data-type="news" tabindex="0">News and media</li>
<li class="custom__option" data-type="analysis" tabindex="0">Analysis</li>
<li class="custom__option" data-type="press" tabindex="0">Press releases</li>
</ul>
Here's a working Codepen to play with.
Your Codepen example uses WAI-ARIA attributes but have missing roles and expected keyboard behaviours.
In order to be accessible, all elements must have a minimum of a role and a name.
Your role sets a promise to the user of what kind of element the thing is and sets an expectation of how that thing will behave. Consider a role of "slider". In that single word, you've conveyed a lot of information to the user as to what that component is and how it would behave.
The name helps the user to understand the purpose of the element. The name of a volume slide would be "Volume".
Related attributes and properties are typically applied to one element, or are implied through coded relationships (using aria-labelledby for example). You would not do the following in HTML, for example:
<span alt="My image's text alternative">
<img src="image.png">
</span>
Yet I see things like this often for ARIA menubar implementations:
<li role="menuitem">
Home
</li>
There are options here, but with similar markup, the following would be more appropriate for the interactive menuitem:
<li role="none">
<button role="menuitem" aria-haspopup="true">Home</button>
</li>
It's best to use HTML elements with the closest semantics to what you are hoping to achieve, hence using the <button> element above. A lot of accessibility comes for free when you take this approach, since browsers add many (or all) of the behaviours expected by the user.
If you were to do the above using <div> and <span> elements, you need to enable appropriate keyboard focus and handle both mouse and keyboard events.
<div role="menuitem" aria-haspopup="true" tabindex="0">Home</div>
The W3C's WAI-ARIA Authoring Practices details approaches and expectations for common design patterns. For example, if you have several top-level items to choose from, you would want to use a Navigation Menubar.
Based on the Codepen example, what you are looking for is probably something like a Menu Button (or this alternative Menu Buttons tutorial), since you only requite a single dropdown menu rather than a whole menubar. This would produce something like the following:
<button aria-expanded="false" aria-haspopup="true">Story type</button>
<div role="menu">
<button role="menuitem">Home</button>
<button role="menuitem">All</button>
<button role="menuitem">News and media</button>
<button role="menuitem">Analysis</button>
<button role="menuitem">Press releases</button>
</div>
I wonder what the right (html5 valid semantic) implementation of <nav> for a mobile-menu (burger menu) is.
For the desktop-view it's pretty easy. Only need to encapsulate my -List with .
But what's with the mobile view, as the -element is only a trigger for a layer which contain the real navigation items?
The Menu has following structure (simplified for better overview):
<div class="rootMenu">
<button aria-controls="menu-list-grow">
<svg .../>
</button>
<div class="myCollapsableWithMenuItems">
<div class="wrapper">
<ul>... MenuItems goes here</ul>
</div>
</div>
</div>
You see, I've still added the aria-controls to the -element of the burger-menu.
But what is the right place to encapsulate the menu with the <nav>-tag?
I have an issue with using tab navigation or screen reader.
I have a bunch of divs with list inside of it, where each list item has a link, as shown in example below. This html represents vertical "carousel", where user can vertically scroll across the items.
The entire carousel is shown inside of popover (if it matters at all). And it has a lot of CSS to keep carousel scrollable(overflow:hidden, not sure if it matters).
While testing the widget for Accessibility, I found an issue:
Carousel container is not focusable when using tab navigation or screen reader. So, the entire container is just skipped by ScreenReader (Voice Over) and it never goes inside container to read the links.
I tried to add tabindex="-1" for the top most div element, and now it receives the focus, however, it doesn't go inside the div to go through the links.
What can be the reasons for that? How can I make VoiceOver not skip the content and go through all the links
<div class="a-carousel-viewport" id="carousel">
<ol class="carousel" role="list" aria-busy="false">
<li class="carousel-card" role="listitem" aria-setsize="12" aria-posinset="11" aria-hidden="true">
<div class="item">
<h4>Title 1</h4>
<a aria-hidden="true" class="a-link-normal vse-carousel-item" tabindex="-1" href="/someurl">
<div class="content">
</div>
</a>
</div>
</li>
<li class="carousel-card" role="listitem" aria-setsize="12" aria-posinset="11" aria-hidden="true">
<div class="item">
<h4>Title 2</h4>
<a aria-hidden="true" class="a-link-normal vse-carousel-item" tabindex="-1" href="/someurl">
<div class="content">
</div>
</a>
</div>
</li>
</ol>
</div>
It's hard to check the behaviour just from the HTML, a JSfiddle or CodePen to include the JavaScript would help a lot. However, you've got a lot of ARIA attributes that aren't necessary and might be confusing VoiceOver.
The first thing I'd try if you can't provide a demo of the problem behaviour is to remove all of the role and aria-attributes from your code sample and see if that fixes the problem. The roles for list and listitem are redundant on list (ol) and list item (li) elements. aria-setsize and aria-posinset are also not needed on lists. Tabindex and aria-hidden might be needed depending on how the carousel hides slides which aren't visible, but if removing the roles and aria-attributes doesn't help, it might be useful to remove them and see if VoiceOver can find the links when you do.
I have a simple question. Should the button, that I use to open/close my navigation menu be included in the nav tags?
The button itself is not helping in navigating but without him, there is no access to navigation.
<nav>
<ul class="nav">
<li class="nav__el nav__el-active">Home</li>
<li class="nav__el">Generic</li>
<li class="nav__el">Services</li>
<li class="nav__el">Blog</li>
<li class="nav__el">Contact</li>
</ul>
<i class="fas fa-bars"></i> //menu btn
</nav>
that's the example. Now the btn is in the nav, but it also can be like that:
<div class="topbar">
<nav>
<ul class="nav">
<li class="nav__el nav__el-active">Home</li>
<li class="nav__el">Generic</li>
<li class="nav__el">Services</li>
<li class="nav__el">Blog</li>
<li class="nav__el">Contact</li>
</ul>
</nav>
<i class="fas fa-bars"></i> //menu btn
</div>
At first glance, when reading this at WHATWG:
The nav element represents a section of a page that links to other pages or to parts within the page: a section with navigation links.
It seems to me that the button should not be included, as that's clearly not a navigation link.
Anyway, if you continue reading:
User agents (such as screen readers) that are targeted at users who can benefit from navigation information being omitted in the initial rendering, or who can benefit from navigation information being immediately available, can use this element as a way to determine what content on the page to initially skip or provide on request (or both).
With that in mind, it makes sense to include that button and any other non-link control you might have (usually in the header area) because if a screen reader user wants to...:
...skip the whole navigation, they also want to skip the other controls that are not links.
...jump straight to the navigation, they might also want to use some navigation elements that are not links.
If you check some of the examples at WHATWG, it looks like they are applying these criteria. The first example is:
<body>
<h1>The Wiki Center Of Exampland</h1>
<nav>...</nav>
<article>...</article>
...
</body>
Here, it makes sense not to skip the title on the page (to know where you are) but then skip all the navigation elements and jump straight to the content.
However, on the last one:
<nav>
<h1>Folders</h1>
<ul>
<li><a ...>... </a></li>
...
</ul>
</nav>
It would make sense to skip the Folders heading element if you are not interested in the navigation because it's actually part of it, the same way you put the heading of a section inside a section and not before it. The same applies to your menu button.
Some other examples of elements that might be part of the main navigation of the site, and thus go into <nav> are logos that link to the root of the site or search forms.
For example, LinkedIn is doing that:
Also, Bruce Lawson, who is part of the Accessibility Task Force, has the search inside the <nav> element on his personal website:
However, you can also find examples of the opposite. For example, AirBnB only includes some links in the <nav> element:
While in this case, I would have also included the search, that for me clearly represents the main way to navigate on their site.
Anyway, you could and should also use ARIA for accessibility and structured data / Schema.org markup for search engine support.
I have a list of audio streams that is hidden or shown depending on whether a user clicks on a a div element with class 'btn-group'. My mark up is similar to twitter bootstrap's button group, like so:
<div class="btn-group">
<a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
Expand
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<!-- dropdown menu links -->
</ul>
</div>
That's fine, but it seems unfortunate that this important bit of functionality is hidden in a div element rather than something more meaningful. Is there an aria-role that would make sense? Is there some other approach folks would recommend?
A decent solution could be to give the aria landmark role for button to the btn-group div like this:
<div class="btn-group" role="button">
That way, screen readers will understand the nature of the group.