does angularJS use a different set of rules for ARIA? - html

im working on updating a site for compliance. the site is mostly AngularJS which im still new to but learning. i found a situation where there is a label targeting a div tag however the label has no :for attribute, instead has an :id and the div has a :label-id targeting the :id of the label tag...when i tried to adjust it, it broke on the front-end so im not sure what im seeing...im curious if this will pass WCAG AA?
i have tried a screen reader, NVDA, no issues...however a crawler i used flagged the label element for not having a :for attribute...i have tried searching for the :label-id attribute with no luck which im guessing means its custom...im guessing a lot of the issue is related to my lack of understanding angularJS...
<div class="groupA">
<label id="elementA">Element A is for Apple</label>
<div class"customSelectA" label-id="elementA">...stuff shows up here after clicking the label and there are also a bunch of angular attributes on this div that are not relevant to my question</div>
</div>

I'd recommend going to the basics and ignoring angular for the moment.
Look at the spec for the <label> element. It has a for attribute that can point to a form element. The ID must point to a "labelable element" (<input>, <button>, <select>, etc).
So the following is valid:
<label for="myID">Element A is for Apple</label>
<input id="myID" type="checkbox">
but the following is not:
<label for="myID">Element A is for Apple</label>
<div id="myID"></div>
In fact, if you run the above example through an html validator, https://validator.w3.org/nu, it will flag it in error:
Error: The value of the for attribute of the label element must be the ID of a non-hidden form control.
Regarding the label-id attribute, it does not exist. It's not part of the html language. It appears to be a custom attribute but custom attributes should start with "data-".
You can have a <label> without a for attribute such as:
<label id="newID">Element A is for Apple</label>
<input type="checkbox" aria-labelledby="newID">
In this case, the <input> points back to the <label> instead of the <label> pointing to the <input>, but that's a poor use of the <label> element. You won't gain the benefit of the <label>. The first example lets you click on the text of the <label> and the checkbox will be selected. In the last example, while the checkbox will be labeled by the text, you can't click on the text to select the checkbox.

Related

for and id attributes in HTML to connect the element

I saw the code below, in one of my studying codes:
<form>
<label for="firstName">First Name:(click here cause cursor go inside the input box)</label>
<input id="firstName" type="text">
</form>
I find that the pair of for and id attributes connect the label and input element in the way that the cursor goes inside the input box automatically by clicking on label.
Which other pair of HTML elements can be connected to each other by the for and id attributes set? If it works for many other HTML elements, is there any list or source of the default action occurred by connecting one of them in each pair element?
According to w3school, we can use for with <label> and <output> element. Here is the link.
Adding a for is important, even if they are adjacent. I seem to recall hearing that some screen readers for the visually impaired have problems otherwise. So if you want to be friendly to those who are perhaps using alternate browsers/screen readers, use this method.

How do I make my custom checkbox accessible?

I'm trying to implement more accessibility to the website I'm working on. I have a custom checkbox inside a button, followed by a list of checkboxes. When I'm using a screenreader, I expect the screen reader to tell me whenever a checkbox is unmarked/marked. This works for all the checkboxes, except the one inside my button. The purpose of the button is to mark/unmark all other checkboxes in the list (this is done by JavaScript). Everything works, except the screenreader is not saying anything when I unmark/mark it.
Here the code:
<button id="checkAll" class="btn btn-default checkAll checkAllInit"
data-target="#everyCheckbox">
<span class="icon icm icm-checkbox_select" role="checkbox"></span>
<span class="text">Unmark all</span></button>
What follows is basically a list of checkboxes, which all can be reached and understood by keyboard navigation and the screen reader. It's just the button that won't give the correct feedback.
Any suggestions appreciated.
It's not valid html. You can use https://validator.w3.org/nu/ to check your code. A <button> cannot have any interactive components nested in it. See https://www.w3.org/TR/html53/sec-forms.html#the-button-element
Content model: Phrasing content, but there must be no interactive
content descendant.
This will confuse the screen reader. You either need a simple button or a simple checkbox.
If you're not using a native <input type='checkbox'>, then you need role='checkbox' and aria-checked. Just toggle the value of aria-checked between true and false in your javascript and the screen reader will announce the change.
First of all, a button element cannot contain any "interactive content", i.e. no other form controls, audio elements, video elements, etc.
Ideally, you should use native HTML elements, i.e. a form element to wrap around the checkboxes and buttons, and the input element with its type set to checkbox. You'll also need to associate labels with the checkboxes. With these native elements, you don't need WAI-ARIA attributes such as role='checkbox' and aria-checked; these WAI-ARIA attibutes are actually redundant (see e.g. the article On HTML belts and ARIA braces .)
If you have good reasons to create custom checkboxes using a combination span, CSS and JavaScript, you will need additional markup to make these checkboxes accessible:
tabindex="O" to make sure that keyboard users can reach the checkbox,
role='checkbox' to enable screen readers to figure out what type of element they are dealing with,
aria-checked (with the values true or false) to enable screen readers to figure out the state of the checkbox,
aria-labelledby to associate a "label" with the checkbox.
As you can see, if you use custom elements where HTML has native elements, you create a lot of extra work for yourself.
Please see this code for better understanding that how to write accessible checkboxes.
Please define the checkboxes like this:
<h1>Show checkboxes:</h1>
<form action="/action_page.php">
<input type="checkbox" name="vehicle1" value="Bike"> I have a bike<br>
<input type="checkbox" name="vehicle2" value="Car"> I have a car<br>
<input type="checkbox" name="vehicle3" value="Boat" checked> I have a boat<br><br>
<input type="submit" value="Submit">
</form>
</body>
</html>
By using this method the checkboxes will be properly accessible by default and also, screen reader will announce the state.
If there are custom checkboxes which are to be made accessible, then please refer:
https://webdesign.tutsplus.com/tutorials/how-to-make-custom-accessible-checkboxes-and-radio-buttons--cms-32074

How to use a block element as a HTML form label?

The HTML tag <label> may not contain block elements by definition. The following code is wrong in HTML 4, although ist works in most browsers:
<input type="radio" value="A" name="ABC" id="ABC_A">
<label for="ABC_A">
<p>Option A</p>
<p>Having a good time with HTML.</p>
</label>
I could make a block element from the <label> via CSS, but this still remains invalid HTML code. And in some instances, it makes sense to format one label into multiple paragraphs.
My question is: Is there a valid way in HTML to use block elements as a label for an input?
Possible workarounds, that I have considered inappropriate are:
Creating one label within each paragraph (why should one input have a dozend labels - and which one should a screen reader read, then?)
Using JavaScript to have the input "clicked" when the block element is clicked. I am searching for a solution that will work without scripting (and that is supported by vommon screen readers)
And ideas? Thank you!

Is putting form fields inside label tags a good or bad idea?

I notice this trend in a lot of frameworks, auto-generated code (Zend) and layout templates. The approach I'm talking about is such:
<label for="someField">
<input id="someField" name="someName" />
</label>
What are the pros and cons of this approach vs. the regular one, and why do people tend to take this approach at all?
It seems to be fine judging by W3C standards in both HTML4.01 and HTML5:
HTML4:
"To associate a label with another control implicitly, the control
element must be within the contents of the LABEL element. In this
case, the LABEL may only contain one control element. The label itself
may be positioned before or after the associated control."
In this example, we implicitly associate a labels with a text input control:
<form action="..." method="post">
<p>
<label>
First Name
<input type="text" name="firstname">
</label>
</p>
</form>
It is still fine as of HTML5:
"The label element represents a caption in a user interface. The
caption can be associated with a specific form control, known as the
label element's labeled control, either using the for attribute, or by
putting the form control inside the label element itself. - W3C.

Should I put input elements inside a label element?

Is there a best practice concerning the nesting of label and input HTML elements?
classic way:
<label for="myinput">My Text</label>
<input type="text" id="myinput" />
or
<label for="myinput">My Text
<input type="text" id="myinput" />
</label>
From the W3's HTML4 specification:
The label itself may be positioned before, after or around the
associated control.
<label for="lastname">Last Name</label>
<input type="text" id="lastname" />
or
<input type="text" id="lastname" />
<label for="lastname">Last Name</label>
or
<label>
<input type="text" name="lastname" />
Last Name
</label>
Note that the third technique cannot be used when a table is being used for layout, with the label in one cell and its associated form field in another cell.
Either one is valid. I like to use either the first or second example, as it gives you more style control.
I prefer
<label>
Firstname
<input name="firstname" />
</label>
<label>
Lastname
<input name="lastname" />
</label>
over
<label for="firstname">Firstname</label>
<input name="firstname" id="firstname" />
<label for="lastname">Lastname</label>
<input name="lastname" id="lastname" />
Mainly because it makes the HTML more readable. And I actually think my first example is easier to style with CSS, as CSS works very well with nested elements.
But it's a matter of taste I suppose.
If you need more styling options, add a span tag.
<label>
<span>Firstname</span>
<input name="firstname" />
</label>
<label>
<span>Lastname</span>
<input name="lastname" />
</label>
Code still looks better in my opinion.
Behavior difference: clicking in the space between label and input
If you click on the space between the label and the input it activates the input only if the label contains the input.
This makes sense since in this case the space is just another character of the label.
div {
border: 1px solid black;
}
label {
border: 1px solid black;
padding: 5px;
}
input {
margin-right: 30px;
}
<p>Inside:</p>
<label>
<input type="checkbox" />
Label. Click between me and the checkbox.
</label>
<p>Outside:</p>
<input type="checkbox" id="check" />
<label for="check">Label. Click between me and the checkbox.</label>
Being able to click between label and box means that it is:
easier to click
less clear where things start and end
Bootstrap checkbox v3.3 examples use the input inside: http://getbootstrap.com/css/#forms Might be wise to follow them. But they changed their minds in v4.0 https://getbootstrap.com/docs/4.0/components/forms/#checkboxes-and-radios so I don't know what is wise anymore:
Checkboxes and radios use are built to support HTML-based form validation and provide concise, accessible labels. As such, our <input>s and <label>s are sibling elements as opposed to an <input> within a <label>. This is slightly more verbose as you must specify id and for attributes to relate the <input> and <label>.
UX question that discusses this point in detail: https://ux.stackexchange.com/questions/23552/should-the-space-between-the-checkbox-and-label-be-clickable
If you include the input tag in the label tag, you don't need to use the 'for' attribute.
That said, I don't like to include the input tag in my labels because I think they're separate, not containing, entities.
Personally I like to keep the label outside, like in your second example. That's why the FOR attribute is there. The reason being I'll often apply styles to the label, like a width, to get the form to look nice (shorthand below):
<style>
label {
width: 120px;
margin-right: 10px;
}
</style>
<label for="myinput">My Text</label>
<input type="text" id="myinput" /><br />
<label for="myinput2">My Text2</label>
<input type="text" id="myinput2" />
Makes it so I can avoid tables and all that junk in my forms.
See http://www.w3.org/TR/html401/interact/forms.html#h-17.9 for the W3 recommendations.
They say it can be done either way. They describe the two methods as explicit (using "for" with the element's id) and implicit (embedding the element in the label):
Explicit:
The for attribute associates a label with another control explicitly: the value of the for attribute must be the same as the value of the id attribute of the associated control element.
Implicit:
To associate a label with another control implicitly, the control element must be within the contents of the LABEL element. In this case, the LABEL may only contain one control element.
Both are correct, but putting the input inside the label makes it much less flexible when styling with CSS.
First, a <label> is restricted in which elements it can contain. For example, you can only put a <div> between the <input> and the label text, if the <input> is not inside the <label>.
Second, while there are workarounds to make styling easier like wrapping the inner label text with a span, some styles will be in inherited from parent elements, which can make styling more complicated.
3rd party edit
According to my understanding html 5.2 spec for label states that the labels Content model is Phrasing content. This means only tags whose content model is phrasing content <label> are allowed inside </label>.
Content model A normative description of what content must be included
as children and descendants of the element.
Most elements that are categorized as phrasing content can only
contain elements that are themselves categorized as phrasing content,
not any flow content.
A notable 'gotcha' dictates that you should never include more than one input element inside of a <label> element with an explicit "for" attribute, e.g:
<label for="child-input-1">
<input type="radio" id="child-input-1"/>
<span> Associate the following text with the selected radio button: </span>
<input type="text" id="child-input-2"/>
</label>
While this may be tempting for form features in which a custom text value is secondary to a radio button or checkbox, the click-focus functionality of the label element will immediately throw focus to the element whose id is explicitly defined in its 'for' attribute, making it nearly impossible for the user to click into the contained text field to enter a value.
Personally, I try to avoid label elements with input children. It seems semantically improper for a label element to encompass more than the label itself. If you're nesting inputs in labels in order to achieve a certain aesthetic, you should be using CSS instead.
As most people have said, both ways work indeed, but I think only the first one should. Being semantically strict, the label does not "contain" the input. In my opinion, containment (parent/child) relationship in the markup structure should reflect containment in the visual output. i.e., an element surrounding another one in the markup should be drawn around that one in the browser. According to this, the label should be the input's sibling, not it's parent. So option number two is arbitrary and confusing. Everyone that has read the Zen of Python will probably agree (Flat is better than nested, Sparse is better than dense, There should be one-- and preferably only one --obvious way to do it...).
Because of decisions like that from W3C and major browser vendors (allowing "whichever way you prefer to do it", instead of "do it the right way") is that the web is so messed up today and we developers have to deal with tangled and so diverse legacy code.
I usually go with the first two options. I've seen a scenario when the third option was used, when radio choices where embedded in labels and the css contained something like
label input {
vertical-align: bottom;
}
in order to ensure proper vertical alignment for the radios.
I greatly prefer to wrap elements inside my <label> because I don't have to generate the ids.
I am a Javascript developer, and React or Angular are used to generate components that can be reused by me or others. It would be then easy to duplicate an id in the page, leading there to strange behaviours.
Referring to the WHATWG (Writing a form's user interface) it is not wrong to put the input field inside the label. This saves you code because the for attribute from the label is no longer needed.
One thing you need to consider is the interaction of checkbox and radio inputs with javascript.
Using below structure:
<label>
<input onclick="controlCheckbox()" type="checkbox" checked="checkboxState" />
<span>Label text</span>
</label>
When user clicks on "Label text" controlCheckbox() function will be fired once.
But when input tag is clicked the controlCheckbox() function may be fired twice in some older browsers. That's because both input and label tags trigger onclick event attached to checkbox.
Then you may have some bugs in your checkboxState.
I've run into this issue lately on IE11. I'm not sure if modern browsers have troubles with this structure.
There are several advantages of nesting the inputs into a label, especially with radio/checkbox fields,
.unchecked, .checked{display:none;}
label input:not(:checked) ~ .unchecked{display:inline;}
label input:checked ~ .checked{display:inline;}
<label>
<input type="checkbox" value="something" name="my_checkbox"/>
<span class="unchecked">Not Checked</span>
<span class="checked">Is Checked</span>
</label>
As you can see from the demo, nesting the input field first followed by other elements allows,
The text to be clicked to activate the field
The elements following the input field to be dynamically styled according to the status of the field.
In addition, HTML std allows multiple labels to be associated with an input field, however this will confuse screen readers and one way to get round this is to nest the input field and other elements within a single label element.