-
-
Notifications
You must be signed in to change notification settings - Fork 568
How to: Article how to make an accessible nav with dropdowns #1472
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 7 commits
a2e1faf
42ae52d
2fc387f
bf169ff
4be5041
6e27a42
2c7f44c
ee903f8
5ccade9
aced8ff
3b94ee3
404459b
f2314eb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,233 @@ | ||||||||||
| --- | ||||||||||
| title: Make an accessible <nav> with dropdowns | ||||||||||
| description: Navigation is a critical part of any application, it allows people to complete journeys and find the information they need. So making it accessible is key. | ||||||||||
| category: How-to | ||||||||||
| author: James Bateson | ||||||||||
| date: 2022-09-04 | ||||||||||
| further_reading: | ||||||||||
| - title: "Menus & Menu Buttons" | ||||||||||
| url: https://inclusive-components.design/menus-menu-buttons/ | ||||||||||
| source: Heydon Pickering | ||||||||||
| - title: "Don't use ARIA menu roles for site nav" | ||||||||||
| url: https://adrianroselli.com/2017/10/dont-use-aria-menu-roles-for-site-nav.html | ||||||||||
| source: Adrian Roselli | ||||||||||
| - title: "Navigation role support" | ||||||||||
| url: https://a11ysupport.io/tech/aria/navigation_role | ||||||||||
| source: Accessibility Support | ||||||||||
| - title: "Top 5 rules of ARIA" | ||||||||||
| url: https://www.deque.com/blog/top-5-rules-of-aria/ | ||||||||||
| source: Deque | ||||||||||
| - title: "Are your anchor links accessible?" | ||||||||||
| url: https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/ | ||||||||||
| source: Amber Wilson | ||||||||||
| - title: "Local Navigation Is a Valuable Orientation and Wayfinding Aid" | ||||||||||
| url: https://www.nngroup.com/articles/local-navigation/ | ||||||||||
| source: Nielsen Norman Group | ||||||||||
| - title: "Cognitive accessibility" | ||||||||||
| url: https://developer.mozilla.org/en-US/docs/Web/Accessibility/Cognitive_accessibility | ||||||||||
| source: MDN Web Docs | ||||||||||
| thanks: "Anya Mueller, Alex Hall" | ||||||||||
| tags: | ||||||||||
| - howto | ||||||||||
| --- | ||||||||||
|
|
||||||||||
| Navigation is a critical part of any application and can often involve many levels of nesting. It allows people to complete journeys and find the information they need. So making it accessible is key. HTML5 includes the <nav> section element to help with this. | ||||||||||
scottaohara marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||
|
|
||||||||||
| ## The nav section element | ||||||||||
|
||||||||||
| ## The nav section element | |
| ## The <code><nav></code> landmark element |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The issue I came across with trying to wrap this one in anything that represented code, was that when it parses this to turn it into a heading in the table of contents, I think it's trying to render a <nav> (or just skipping it, as maybe unsafe?) Is there an available filter could possibly use where those are generated?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oof, yeah. Let's ignore wrapping code in the headings for now, and I'll get to the bottom of this bug.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I probably should have opened one when I spotted it writing this sorry, but wasn't sure if it was intended. Anyway, sounds good, thank you :)
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Let's start with a quick overview of <nav>. The <nav> section element has semantic meaning and comes with accessibility benefits by using it to mark-up sections of navigation. | |
| Let's start with a quick overview of <code><nav></code>. The <code><nav></code> landmark element has semantic meaning and comes with accessibility benefits by using it to mark-up sections of navigation. |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| <p>The <nav> HTML element represents a section of a page whose purpose is to provide navigation links, either within the current document or to other documents. Common examples of navigation sections are menus, tables of contents, and indexes.</p> | |
| <p>The <code><nav></code> HTML element represents a section of a page whose purpose is to provide navigation links, either within the current document or to other documents. Common examples of navigation sections are menus, tables of contents, and indexes.</p> |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| The <nav> element will communicate a role of navigation-equal to setting `role="navigation"`, (this may still need to be added if needing to [support some assistive technology](https://a11ysupport.io/tech/aria/navigation_role)) meaning it can be easily navigated to by people with screen readers—as a landmark. | |
| The <code><nav></code> element will communicate a role of navigation-equal to setting `role="navigation"` to assistive technology. This allows people using screen readers to easily identify it as navigation and navigate to it when navigating by landmarks. | |
| Note that adding `role="navigation"` role may still be needed if you need to [support some older assistive technology](https://a11ysupport.io/tech/aria/navigation_role). |
Suggesting breaking this apart to communicate:
- What
navdoes under the hood, - How people can use it, and
- Separate support concerns a bit so people don't mistakenly skim and add redundant ARIA.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| ### Best practices summarized | |
| ### Best practice |
We haven't discussed these overtly in the preceding sections, so removing "summarized", as this is their first appearance.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| - Not all blocks containing links need to use <nav>. Use it for larger sections of navigation links. Overuse can create 'noise' for people using screen readers. | |
| - Not all blocks containing links need to use <code><nav></code>. Use it for larger sections of navigation links. Overuse can create "noise" for people using screen readers. |
Nice!
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| - Uniquely label the <nav> to give a better idea of its purpose. This can be done with a heading or `aria-label`/`aria-labelledby`. **Note**: Screen readers will already announce the element as being navigation, so avoid using the word 'nav' or 'navigation' in the accessible name. | |
| - Uniquely label the <code><nav></code> to give a better idea of its purpose. This can be done with a heading or `aria-label` or `aria-labelledby`. **Note**: Screen readers will already announce the element as being navigation, so avoid using the word "nav" or "navigation" in the accessible name. |
I love this, but it comes as sort of a surprise and does not offer specific code examples. I worry people won't know of a good pattern to reference, and might not develop it properly. Can we introduce the concept earlier in the post?
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| - For site navigation consider using a list (`<ul>/<ol>`) inside of the <nav>. So that assistive technology can announce how many links it contains. | |
| - For site navigation with more than two links, consider using a list (`<ul>`/`<ol>`) inside of the <code><nav></code>. This will allow people who use assistive technology to know how many links the list contains. |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| <h2 id="main-nav-label" class="visually-hidden">Main menu</h2> | |
| <h2 id="main-nav-label" class="visually-hidden">Main</h2> |
"Menu" has a very specific meaning in the context of authoring accessible components. I'd advocate for removing it.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| <nav aria-label="Main menu"> | |
| <nav aria-label="Main"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GitHub can't easily handle this via suggestion, but can we:
- Break these into two examples, and
- Provide a heading before each example to describe the two techniques.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Navigation designs often need many levels of links underneath a top-level link. This results in using the dropdown pattern, whereby a hidden set of links are shown by interacting with the parent, this can be many levels deep. Some accessibility considerations must be made before implementation. | |
| Navigation often needs one or more levels of links underneath a top-level link. This results in using the dropdown pattern, whereby a hidden set of links are shown by interacting with the parent. This approach can nest links many levels deep. | |
| Some accessibility considerations must be made before implementation: |
Clarifying that the design is the result of the site or app's information architecture, as well as dropdown nav applies to both 1 and 1+ nested levels of navigation hierarchy.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| <nav aria-label="Main menu"> | |
| <nav aria-label="Main"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💯
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a little unclear what the difference between issue one and issue two are. Could we break them out into an ordered list?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we link to an example of what a toggle element is? This is the first time we've mentioned it, but it is vital for constructing accessible tiered nav.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| **Note:** If your parent elements don't need to be a link themselves, make sure to use a `<button>` element, so that they can communicate they are expandable and have an event associated and benefit from all the accessible goodness buttons get for free. | |
| **Note:** If your parent elements don't need to be a link themselves, make sure to use `<button type="button">` element, so that they can communicate they are expandable and have an event associated and benefit from all the accessible goodness buttons get for free. |
Adding type="button" to prevent the browser attempting form submission.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| <nav aria-label="Main menu"> | |
| <nav aria-label="Main"> |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| <button> | |
| <button type="button"> |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| <svg aria-hidden="true">...</svg> | |
| <svg aria-hidden="true" focusable="false"> | |
| <!-- Icon SVG code --> | |
| </svg> |
Added focusble="false" and a comment to explain the SVG's purpose.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By nesting the dropdown list as a direct child of the parent list item, it means that when visible, the first link will be the next focusable element after the parent item toggle.
Can we break this into two sentences to help lower the reading level?
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Related to focus, another nice feature would be to make sure that if the person pressed the <kbd>ESC</kbd> key, the dropdown would close, and the person's focus return to the toggle element they used to open it. | |
| Related to focus, another nice feature would be to make sure that if the person pressed the <kbd>ESC</kbd> key, the dropdown would close, and the person's focus returns to the toggle element they used to open it. |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| A parent link for a dropdown generally will still need to keep its functionality as a link. This can present problems if, for example, a click event has been attached to it to reveal a dropdown. Giving people an explicit way to toggle the visibility of dropdowns is a much nicer option. | |
| A parent link for a dropdown generally will still need to keep its functionality as a link. This can present problems if, for example, a click event has been attached to it to reveal a dropdown. Giving people an explicit way to toggle the visibility of dropdowns via a separate control is a more accessible option. |
jimbateson marked this conversation as resolved.
Show resolved
Hide resolved
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| When thinking about making some component interactions accessible, it's often assumed that more complex ARIA attributes and patterns may be needed. But a <nav> with dropdowns does not need any. There are [menu-related ARIA patterns available](https://www.w3.org/TR/wai-aria-practices/#menu). But these are slightly different in context from the site navigation pattern in this article. Menu ARIA is more designed to deal with native operating system-like menus, for example, a selection of options for a person. | |
| When thinking about making some component interactions accessible, it's often assumed that more complex ARIA attributes and patterns may be needed. But a <code><nav></code> with dropdowns <strong≥does not</strong> need any. | |
| There are [menu-related ARIA patterns available](https://www.w3.org/TR/wai-aria-practices/#menu). But these are slightly different in context from the site navigation pattern in this article. Menu-related ARIA is more designed to deal with native operating system-like menus. |
Two thoughts, so two paragraphs. Also emphasizing not needing menu roles. I also removed the example, as I don't want to suggest that's the only relevant menu to consider.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, will keep the related further reading link in as as well so people can further explore this if they wish and look for examples :)
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Although <nav> can be used without ARIA to create accessible navigation, there are things we can do with it to provide a better experience for people. | |
| Although <code><nav></code> can be used without ARIA to create accessible navigation, there are things we can do with it to provide a better experience for people: |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| <nav aria-label="Main menu"> | |
| <nav aria-label="Main"> |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| <svg aria-hidden="true">...</svg> | |
| <svg aria-hidden="true" focusable="false"> | |
| <!-- Icon SVG code --> | |
| </svg> |
jimbateson marked this conversation as resolved.
Show resolved
Hide resolved
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Although not technically required to make accessible navigation, making sure your site has a 'skip link' (usually visually hidden until tabbed to) that can bypass the main site navigation is a handy usability feature. It allows someone to jump directly to a page's <main> landmark, skipping common and repeated site areas, such as the navigation so the person does not need to traverse this content on every page. | |
| Although not technically required to make accessible navigation, making sure your site has a [skip link](https://www.a11yproject.com/posts/skip-nav-links/) that can be set to bypass the main site navigation is a handy usability feature. It allows someone to skip repeated site areas, such as the main navigation, so someone using assistive technology does not need to traverse this repetitive content on every page. |
- Linking to our post on skip links, so a reader can learn more about them.
- Skip links don't target the
mainlandmark automatically, so rephrasing to not suggest that.
scottaohara marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really appreciate that you're providing segue paragraphs after your section headings 🙂

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggesting two things here:
codeelement, which I will be doing for other instances.