I currently write a user-interface for a search page on a local application. This search must have checkboxes to limit the scope of the search query. To make this functionality accesible I want to use "wai-aria"-Attributes.
So far my markup looks like this:
<div class="input-group">
<div class="checkbox-inline">
<input type="checkbox" id="check-bd-1">
<label for="check-bd-1">Band 1</label>
</div>
<div class="checkbox-inline">
<input type="checkbox" id="check-bd-2"></input>
<label for="check-bd-2">Band 2</label>
</div>
(... and so on...)
<p id="help-check-band" class="form-control-static">Helptext...</p>
</div>
I want to use a "aria-describedby"-Attribute to reference the helptext, identified by "help-check-band". This text is appropriate for each input of this group.
My question is: Where should I put the "aria-describedby"-attribute? Is it neccesary to put it on each <input>-element, or does it suffice to put it in the topmost div (with class "input-group")?
According to The Mozilla Dev-Network both ways seem to be possible. "aria-describedby" can be utilized by the container and the input elements. Since the attributes on the input-Element correspond directly with the functionality, this way seems to fit this case.
Related
I've been learning about the "for" attribute in HTML and what it does but I've stumbled upon a weird example that I've yet to understand
Code1
<input id="indoor" type="radio" name="indoor-outdoor">
<label for="indoor">Indoor</label>
Code2
<label for="loving"><input id="loving" type="checkbox" name="personality"> Loving</label>
<br>
<label><input type="checkbox" name="personality"> Loving</label>
I understand why "for" is used in the first block of code but I don't understand why the second code used "for" and "id" implicitly when it could've just worked fine without them.
Any help?
It is correct, that it works without it. But it is useful to connect the label with the input field. That is also important for the accessibility (e.g. for blind people, the text is read).
The browsers also allow you to click the labels and automatically focus the input fields.
For checkboxes this can be useful as well. But for these, you could also surround the checkbox-input like this:
<label>
<input type="checkbox"> I agree with the answer above.
</label>
In this case, the checkbox is automatically checked when you click on the text.
The surrounding of the inputs with a label works with every input field. But the text, that describes the input field, should always be inside it. That what for is for: When your HTML disallows the label-surrounding, you can use the for-attribute.
The the both following examples:
Simple stuctured:
<label>
Your Name:<br>
<input type="text"/>
</label>
Complex structure around input fields:
<div class="row">
<div class="col">
<label for="name">Your Name:</label>
</div>
<div class="col">
<input type="text" id="name" />
</div>
</div>
It could be used without "for" attribute, and it will be fine, according to docs.
This is just one option how to use "for" to omit confusing developers.
Anyway, in case of placing checkbox inside label, you can skip "for" and it will be fine.
<!-- labelable form-relation still works -->
<label><input type="checkbox" name="personality"> Loving</label>
"for" approach much preferable if you want to style it, f.e. using Bootstrap
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="flexCheckDefault">
<label class="form-check-label" for="flexCheckDefault">
Default checkbox
</label>
</div>
To be able to use the label with the check box.
E.g., when rendered, click the label and it will toggle the check box ticked state.
Edit: Further to this, it allows putting the label anywhere on the page.
Can sommeone explain me the difference between using the for-attribute on a label and using the aria-labelled-by-attribute on the input.
As far as I know aria-labelled-by allows multiple elements (e.g.radio buttons) to be labelled by the same label whether for relies on the id of the elements which should be unique and can therefore only assigned to one element.
So in which case should I use for and in which case aria-labelled-by?
The main difference is that for attribute has the functional purpose. for attribute is used to chain the label with specified form field of some id. For example:
<div>
<input type="checkbox" id="checkboxId" />
<label for="checkboxId">My cool checkbox with clickable label</label>
</div>
<div>
<input type="checkbox" id="checkboxId2" />
<label>My cool checkbox without clickable label</label>
</div>
As you can see, the label with specified for attrubute has ability to toggle checkbox of id that is specified in this for attribute.
The ARIA attributes are mainly used to make you application accessible for people with some kind of disabilities (e. g. to make you application suitable with screen-readers, etc.). The ARIA attributes have no direct functional purposes, they are only about accessibility
<input aria-labeledby="myLabel" type="checkbox" id="checkboxId" />
<label id="myLabel">My cool label</label>
Problem: Grouping form elements
I have an HTML form, where in few places a single control is composed of several inputs. One example is a group of radio buttons.
I'd like to group those inputs and it's label explicitly, so that the screen readers would also (in addition to the visual representation by aligning them on a single line) be able to understand and announce this relationship.
For example, let's say I have a control like this:
<div class="control">
<div class="control-label">Type</div>
<div class="control-inputs">
<input type="radio"
name="type"
value="a"
id="type-a" />
<label for="type-a">A</label>
<input type="radio"
name="type"
value="b"
id="type-b" />
<label for="type-b">B</label>
</div>
</div>
Standard solution problems: Fieldset styling issues
fieldset element and it's child legend seem to be made exactly for that (used in the example below).
The problem is that fieldset and legend elements can't be styled like normal elements (some discussion about it) and nowadays other than in Firefox it's impossible to align them on a single line using Flexbox, which my layout requires.
<fieldset class="control">
<legend class="control-label">Type</legend>
<div class="form-inputs">
<input type="radio"
name="type"
value="a"
id="type-a" />
<label for="type-a">A</label>
<input type="radio"
name="type"
value="b"
id="type-b" />
<label for="type-b">B</label>
</div>
</fieldset>
Question: Is there some other way?
That makes me wonder if there is some accessible way to group several form controls other than using fieldset element?
Possible solution: role="group"?
There is a "group" role (used in the example below), which could be added to a simple div and it looks like it might do the job, but nowhere is stated clearly that it is the functional equivalent to using a fieldset. And if it does, then how do I mark an element of this group to serve as an equivalent of legend?
<div role="group"
class="control">
<div class="control-label">Type</div>
<div class="control-inputs">
<input type="radio"
name="type"
value="a"
id="type-a" />
<label for="type-a">A</label>
<input type="radio"
name="type"
value="b"
id="type-b" />
<label for="type-b">B</label>
</div>
</div>
Basically you have already answered your question in the Possible Solution section (btw, as a blind person, I'm just impressed how you styled your question with headings!). You missed one tiny and simple thing, the aria-label attribute:
<div role="group" class="control" aria-label="Type">
Note: this will be invisible on screen, it is a screen-reader only solution. If however you want to make it visible, do the following using the aria-labelledby attribute instead:
<div role="group" class="control" aria-labelledby="pseudolegend">
<div id="pseudolegend" class="style-it-like-a-legend">Type</div>
[...]
</div>
The pseudolegend may be a span or even a p, of course, if you find it more appropriate.
A quick and dirty local test I made showed that, at least with JAWS and Chrome, there is no difference between a fieldset and a div with aria-label.
Note: For radio button groups in particular you can use role=radiogroup. Also, in order for the semantics of a group or radiogroup to be expressed to screen reader users an accessible name for the grouping element is required.
I have a page I'm trying to code where the user has to select one from a number of options, presented as a grid of thumbnails. On similar pages, I've used role="radiogroup" and role="radio" (and appropriate scripting, labelling, etc), and that worked well - the difference with this one is that there are multiple sections within the larger radiogroup.
Edit, to clarify: I'd rather use native radio buttons, as several people have pointed out. I may not be able to because this is a big angular app with a lot of weird baggage I have to work around, but I'm looking into it. That said, whether they're role="radio" or type="radio", my question is specifically about the best way to communicate that some of them are grouped together.
The user can pick only one option, from any of these sections. The structure is along these lines:
Choose an image
Artist 1
Image A
Image B
Artist 2
Image C
Image D
So basically, I'm looking for a way to preserve the "artist" context while moving through the image options. Something like optgroup from the select element. I've tried fieldset, which kind of works; I'm wondering if that's the best way to go?
Here's what I currently have, structure-wise. (Appropriate focus and keyboard management will be added as needed via JS.)
<form id="select-design" aria-label="Design Options">
<h2>Choose an image</h2>
<div role="radiogroup" id="collections-list" aria-label="Options" tabindex="0">
<fieldset id="group-1">
<legend>Artist: Jack Kirby</legend>
<div role="radio" aria-checked="false" tabindex="-1">
<img src="//placehold.it/200x200/bada55/fff" alt="Cool Picture">
</div>
<div role="radio" aria-checked="false" tabindex="-1">
<img src="//placehold.it/200x200/0de/fff" alt="Also Cool Picture">
</div>
</fieldset>
<fieldset id="group-2">
<legend>Artist: Kevin Maguire</legend>
<div role="radio" aria-checked="false" tabindex="-1">
<img src="//placehold.it/200x200" alt="Nice Art">
</div>
<div role="radio" aria-checked="false" tabindex="-1">
<img src="//placehold.it/200x200/0cd/fff" alt="Nicer Art">
</div>
</fieldset>
</div>
And here it is as a codepen.
One issue I'm seeing is that with my current html, it reads the first radio button as "2 of 3" - I guess it's treating the legend as a radioitem by default due to its placement in the DOM. Overall, it works, but I feel like it could be better.
Any thoughts?
Would be especially grateful if any screen-reader users can weigh in on this one.
Agree with #stringy about using native radio buttons (see first rule of ARIA use) But if you must create custom radio buttons you need to use the aria attribute aria-setsize on each control (also suggest looking at the accessible custom control checklist):
<fieldset id="group-1">
<legend>Artist: Jack Kirby</legend>
<div role="radio" aria-checked="false" tabindex="-1" aria-setsize="2">
<img src="//placehold.it/200x200/bada55/fff" alt="Cool Picture">
</div>
<div role="radio" aria-checked="false" tabindex="-1" aria-setsize="2">
<img src="//placehold.it/200x200/0de/fff" alt="Also Cool Picture">
</div>
</fieldset>
In regards to the outer <div> This in itself is not a radiogroup it groups 2 sets of radiogroups (which don't need to be specified using role=radiogroup as you are using fieldset/legend)
So suggest using role=group and removing the tabindex=0 as the div container isn't itself an interactive object and should not be in the focus order:
<div role="group" id="collections-list" aria-label="Options">
#jack if all radiobuttons are part of same group, then they should be containing within a single fieldset/legend or role=radiogroup with accessible name (via aria-label or aria-labelledby) then wrap each of the 3 sub groups in
<div role=group aria-label="whatever">
Part of the problem is that you are relying on <div> elements to create your form instead of standard form elements. If you change to <input type="radio"> as Andre suggests, you can use a matching name attribute to associate the radios.
This way the keyboard and screenreader software can tell how many inputs there are in the group even if they are separated by other markup. All of the HTML form elements have full keyboard support and focus states, which reduces the amount of scripting you have to do.
Inputs should also have a label, so that's a natural home for your image and any other details of the option. And you tell the browser (and therefore screenreaders) which label belongs to which input by pairing their for/id attributes.
E.g.
<p>Artist: Jack Kirby</p>
<input type="radio" name="A1" value="p1" id="p1">
<label for="p1"><img src="pic1.jpg" alt="Title of artwork" /></label>
<input type="radio" name="A1" value="p2" id="p2">
<label for="p2"><img src="pic2.jpg" alt="Title of artwork" /></label>
<p>Artist: Kevin Maguire</p>
<input type="radio" name="A1" value="p3" id="p3">
<label for="p3"><img src="pic3.jpg" alt="Title of artwork" /></label>
<input type="radio" name="A1" value="p4" id="p4">
<label for="p4"><img src="pic4.jpg" alt="Title of artwork" /></label>
Different HTML elements carry different useful information to the browser, and div elements are mostly just an empty box to contain other elements. ARIA works best when you've got unique widgets you can't replicate with meaningful markup, but it's much easier to make things accessible when you can use the right HTML for the job. MDN's HTML guide that I linked above has heaps of useful information for this kind of thing.
What are the advantages of using the <fieldset> tag?
I don't really get what it is used for.
Forms are often broken up into various sets of fields.
The fieldset tag allows you to logically group sets of fields in order that your forms be more descriptive.
You'll also note that you can use the fieldset to style your forms and display those logical associations between fields.
Just like forms you find in the "real" world.
The "advantages" of using a fieldset are that they allow you to mark up your data (in this case a form) in the most semantic way available. Consider that placing your fields in a fieldset is more descriptive than placing your fields in a div. The div tells you nothing about the relationship between the fields, a fieldset tells you there is a relationship.
It's a similar principle to many of the new HTML5 tagsets. <footer> for example tells you more about the meaning of the data inside it compared to an ambiguous <div>.
If you take a look at the HTML5 spec for Developers:
http://developers.whatwg.org/forms.html#the-fieldset-element
The fieldset element represents a set
of form controls optionally grouped
under a common name.
(there's a lot more information if you follow the link)
Combined with the legend element, it allows you to easily do this, which is difficult to recreate without using fieldset/legend:
It allows you to group a set of related fields and give them a legend.
<fieldset>
<legend>Gender</legend>
<input type="radio" name="gender" id="male" value="male">
<label for="male">Male</label>
<input type="radio" name="gender" id="female" value="female">
<label for="female">Female</label>
<fieldset>
<fieldset>
<legend>Address</legend>
<label for="line1">Line 1</label>
<input name="address1" id="line1">
<label for="line2">Line 2</label>
<input name="address2" id="line2">
<label for="town">Town</label>
<input name="town" id="town">
<label for="country">country/label>
<input name="country" id="country">
</fieldset>
You group stuff together with it. Which is useful if you need to access things in it for CSS or JavaScript, and don't want to go through the hassle of assigning ID's to everything.
Also, the legend looks pretty good.