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?
Related
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.
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 am editing a site to be 3 columns.
Here is example page, currently 2 columns:
https://courses.guitar-dreams.com/lessons/an-introduction-to-triads-and-their-inversions/
So what we have is a header, sidebar, content area, and footer. Seems pretty straightforward. But as I look at the HTML, the structure is so odd. Here is how this page is arranged:
<body>
<div class="learndash-wrapper">
<div class="ld-focus">
<!-- notice how it is starting out with sidebar even though we have 2 headers on top of each other... -->
<div class="ld-focus-sidebar">
<div class="ld-focus-sidebar-wrapper">
<div class="ld-course-navigation">
Here is sidebar navigation content
</div> <!--/.ld-course-navigation-->
</div> <!--/.ld-focus-sidebar-wrapper-->
</div> <!--/.ld-focus-sidebar-->
<!-- ok now the main content -->
<div class="ld-focus-main">
<!-- oh but wait, let's add header first! And namely the 2nd header! -->
<div class="ld-focus-header">
Here is the 2nd header
</div> <!--/.ld-focus-header-->
<!-- ok now that we added 2nd header, let's add main content! -->
<div class="ld-focus-content">
here is main content
</div> <!--/.ld-focus-content-->
</div> <!--/.ld-focus-main-->
</div> <!--/.ld-focus-->
<!--/.ld-learndash-wrapper-->
<!-- Oh wait, now that we are at end, let's add that first header now! -->
<div id="wpadminbar" class="">
The topmost header
</div>
</body>
You see what I mean? I am not a web design expert, but I tend to believe that layout of pages generally should follow similar principles to the document publishing world. That is, if your page starts with header, probably good idea for that to be the first design element that you add, and not the last, and moreover, that the design element, if possible, should be placed in the design environment in a way that has physical correspondence to the rendered document.
I am trying to add a right sidebar to make it a 3 column layout. I tried adding a wrapper div to <div class="ld-focus-main"> with display: flex and followed some of the approaches here:
http://geniuscarrier.com/2-columns-layout-with-flexbox/
<div class="ld-focus-main">
<div class="ld-focus-header">
</div> <!--/.ld-focus-header-->
<div class="mywrapper">
<div class="ld-focus-content">
here is main content
</div> <!--/.ld-focus-content-->
<div class="mysidebar">My sidebar</div>
</div>
</div> <!--/.ld-focus-main-->
Here I used (as inline styles)
.mywrapper {
display: flex;
align-items: center;
}
.ld-focus-content {
flex-grow:1
}
I didn't use properties on the right sidebar since in the example in the link above it suggested that if all is well with wrapper and left then right part will follow suit.
But above doesn't produce desired result. At bottom of page linked above you see my added divs and "My Sidebar". I think part of the problem is that the theme template uses such bizarre placement of divs and properties such that when I try to add that right column the underlying structure is not making it work as expected. Sort of like 2nd, 3rd order effects... as well as a Jenga game within a Jenga game.
I was thinking about just redoing the entire template, but at this point I would prefer to just add a sticky right sidebar without a ton of rework. That said, to me it seems the proper way to do such a layout, syntactically would be
<div class="mainwrapper">
<div class = "firstheader"></div>
<div class = "secondheader"></div>
<div class = "outercontentwrapper"></div>
<div class = "leftnavigation"></div>
<div class = "contentwrapper">
<div class = "maincontent"></div>
<div class = "rightsidebar"></div>
</div>
</div>
<div class = "footer"></div>
</div>
Just not sure all the specific properties such that the page would behave as is now, plus add a right sidebar.
So with all that, how would you go about adding that right column?
Thanks!
Brian
I'm trying to learn semantic HTML5 markup by converting a simple site I once made for an old magazine. Now I've come to the navigation and search area. You should be able to select a specific article to read or search within the database. There are two tabs and when the first one is active you see the contents of the selected issue like this:
When clicking on the search tab you come to a search field, like so:
And when you've made a search the results are presented in a similar fashion to the contents above:
The present markup looks something like this:
<div id="nav">
<div id="tabs">
<div class="tab">Browse</div>
<div class="tab">Search</div>
</div>
<div id="browse">
<form>
<div>
<label>Year:</label>
<select>
<option>1985</option>
</select>
</div>
<div>
<label>Issue:</label>
<select>
<option>1</option>
</select>
</div>
</form>
<div id="contents">
<h1>Contents</h1>
<ul>
<li><a>Lorem ipsum</a></li>
</ul>
</div>
</div>
<div id="search">
<form>
<label>Search for anything:</label>
<input type="text">
<input type="submit" value="Ok">
</form>
<div id="results">
<!--
<h1>Sorry, we couldn't find anything.</h1>
<ul>
<li><a>Various stuff</a></li>
</ul>
-->
</div>
</div>
</div>
As for semantic elements, I have considered various options, none of which seems like the solution.
My first problem is whether I should wrap the whole thing inside nav tags or just the browse part, or even just the contents part of the browse part. I'm somewhat inclined to consider the whole thing a single main navigational area.
As for the inner parts, I assume they could be divided into section elements, primarily a browse section and a search section. If so, it would have been nice to get the tab text into those sections as headings, but that will complicate things presentational-wise too much (I know I shouldn't worry about CSS and JS at this stage, but I do). And sections without headings seem like a bad idea.
Another option would be to regard the div#contents and the div#results as subsections. One problem with that is that the results area doesn't have any content until a search has been made.
I can think of some other options as well, but I don't see any point in mentioning them all just to show research effort. I would still need just as much help. And I'd appreciate it too.
My first problem is whether I should wrap the whole thing inside nav
tags or just the browse part...
Looking at the definition of the nav element in the HTML5 spec
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.
...tells us that it should be used for the id="browse" element.
I think it should also wrap the form because it contains controls to filter these navigation items.
The id="search" element should, according to the aria role search
A landmark region that contains a collection of items and objects
that, as a whole, combine to create a search facility.
Get a role="search".
The tab list on the top should get the proper aria treatment for tabs with role="tablist" and role="tab". As shown in this snippet:
<div id="tabs" role="tablist">
<div class="tab" role="tab" aria-controls="browse">Browse</div>
<div class="tab" role="tab" aria-controls="search">Search</div>
</div>
A quick question re: HTML5 nav, specifically that of sub navigation (from a semantic point of view).
I have <nav> in the header for the main menu. Down the left of a standard page I have second level nav and down the right third level nav (no, I didn’t design the site). Is there anything I can do HTML5/ARIA wise to differentiate between the 3 menus? Or are they all simple <nav> blocks?
I dont even think I need <aside> in either left or right column as there isnt any additional info apart from these actual menus.
Any thoughts/advice would be much appreciated.
This may be an old question, but there is a better answer now:
You can label each navigation section implicitly using headings, and explicitly use WAI-ARIA attributes:
<nav role="navigation" aria-labelledby="firstLabel">
<h2 span id="firstLabel" class="hidden">Main menu</h2>
<ul/>
</nav>
...
<nav role="navigation" aria-labelledby="secondLabel">
<h2 span id="secondLabel" class="hidden">Local pages</h2>
<ul/>
</nav>
For user-agents like screenreaders, they can report that as "Local pages, navigation" (although they vary in how it's reported).
Read more on a W3C wiki page on using labelledby.
I would differentiate between the navigation sections by giving them semantically relevant ids and by placing them in order of importance in the HTML code, along the following lines:
<body>
<nav id="main-navigation">
<!-- The main menu goes here -->
</nav>
<nav id="sub-navigation">
<!-- The left hand menu goes here -->
</nav>
<nav id="leaf-navigation">
<!-- The right hand third level menu goes here -->
</nav>
<section id="content">
<!-- Actual page content -->
</section>
</body>
Other than that, I see no real need for further differentiation between the sections. The above approach is easy to understand, should be reasonably easy to style and is semantically clear, which is certainly good enough for me.