Issue with checkbox aria-label which is coming as blank - html

I have the following code:
<label class="el-checkbox el-transfer-panel__item"><span class="el-checkbox__input"><span class="el-checkbox__inner"></span><input type="checkbox" aria-hidden="false" class="el-checkbox__original" value="6" aria-labelledby="checkbox_5" id="checkbox_5"></span><span class="el-checkbox__label"><span>Total amount due</span><!----></span></label>
Every time I move my keys over it, the speech viewer shows blank. I tried many ways to fix it but its always showing the blank

The issue here is in how you are using aria-labelledby. This property should point to the ID of something which describes the item. In your code, you are pointing the element at itself which doesn't give it any details to work with.
The <label> property is what a screen-reader would refer to and that requires a for="" value (which your markup doesn't have). The code below illustrates a better way to approach this for accessibility.
<label for="checkboxID">
<div class="el-checkbox__input">
<div class="el-checkbox__inner"></div>
<input type="checkbox" name="checkboxName" id="checkboxID"> <span class="el-checkbox__label">Total amount due</span>
</div>
</label>
I have swapped the <span> tags for <div> because span tags should only be used for inline elements and shouldn't be used to wrap around block-level elements (such as the <input>).
Here's an example from the MDN of how you could use aria with a checkbox:
<span role="checkbox" aria-checked="false" tabindex="0" aria-labelledby="tac"></span>
<span id="tac">I agree to the Terms and Conditions.</span>

Related

What is the appropriate semantic markup for form label help sub-text

Some form elements in a form may require text to explain the function of said element. I'm thinking of encapsulating this text in a paragraph element, as follows,
label p {
margin-top: -1px;
font-size: smaller;
}
<div class="form-group">
<label for="form-input-1">Label Text
<p>Label explainer/help text</p>
</label>
<input id="form-input-1" />
</div>
My question is: is the <p> element the most semantic element for this use? In my opinion, the label sub-text is a type of sub-title and one could argue that it may call for a <h*> element. But, these are often used for outlines, and I don't believe this would be super semantic here. Would a <span>, make sense here, as these may be used to mark off parts of inline flow elements?
Please, share your thoughts!
<label> elements can only contain phrasing content, which means they can't contain headings or paragraph elements, which are flow content.
Additionally, the MDN Docs note that headings should not be used within labels because that "interferes with many kinds of assistive technologies".
If additional form field instructions are needed beyond what would reasonably fit within a label, you should use a separate element, outside of the label—and tie it to the input using the aria-describedby attribute, as outlined on the W3C's Web Accessibility Tutorial on Form Instructions.
Here's an example of that approach:
form {
display: grid;
grid-gap: 0.5rem;
padding: 0.5rem;
}
<form>
<label for="input">Label Text</label>
<span id="instructions">Additional instructions lorem ipsum</span>
<input id="input" aria-describedby="instructions" type="text">
</form>
In complex forms there are mulitple sections, headings, hints, helper texts an so on used as explanation. So there are multiple ways to add descriptions and helper texts to a form:
<span> is the simplest form. Add it to the label-element.
<fieldset> with <legend> wraps fields together and adds a descripition.
<section> can give additional structure and information to a form.
<p> can be used to add addtional information i.e. to the whole form or a form-section
<div> is used by Google in Maerial Design for a text field helper line
Often done but NOT to be used for farer explanation should be texts in placeholders.
In your example I believe a span within the labelshould be a good solution which will match the semantic.
ADDITOINAL INFORMATION
Complex HTML code example from MDN:
<form method="post">
<h1>Payment form</h1>
<p>Required fields are followed by <strong><abbr title="required">*</abbr></strong>.</p>
<section>
<h2>Contact information</h2>
<fieldset>
<legend>Title</legend>
<ul>
<li>
<label for="title_1">
<input type="radio" id="title_1" name="title" value="A">
Ace
</label>
</li>
<li>
<label for="title_2">
<input type="radio" id="title_2" name="title" value="K" >
King
</label>
</li>
<li>
<label for="title_3">
<input type="radio" id="title_3" name="title" value="Q">
Queen
</label>
</li>
</ul>
</fieldset>
<p>
<label for="name">
<span>Name: </span>
<strong><abbr title="required">*</abbr></strong>
</label>
<input type="text" id="name" name="username">
</p>
<p>
<label for="mail">
<span>E-mail: </span>
<strong><abbr title="required">*</abbr></strong>
</label>
<input type="email" id="mail" name="usermail">
</p>
<p>
<label for="pwd">
<span>Password: </span>
<strong><abbr title="required">*</abbr></strong>
</label>
<input type="password" id="pwd" name="password">
</p>
</section>
<section>
<h2>Payment information</h2>
<p>
<label for="card">
<span>Card type:</span>
</label>
<select id="card" name="usercard">
<option value="visa">Visa</option>
<option value="mc">Mastercard</option>
<option value="amex">American Express</option>
</select>
</p>
<p>
<label for="number">
<span>Card number:</span>
<strong><abbr title="required">*</abbr></strong>
</label>
<input type="tel" id="number" name="cardnumber">
</p>
<p>
<label for="date">
<span>Expiration date:</span>
<strong><abbr title="required">*</abbr></strong>
<em>formatted as mm/dd/yyyy</em>
</label>
<input type="date" id="date" name="expiration">
</p>
</section>
<section>
<p> <button type="submit">Validate the payment</button> </p>
</section>
</form>
Link to see MDN form live:
https://mdn.github.io/learning-area/html/forms/html-form-structure/payment-form.html
Link to wider MDN explanations:
https://developer.mozilla.org/en-US/docs/Learn/Forms/How_to_structure_a_web_form#common_html_structures_used_with_forms*
Link to example Google Material Design:
https://material.io/develop/web/components/input-controls/text-field/helper-text
There doesn't seem to be any definitive answer or resource so you can only get opinions. Here's mine:
I'd start by thinking about how to markup the whole form. I think the semantic form style described in MDN article is a pretty good place to start. Especially the part that a form is logically a list of form controls so you should have <ul> and <li> elements wrapping the controls in semantic order. However, I think it has one problematic part where it uses logically markup like
<label><input>text</label>
for radio buttons, but
<label>text<input></label>
for text inputs. I'd highly prefer that the markup order doesn't change depending on the input type (checkbox/radio button vs text/email/password). To do that in practice, you probably want to always use markup like
<li class="checkbox">
<label for=id1>text</label>
<input id=id1>
</li>
which you can then style by using e.g. li.checkbox { display: flex; ... } and reorder the label and input visually as needed. Obviously the class is needed only for styling but it is not needed for semantics. If browsers ever implement :has() then there would be no need for a class at all.
As for the help text for the input, in theory, you would want to use
<li class="checkbox">
<label for=id1>text</label>
<input id=id1>
<label for=id1 class=help>help content here</label>
</li>
because by spec it should be possible to attach multiple labels to a single input. However, as far as I know, this doesn't work in practice with the software that's commonly used by blind people needing accessibility aids.
As such, the next question is how do you think this help text should be used by all the following groups?
Users with vision without JavaScript support. (Note that this group includes most search engines.)
Blind persons without JavaScript support.
Users with vision with JavaScript support. (Note that this group includes some search engines.)
As far as I know, there's no good answer to cater for all the 3 groups perfectly. Note that for practical support for a yet another group "Blind persons with JavaScript support" you can use any markup you want and use ARIA attributes to make it accessible. Overall, the best I can think of is as follows:
<li class="checkbox">
<label for=id1>text</label>
<input id=id1 aria-describedby=id2>
<aside id=id2>help content here</aside>
</li>
That should be good enough to attach the help content to the input for accessibility tools, the help content is semantically additional content so <aside> should be okay for both blind and visual users and you can use CSS only to make the <aside> visible only when the input is focused. Also note that <aside> allows any content for help, incuding videos in iframes, not just text. Of course, if you need user to click within the <aside> element you cannot use input:focus to toggle the element visible but you need to use some kind of JavaScript support. Exact details depend on which group you want to cater for most and if you want to have the help text available to all groups.
This markup also contains all the information you need to wrangle it as needed by JavaScript. For some non-JavaScript styling options you might want to wrap the label and input in some wrapper element so that you can position those as a group separate from <aside> element. In that case markup like
<li class="checkbox">
<div>
<label for=id1>text</label>
<input id=id1 aria-describedby=id2>
</div>
<aside id=id2>help content here</aside>
</li>
could be a good option. You can target that classless <div> element by selector form li.checkbox>div if needed. One could then use e.g. display:grid or subgrid for the li.checkbox and e.g. display:flex for the li.checkbox>div to position everything nicely. However, if you do that, you cannot nicely toggle the visibility of the help text simply by using style like input:not(:focus) + aside { display: none; }. I think you can survive without the wrapper <div> element if you use display:grid for li.checkbox because that allows positioning stuff in 2D unlike flex.
And if you need to support users with vision but without support for CSS, then I don't have a good solution. Using the above mentioned semantic list markup results in bullet points in addition to form inputs which could look pretty messy for non-CSS users.

Difference between for and aria-labeled-by

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>

Using <label for=""> with a HtmlHelper rendered element with an id that contains a space

If I have a plain checkbox <input> element with an id attribute that contains a space, I can still use <label for=""> to bind a label to the element, and then click on the label text to toggle the checkbox value:
<input type="checkbox" id="remember me" />
<label for="remember me">Remember me</label>
However, if I create the same <input> element using the HtmlHelper class, <label for=""> does not seem to bind the label to the label text. When I click on the label text, the checkbox does not toggle:
#Html.CheckBox("remember me")
<label for="remember me">Remember me</label>
Why is the behavior differing when I use HtmlHelper? Is it possible to use <label for=""> with a HtmlHelper rendered element that has an id that contains a space?
Please note, the main purpose of this question is to document something interesting that I discovered. According to HTML 5 standards, the id attribute should be at least one character, and should not contain any space characters. I came across some code that obviously didn't follow the W3C recommendations, and while cleaning it up, found a solution for the above problem, so I figured I may as well share what I found in case this can help someone in the future.
When the HtmlHelper creates the <input> element, it replaces all spaces in the id attribute with underscores.
If you inspect the rendered HTML code, you will see the the input element renders as follows:
<input id="remember_me" name="remember me" value="true" type="checkbox">
If you want to associate a label with the above element, therefore, you need to replace all spaces with underscores in the forstring:
#Html.CheckBox("remember me")
<label for="remember_me">Remember me</label>
Another way you can possibly avoid the above problem is by skipping the for="" attribute all together, and just wrapping the <label> tag around the entire input element:
<label>
#Html.CheckBox("remember me")
Remember me
</label>
I've found this solution to sometimes causes issues, however, if I had some CSS styles set for all label elements, and didn't want the styles applied to all the elements that the label surrounded.

What's an accessible way to group items within a radiogroup? (HTML5/WAI-ARIA)

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.

Is there a Standardized method of Form Accessibility and Semantics?

With so many articles on the "proper," "semantic," and "accessible" use of forms and architecture, I'm rethinking how I approach forms. There are literally so many variations of what is "right" that I'm not 100% on what is really accurate anymore.
In an MDN article (here), it mentions:
With this example, a screen reader will pronounce "Fruit juice size small" for the first widget, "Fruit juice size medium" for the second, and "Fruit juice size large" for the third.
<form>
<fieldset>
<legend>Fruit juice size</legend>
<p>
<input type="radio" name="size" id="size_1" value="small" />
<label for="size_1">Small</label>
</p>
<p>
<input type="radio" name="size" id="size_2" value="medium" />
<label for="size_2">Medium</label>
</p>
<p>
<input type="radio" name="size" id="size_3" value="large" />
<label for="size_3">Large</label>
</p>
</fieldset>
</form>
Now, I can see the benefit of this for something like the example above, however, say I made a multi-step shopping cart, I wouldn't want assistive technology to speak "Checkout: cc-number," "Checkout: cc-date" using "checkout" prior to every label. Especially in cases where steps are labelled. This would be repetitive and sometimes confusing I would assume... But I've always grouped sections of a form within a <fieldset>. Now I'm rethinking using fieldset and legend at all, but does it now go against semantics? What's the trade-off? Is there a balance?
Additionally, and I'll use the same MDN article so I'm not sending you all over the web,
Note that even without considering assistive technologies, having a
formal label set for a given widget lets users to click on the label
to activate the corresponding widget in all browsers. This is
especially useful for radio buttons and checkboxes.
Some assistive technologies can have trouble handling multiple labels
for a single widget. Because of this, you should nest a widget inside
its corresponding element to build an accessible form.
<form>
<p>
<input type="checkbox" id="taste_1" name="taste_cherry" value="1">
<label for="taste_1">I like cherry</label>
</p>
<p>
<label for="taste_2">
<input type="checkbox" id="taste_2" name="taste_banana" value="1">
I like banana
</label>
</p>
</form>
Now, in this instance, the labeling for both these items are reasonably common, I have used both methods, but is there a balance between accessibility and semantics here? I tend to put the label not wrapping the input for consistency in code and I know their is strong debate on this subject (mainly the ability to drop the for and not need the id and/or having labels in different areas of the markup). So, I'm not trying to rehash the debate here, I tend to use the for and id regardless if I wrap elements in a label or not. But if there is an accessibility concern for one then why isn't the latter the golden standard?
Yet another point, WAI-Aria rules now contribute, so how much do these rules really impact the accessibility and semantics of a form?
<p>Required fields are followed by <strong><abbr title="required">*</abbr></strong>.</p>
<form>
<fieldset>
<legend>Fruit juice size*</legend>
<p>
<label for="size_1">
<input type="radio" name="size" id="size_1" value="small" aria-labelledby="size_1_label" />
<span id="size_1_label" required aria-required="true">Small</span>
</label>
</p>
<p>
<label for="size_2">
<input type="radio" name="size" id="size_2" value="medium" aria-labelledby="size_2_label" />
<span id="size_2_label">Medium</span>
</label>
</p>
<p>
<label for="size_3">
<input type="radio" name="size" id="size_3" value="large" aria-labelledby="size_3_label" />
<span id="size_3_label">Large</span>
</label>
</p>
</fieldset>
</form>
I'm really just curious whether or not there is a standardized method of approach when dealing with Semantic and Accessible markup. So far it seems people just do whatever they feel is right and then vocalize their thoughts all over the internet.
I've read through W3C's drafts and recommendations but even they use varying examples. Does anyone have evidence of what approach really improves accessibility and semantics in relation to forms? Are their any particular websites that have the time an resources to test this and draw an accurate conclusion that I'd be able to review?
The answer to your question really is "it depends".
All of the accessible markup you list above is valid. So if you are simply looking for accessible markup, you can use any of the examples. The rest of the decisions really come down to
error handling, and
additional instructions
Error Handling
When errors appear in your form, they need to be programmatically associated with the form fields that they reference. There are two ways to do this while maintaining the label itself:
Add the error to the label
You can add the error text to the label itself. Having a wrapped label gives you more flexibility over the order that this error text occurs in the DOM. you can place the error before the label, after the label, after the input or before the input. For this reason, you might choose to use the wrapping technique instead of the non-wrapping technique:
<label>My Input
<input type="text" aria-invalid="true" id="myinput" name="myinput"/>
<span class="error">The input field must be a valid username</span>
</label>
Associate the error using ARIA
The second technique is to associate the error using ARIA. This is very flexible because it allows multiple elements to form the label of the input and can also be used for additional instructions.
<label id="mylabel">My Input</label>
<input type="text" aria-invalid="true" aria-labelledby="mylabel myerror"/>
<span id="myerror" class="error">The input field must be a valid username</span>
Now if your input is a checkbox or radio button, you will want to maintain the for and id association so that the user can click (or touch) the label in order to activate the checkbox/radio.
Additional Instructions
As mentioned above, using ARIA labelling techniques, you can associate multiple elements with a single input field. This is useful for providing additional instructions and hints. aria-labelledby is used for the accessible name (label) whereas aria-describedby can be used for a hint and can also reference multiple elements by using multiple ids.
<label id="mylabel">My Input</label>
<input type="text" aria-invalid="true" aria-labelledby="mylabel myerror" aria-describedby="unameinstructions"/>
<span id="myerror" class="error">The input field must be a valid username</span>
<span id="unameinstructions">A valid user name must contain at least one alpha, one numeric character and must be at least 8 characters</span>
Here is a presentation I created on accessible dynamic forms http://www.slideshare.net/dylanbarrell/accessible-dynamic-forms-27169766 it references some example code that can be found here https://github.com/dylanb/a11yvalid and the running example of good best practices (except perhaps the CSS styling choices) can be found here http://dylanb.github.io/bower_components/a11yfy/examples/form-validation.html