I have a lengthy list of buttons that I want to make WCAG compliant. Many of the items have endnotes (marked with an asterisk) as below. What is the proper way to provide the accessible description for these endnotes?
As far as I know, some browsers are not reading aria-describedby on not focusable elements.
<ul aria-describedby="list_description">
<li><button>Element **</button></li>
<li><button>Element</button></li>
<li><button>Element *</button></li>
<li><button>Element</button></li>
<li><button>Element *</button></li>
<li><button>Element *</button></li>
<li><button>Element **</button></li>
<li><button>Element</button></li>
<li><button>Element</button></li>
<li><button>Element *</button></li>
<li><button>Element **</button></li>
</ul>
<p id="list_description">
* - Important element <br>
** - Very important element
</p>
I was thinking about the solution described here: Accessibility and asterisks end notes, but placing <a> inside <button> doesn't seem right.
Another way is to provide duplicated descriptions for every list item.
What would you suggest to approach it?
placing <a> inside <button> doesn't seem right
Not only does it not feel right, it's not valid html :-) If you look at the <button> spec, under "content model", it says "there must be no interactive content descendant". An <a> is interactive so is not allowed inside a button.
Since you already have the text on the page that documents what * and ** mean, I would put IDs on those elements and then refer to them in the aria-labelledby attribute on each button.
I would also "hide" the * and ** in the button text from the screen reader since the user doesn't need to hear "star" or "star star". You do this with aria-hidden.
The final solution would be:
<ul>
<li>
<button id='b1' aria-labelledby='b1 vimportant'>Element
<span aria-hidden="true">**</span>
</button>
</li>
<li>
<button id='b2' aria-labelledby='b2'>Element</button>
</li>
<li>
<button id='b3' aria-labelledby='b3 important'>Element
<span aria-hidden="true">*</span>
</button>
</li>
<li>
<button id='b4' aria-labelledby='b4'>Element</button>
</li>
<li>
<button id='b5' aria-labelledby='b5 important'>Element
<span aria-hidden="true">*</span>
</button>
</li>
</ul>
<p id='important'><span aria-hidden="true">* - </span>Important element</p>
<p id='vimportant'><span aria-hidden="true">** - </span>Very important element</p>
Note, for consistencies sake, I put IDs on all the buttons and used aria-labelledby on all the buttons even though the buttons without a footnote don't really need them. It kind of makes for some silly code to have a button labeled by itself but it makes it easy to add other footnotes or have some simple text that is applied to the "not important" elements. If that's not likely, then you can remove the IDs and aria-labelledby on the simple buttons:
<ul>
<li>
<button id='b1' aria-labelledby='b1 vimportant'>Element
<span aria-hidden="true">**</span>
</button>
</li>
<li>
<button>Element</button>
</li>
<li>
<button id='b3' aria-labelledby='b3 important'>Element
<span aria-hidden="true">*</span>
</button>
</li>
<li>
<button>Element</button>
</li>
<li>
<button id='b5' aria-labelledby='b5 important'>Element
<span aria-hidden="true">*</span>
</button>
</li>
</ul>
<p id='important'><span aria-hidden="true">* - </span>Important element</p>
<p id='vimportant'><span aria-hidden="true">** - </span>Very important element</p>
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 am trying to create a dropdown with the options taking you to external sites or in my case my website but another language.
I have already made the dropdown but I don't know where to put the code which will allow you to go to the site.
$(document).ready(function() {
$('button').click(function() {
$('ul').toggleClass('active')
})
})
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<div>
<button class="btn">Change Language</button>
<a href="https://discord.com/oauth2/authorize?client_id=709030261605793803&permissions=171166800&scope=bot">
<button type="submit" class="btn">Invite To Discord</button>
<a href="">
<button type="submit" class="btn">Get Started</button>
<ul class="active">
<li>Français</li>
<li>Português</li>
<li>русский (Russian)</li>
</ul>
</a>
</a>
</div>
You need to replace the # within your <a> tags with the actual urls of the page you want to direct to. Also, your html doesn't seem correct. Links within links, plus the addition of buttons all seems very confusing. Depending on what you are trying to do, try simplifying it to something like this...
<div>
<ul>
<li>Français</li>
<li>Português</li>
<li>русский (Russian)</li>
</ul>
</div>
I often need to use a step indication to display the step the user is on, or the progress of a package in transit, etc.
Like this:
This is made up of an unordered HTML list.
<ul class="progress-tracker progress-tracker--text progress-tracker--center">
<li class="progress-step is-complete">
<span class="progress-marker"></span>
<span class="progress-text">
<h4 class="progress-title">Step 1</h4>
Summary text explaining this step to the user
</span>
</li>
<li class="progress-step is-complete">
<span class="progress-marker"></span>
<span class="progress-text">
<h4 class="progress-title">Step 2</h4>
Summary text explaining this step to the user
</span>
</li>
<li class="progress-step is-active">
<span class="progress-marker"></span>
<span class="progress-text">
<h4 class="progress-title">Step 3</h4>
Summary text explaining this step to the user
</span>
</li>
<li class="progress-step">
<span class="progress-marker"></span>
<span class="progress-text">
<h4 class="progress-title">Step 4</h4>
Shorter summary text
</span>
</li>
<li class="progress-step">
<span class="progress-marker"></span>
<span class="progress-text">
<h4 class="progress-title">Step 5</h4>
Shorter summary text
</span>
</li>
</ul>
Assuming a new list is loaded on each page (i.e. "step"), is there a way to adapt this for screen readers/assistive technology?
It would be nice to have the reader read the current step to the user, at least.
Are the steps static or can the user click on a previous step to go back?
If the progress indicator is interactive, then enclose the whole thing in a <nav> element. Your progress indicator would be similar to a breadcrumb trail. The <nav> should also have an aria-label and the current step in the process should have aria-current. So it might look something like:
<nav aria-label="progress">
<ul class="progress-tracker progress-tracker--text progress-tracker--center">
<li class="progress-step is-complete">
...
</li>
<li class="progress-step is-complete">
...
</li>
<li class="progress-step is-active" aria-current="true">
...
</li>
...
</ul>
</nav>
However, your code snippet didn't include any links so I'm guessing your progress indicator is static and not interactive. In that case, don't use a <nav>, because you can't navigate with your indicator, but you could still group the elements together. Having an unordered list is a type of grouping, but sometimes a screen reader will not read the aria-label on a list.
<ul aria-label="progress">
You could work around the issue by having:
<div role="group" aria-label="progress">
<ul>
<li>
...
</li>
</ul>
</div>
(essentially replacing the <nav> in the first example with <div role="group">.
Since your progress indicator is a series of steps, using an ordered list <ol> would have better semantic information. You can style the list so the default numbers of a <ol> are not displayed (similar to how you're not showing bullet points with the <ul>).
And finally, I would add some "hidden" text for the screen reader to say if the step is completed or not. Visually, you have blue circles for completed steps, an open circle for the active step, and gray circles for not completed. That's all done with CSS (your "is-complete" and "is-active" classes). That same context should be conveyed to screen readers. The open circle ("is-active") is conveyed with the aria-current attribute. Use a "sr-only" type class to add text for a screen reader. (See What is sr-only in Bootstrap 3?)
<div role="group" aria-label="progress">
<ol class="progress-tracker progress-tracker--text progress-tracker--center">
<li class="progress-step is-complete">
<span class="sr-only">completed</span>
...
</li>
<li class="progress-step is-complete">
<span class="sr-only">completed</span>
...
</li>
<li class="progress-step is-active" aria-current="true">
...
</li>
<li class="progress-step">
<span class="sr-only">not completed</span>
...
</li>
...
</ol>
</div>
In summary, the minimal changes you need are to:
maybe switch from <ul> to <ol>
add "sr-only" text to the "completed" and "not completed" items
add aria-current to the current step
I disagree with the answers that were previously added to this question.
The correct way of identifying the current step is with aria-current="step".
While aria-current="page" is valid, is meant to be used in a set of links (for exemple, a breadcrumbs widget or a pagination widget).I highly recommend reading more about the aria-current attribute, including its possible values and when to use it. Your example would then look like follows:
<ol>
<li>Step 1 ... </li>
<li>Step 2 ... </li>
<li aria-current="step">Step 3...</li>
<li>Step 4 ... </li>
<li>Step 5 ... </li>
</ol>
Note: I also recommend you use an <ol> instead of an <ul> as this list of steps has an order.
It doesn't look like any of your content is focusable. I had a similar situation that I've shipped in our angular app that works great with JAWS, NVDA, and VoiceOver. What you can do is wrap your markup in a 'div' container and screen reader specific content like this.
<div>
<span class="sr-only">Step 3 of 5: Summary text explaining this step to the user</span>
...
</div>
The 'sr-only' class hides the copy from the visual UI but allows for screen readers to "see" it in the accessible tree.
.sr-only {
border: none;
clip: rect(0, 0, 0, 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
It's important to only make the content available for the step that is currently active.
Hope this helps.
I am brand new to Microdata and I am slowly getting it. But for some reason this does not validate with the W3C validator since I’m putting a <div> in the middle of a <ul>:
<div itemscope itemtype="http://schema.org/BeautySalon">
<ul>
<li>
<b>
<span itemprop="name">foobar and you</span>
</b>
</li>
<div itemprop="address" itemscope itemtype="http://schema.org/PostalAddress">
<li>
<span itemprop="streetAddress">6969 foobar</span>
</li>
<li>
<span itemprop="addressLocality">Miami Beach</span>,
<span itemprop="addressRegion">FL</span>
<span itemprop="postalCode">33139</span>
</li>
</div>
<li>
<span itemprop="telephone">305 691 6969</span>
</li>
</ul>
</div>
How would I correctly add the
<div itemprop="address" itemscope itemtype="http://schema.org/PostalAddress">
and correctly add all the itemprop and still be W3C valid?
ul doesn’t allow div as child, so you can’t use it as container for several li elements. There are various possible solutions.
I think using ul here is not appropriate. But if you want to keep using ul:
It doesn’t seem to make sense that the street address is not in the same list item as the locality/region/postal code. So you might want to put them all in the same list item (and you might also want to use br for postal addresses).
If you want to use b for the name, you could omit the span. Either specify the Microdata on the b or (for consistency) on the li.
If you don’t need a separate element for the telephone number, you could specify the Microdata on the li.
This would give you:
<div itemscope itemtype="http://schema.org/BeautySalon">
<ul>
<li itemprop="name"><b>foobar and you</b></li>
<li itemprop="address" itemscope itemtype="http://schema.org/PostalAddress">
<span itemprop="streetAddress">6969 foobar</span><br>
<span itemprop="addressLocality">Miami Beach</span>,
<span itemprop="addressRegion">FL</span><br>
<span itemprop="postalCode">33139</span>
</li>
<li itemprop="telephone">305 691 6969</li>
</ul>
</div>
You can use every HTML5 element for Microdata. Re-use your existing markup. Only if you need additional elements for Microdata, add and use div/span (and possibly meta/link).
Just trying to get the hang of using the semantically correct XHTML markup.
Just writing the code for a small navigation item. Where each button has effectivly a title and a descrption. I thought a definition list would therefore be great so i wrote the following
<dl>
<dt>Import images</dt>
<dd>Read in new image names to database</dd>
<dt>Exhibition Management</dt>
<dd>Create / Delete an exhibition </dd>
<dt>Image Management</dt>
<dd>Edit name, medium and exhibition data </dd>
</dl>
But...I want the above to be 3 buttons, each button containing the dt and dd text. How can i do this with the correct code? Normally i would make each button a div and use that for the visual button behaviour (onHover and current page selection stuff).
Any advice please
Thanks
<ul>
<li>Import images</li>
<li>Exhibition Management</li>
<li>Image Management</li>
</ul>
thats good enough.
using <dl> for navigation is not very clever. or use a <span> inside the <li> with the description. <dd> will give you much headache since they aren't inside the <dt> and don't care about its position and styling
I am slightly confused by the use of your term "button". If you mean a link, then you could do:
Import images
If, however, you mean the input tag, then one way to do this would be to use input type=image and then provide an alt description.
For instance:
<input type="image" src="image.jpg" value="Import images" alt="Read in new image names to database"/>
You could use <label> elements instead of <dt> elements:
<ul>
<li>
<a href="#">
<label for="import-images">Import images</label>
<span id="import-images">Read in new image names to database</span>
</a>
</li>
<li>
<a href="#">
<label for="exhibition-management">Exhibition Management</label>
<span id="exhibition-management">Create / Delete an exhibition</span>
</a>
</li>
<li>
<a href="#">
<label for="image-management">Image Management</label>
<span id="image-management">Edit name, medium and exhibition data</span>
</a>
</li>
</ul>
... the for attribute of the <label> element need only match the id of another element in the document to be valid.