semantic html - autocomplete results in combobox - html

I have a role="combobox", which opens up a role="listbox" when something is typed. The listbox has a list of items where the <li> are marked as role="presentation" and the children element as role="option". The list items in this case have 2 bits of information, a primary text and a secondary text. should these list items simply be divs, or is there a better semantic element which can be used?
<input role="combobox" aria-haspopup="true" aria-autocomplete="list" ... />
<ul role="listbox">
<li role="presentation">
<div role="option">
<div> primaryText </div>
<div> sencondaryText </div>
</div>
</li>
</ul>
Is there a more semantic way to represent the primary and secondary text?
In a similar scenario, when search results are shown, I have seen each search result is an <article>, the title is either <header> or <h1>, and the secondary text is regular <div>. Does that structure make sense here?
Also, in some cases the results need to have a title, for example: "Results"
In that case I usually change the structure to:
<input role="combobox" aria-haspopup="true" aria-autocomplete="list" ... />
<div class="container">
<div> Results </div>
<ul role="listbox">
<li role="presentation">
<div role="option">
<div> primaryText </div>
<div> sencondaryText </div>
</div>
</li>
</ul>
</div>
In this case would it make sense to use a <section> like this
<input role="combobox" aria-haspopup="true" aria-autocomplete="list" ... />
<section class="container">
<header> Results </header>
<ul role="listbox">
<li role="presentation">
<div role="option">
<div> primaryText </div>
<div> sencondaryText </div>
</div>
</li>
</ul>
</section>
UPDATE:
As mentioned here:
https://www.w3.org/TR/wai-aria-practices-1.1/#presentation_role
Any children of the role="option" would behave as if they have role="presentation" applied to them, so doesn't matter whether they are divs or spans or heading tags, the semantics would be removed.

should these list items simply be divs, or is there a better semantic element which can be used?
<li> is certainly one of the best fit for the items of your list box, except if individual results are quite long (see below) with your third question.
Is there a more semantic way to represent the primary and secondary text?
As far as I know, no. You may use <dl>, <dt>, <dd> instead of <ul>, <li>.
Both are correct solutions, none is better than the other, between the two.
In a similar scenario, when search results are shown, I have seen each search result is an <article>, the title is either <header> or <h1>, and the secondary
text is regular <div>. Does that structure make sense here?
It depends on how the results are going to be navigated.
If you are in the context of a form and if the results are navigated through by using arrow keys, which is the case for a typical combobox, the construction with <article> and headings is much less appropriate.
If you enter something to search, and then go out of the form to read the results, then <article> and headings is the best option, much better than simple <ul> <li>, because screen reader users can use keyboard shortcuts to navigate by heading or by section.
The length of the primary and secondary texts might be a criteria to help you decide which is the best option for your case.
For example, Google search results are used like the later, that's why they use a markup with headings.
Also, in some cases the results need to have a title, for example: "Results" In that case I usually change the structure to:
...
In this case would it make sense to use a like this
Yes, in this case it makes perfect sense.

Related

How to fix role="tablist"/role="tab" Axe violations?

We have some tabs on our page with the following structure:
<ul role="tablist">
<li>
<div role="tab" tabindex="0" aria-selected="true" aria-controls="id1">First tab content...</div>
</li>
<li>
<div role="tab">Second tab content...</div>
</li>
</ul>
This gives rise to two violations when running Axe accessibility tests, namely:
<li> elements must be contained in a <ul> or <ol>, and Certain ARIA roles must contain particular children (also the converse that certain children need particular parent roles).
I understand that the first violation is due to the tablist role meaning that the <ul> is no longer seen as a <ul>. I don't understand the second violation as the spec does not enforce that elements with role="tab" are immediate children of tablist.
One possible fix, which prevents these violations, would be to move role="tab" up to the <li> elements. The problem then though is a different violation: Nested interactive controls are not announced by screen readers, due to the contained <div> being focusable presumably. Changing this to the outer <li> would require a whole load of js and css changes, so is not a simple fix.
To what extent does this really need fixing and what is the best approach?
Axe is wrong. The spec for the tab role says:
Authors MUST ensure elements with role tab are contained in, or owned by, an element with the role tablist.
Emphasis mine. Notice that is says a tab must be contained in a tablist. Contained in does not mean a direct child but rather a descendent.
This is further emphasized if you look at the next phrase, or owned by. "Owned" has a definition:
An 'owned element' is any DOM descendant of the element, any element specified as a child via aria-owns, or any DOM descendant of the owned child.
So again, as long as the tab is a descendant of a tablist (child, grandchild, great-grandchild, etc), then technically it's valid and axe is wrong.
Now, the definition of "owned" gives you a clue as to how you can work around axe's bug in case the violation bothers you. Add aria-owns to your <ul> and point it to the tab elements (your <div>s). Your original code will pass axe like this:
<ul role="tablist" aria-owns="foo1 foo2">
<li>
<div id="foo1" role="tab" tabindex="0" aria-selected="true" aria-controls="id1">First tab content...</div>
</li>
<li>
<div id="foo2" role="tab">Second tab content...</div>
</li>
</ul>
You still have the issue of an <li> not contained in a <ul>. #graham covered that part. And I also agree with #graham that you should follow the authoring practice for the tab design pattern.
The answer with your current setup is to remove the semantic meaning from the <li>.
<ul role="tablist">
<li role="none presentation">
<div role="tab" tabindex="0" aria-selected="true" aria-controls="id1">First tab content...</div>
</li>
<li role="none presentation">
<div role="tab">Second tab content...</div>
</li>
</ul>
role="none presentation" removes all semantic meaning from the <li> (so think of it like a <div> now).
It would be preferable to move everything "up one level" to keep the DOM tidy though, so a better solution might be:
<ul role="tablist">
<li role="tab" tabindex="0" aria-selected="true" aria-controls="id1">
First tab content...
</li>
<li role="tab">
Second tab content...
</li>
</ul>
This would work as you have now changed the semantic meaning of both the <ul> and the <li>, although it might need a minor adjustment to CSS.
Also Axe can sometimes complain with the first example, even though it is valid, the second example will have no complaints from automated checkers.
Alternatively you may want to look at using <button> elements to create tabs, see the tabs example on W3 on how to structure that.
It has the advantage that the click handler can be used for both mouse and keyboard interactions because you are using a <button>.

How to apply keyboard accessibility when dropdown items are span tags?

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>

Semantic markup of navigation and search area

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>

Proper ARIA handling of breadcrumb navigation

What can be done to improve the accessibility of a breadcrumb menu similar to:
<ul class="breadcrumbs" aria-label="breadcrumb navigation" role="navigation">
<li>Home</li>
<li>News</li>
<li class="unavailable">#Model.Title</li>
</ul>
Given in this example Home is the site root, News is the first child, and the unavailable class is the current item the /news/article item.
Is there anything that could be done to improve this such as using rel attributes or aria-level attributes?
I would avoid the use of aria-level and use a <ol> element instead. It is best to avoid using aria attributes wherever a native alternative exists. Using aria adds an extra layer of complexity. Simple HTML is far better and already has semantics that are surfaced to AT. This is the first rule of ARIA.
Borrowing from the WAI-ARIA-Practices document, breadcrumbs would look like something like this:
<nav aria-label="Breadcrumb" class="breadcrumb">
<ol>
<li>
<a href="../../">
WAI-ARIA Authoring Practices 1.1
</a>
</li>
<li>
<a href="../../#aria_ex">
Design Patterns
</a>
</li>
<li>
<a href="../../#breadcrumb">
Breadcrumb Pattern
</a>
</li>
<li>
<a href="./index.html" aria-current="page">
Breadcrumb Example
</a>
</li>
</ol>
</nav>
Some notes:
Wrapping the breadcrumbs in a <nav> element lets screen reader users quickly find and jump to the breadcrumbs.
Using <ol> element surfaces an order to screen reader users.
The <ol> should be a child of the <nav>. Some implementations apply role="nav" to the <ol> itself. This is wrong and will override the default <ol> semantics.
aria-current informs screen reader users that this is the current page. If the last breadcrumb for the current page is not a link, the aria-current attribute is optional.
Going from using a screen reader and reading this blog post, the rel attributes won't make a difference to A.T. As for using aria-level, it works if you put it on the anchor tags. I'd also advise wrapping the list in a nav element, for semantic purposes and to save the need of putting a navigation role on the list when you don't need to.
I wound up with this markup for what I think is a not-too-bad breadcrumb. Hide the bullets using CSS (I didn't stop to do that I'm afraid) and I'd say its good.
<nav aria-label="breadcrumb" role="navigation">
<ul>
<li>Home</li>
<li>News</li>
</ul>
</nav>
Hope this helps!
You can use like below
<nav role="navigation" aria-label="breadcrumbs">
<p id="breadcrumblabel">You are here:</p>
<ol id="breadcrumb" aria-labelledby="breadcrumblabel">
<li>Home</li>
<li>Menu1</li>
<li>Menu2</li>
</ol>
</nav>
When searching the Web for a thorough solution on accessible breadcrumbs, #Craig Brett's solution seemed good at first sight. But after reading several sources, aria-level seems to be misused there (besides a W3C Validation problem, see my comment above).
Therefor I like to propose this approach:
<nav aria-labelledby="bc-title" role="navigation">
<h6 id="bc-title" class="vis-off">You are here:</h6>
<a href="~/" aria-labelledby="bc-level-1">
<span id="bc-level-1" class="vis-off">Homepage Website-Title </span>Home
</a>
<a href="~/news" aria-labelledby="bc-level-2">
<span id="bc-level-2" class="vis-off">Level 2: News </span>News
</a>
#Model.Title
</nav>
In this solution we have an HTML5 sectioning element (nav), which should have a heading, and *tada* there it is. Class vis-off signifies an element that is just available to screen readers. With aria-labelledby I'm telling the screen reader to read that headline.
In contrast to Chris' solution, either the <ul> or aria-level is gone.
I'd so or so go for an <ol> if necessary, because the items are in order. Better leaving it out, otherwise it gets very verbose in many screen readers on every page ("List item 1…").
aria-level seems to be misused in the solution above in my understanding. It must be child of a role attribute like f.e. role="list" and that role just signifies not structurally marked-up non-interactive lists.
Maybe a role treeitem might be more appropriate. IMHO it's overkill.
PS: I'm not using BEM notation here to shorten the ids and classes for readability.

HTML5 <nav> element

I'm always trying to use the new html5 elements, but find myself doing stuff like this:
<nav class="some-menu">
<ul class="menu">
<li>
<a title="link to somewhere" href="the-link.php">link to somewhere</a>
</li>
</ul>
</nav>
When I could have achieved the same (visually) with:
<ul class="menu">
<li>
<a title="link to somewhere" href="the-link.php">link to somewhere</a>
</li>
</ul>
More symantic markup vs bloated DOM, should I include the <nav> tag in that situation?
EDIT
I've found the <menu> item can actually be used in this situation along with <li> e.g:
<menu class="side-menu">
<li><a title="a menu item" href="touch-my-nipples.thanks">Inappropriate Href</a>
</menu>
Which achieves more semantic markup without verbosity
Well you could argue that not including html5 tags increases the readability of your html file.
However, for SEO purposes, using html5 tags may assist in your page rank, so that might be a consideration if you are developing for a commercial web page.
In this one particular case, if the purpose of the <li> is not for navigation, then it I doubt you would get any criticism for it.
This is a good question. More DOM == more time to load the page, which is not good. However, you could try to use a combination of both. How about simply doing something like this:
<nav class="menu">
<a class="menu-item" href="...">Link 1</a>
<a class="menu-item" href="...">Link 2</a>
</nav>
I don't think there is a huge benefit to one over the other, though you should test to see how this appears to different screen reader users (as accessibility may be benefit of semantic markup).
It's not just about code bloat, don't forget about accessibility. By having a <nav> element, you can tell user's screen readers where the menu is. It would be difficult to detect if it was just ul.menu.
As Denis mentions, there are also advantages for SEO rankings.
"the element which allows you to group together links, resulting in more semantic markup and extra structure which may help screenreaders."
By: http://html5doctor.com/nav-element/
Example:
<nav>
<ul>
<li>Home</li>
<li>About</li>
</ul>
</nav>
Good idea use because: internal links for site navigation
<menu> tag
The HTML element represents an unordered list of ""menu"" choices, or commands.
By: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/menu