Related
Consider the following:
<label>Range from
<input name='min_value'/> to
<input name='max_value' />
</label>
Is this semantically correct since the W3C recommendations state that a label is associated with exactly one form control?
Clicking into the second input shifts focus immediately to the first input? Can this be prevented?
How would one markup a min/max input combination to show that two inputs belong together?
No, it's not correct (since, as you note, a label is associated with exactly one form input).
To label a group of inputs that belong together, use a <fieldset> and a <legend>:
<fieldset>
<legend>Range</legend>
<label for="min">Min</label>
<input id="min" name="min" />
<label for="max">Max</label>
<input id="max" name="max" />
</fieldset>
References:
<input />HTML 5 spec.
<fieldset>HTML 5 spec.
<label>HTML 5 spec.
<legend>HTML 5 spec.
As the accepted answer states, that's not correct, however I think there are better ways to do it.
Accessible alternatives:
Option 1 (using the aria-label attribute):
Range:
<input ... aria-label='Range start' />
<input ... aria-label='Range end' />
Option 2 (using hidden label tags):
<label for='start'>Range start</label>
<input type='text' id='start' />
<label for='end' class='hidden'>Range end</label>
<input type='text' id='end' />
Where the .hidden class is only readable by screen readers.
Option 3 (using aria-labelledby attributes):
<label id='lblRange'>Range</label>
<input type='text' id='start' aria-labelledby='lblRange' />
<input type='text' id='end' aria-labelledby='lblRange' />
Advantages of option #1: Each input has a good description that other suggestions (such adding a "to" label) do not. Options #2 and #3 might not be the best for this specific case, but worth mentioning for similar cases.
Source: http://webaim.org/techniques/forms/advanced
I see many answers saying it is wrong to put 2 inputs inside a label.
This is actually a wrong statement in html5. The standard explicitly allow it:
http://www.w3.org/TR/html5/forms.html#the-label-element
If the for attribute is not specified, but the label element has a labelable element descendant, then the first such descendant in tree order is the label element’s labeled control.
If a label element has interactive content other than its labeled control, the activation behavior of the label element for events targeted at those interactive content descendants and any descendants of those must be to do nothing.
However, Safari does not respect the html5 standard here (tested on iOS 11.3). So, someone that wants to be compatible with Safari must use workarounds here or wait until Apple fixes its browser.
According to this - label can contain only one input as it should be associated with only one control. Putting input inside the label means elimination of for attribute (automatic linking).
So you should either put single input into label or specify for attribute which points to input id and don't put input into label.
How about this:
<label> Range from <input name='min_value'> </label>
<label> to <input name='max_value'> </label>
1 LABEL = 1 INPUT !!!
If you put 2 INPUTS inside a LABEL, it will NOT work in Safari (and iPad and iPhone)... because when you click inside LABEL it automatically focuses the first INPUT... so the second input is impossible to type to.
I see many answers saying it is wrong to put 2 inputs inside a label. This is actually a wrong statement in html5. The standard explicitly allow it: http://www.w3.org/TR/html5/forms.html#the-label-element
<label id='dobRange'>DOB between</label>
<input type='text' id='start' aria-labelledby='dobRange' />
<input type='text' id='end' aria-labelledby='dobRange' />
in haml:
= f.label :dob_range
= f.search_field :dob_gteq, 'aria-label': 'dob_range'
= f.search_field :dob_lteq, 'aria-label': 'dob_range'
i don't think you should be putting the input field inside the label control.
<label for="myfield">test</label><input type="text" id="myfield" name="myfield />
the label is just that, a label for something.
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
Any way to provide a separate tabIndex order for accessible elements in HTML5 using WAI-ARIA?
Usecase: Lets take a case where a multiple choice question is rendered in HTML. It can have a question text, radio buttons with labels, and a submit button.
Here only radio buttons and submit button should be tabbable. Whereas all three components should be accessible for screen readers. Question text should be read before the radio button labels are read.
As an example, please check a question in the following link http://www.html5tests.com/tests/intro/intro-00.php
How should we use aria in such a case.
The Using WAI-ARIA in HTML Spec provides some practical guides about using ARIA. As written on that spec the first rule of ARIA use is:
If you can use a native HTML element [HTML5] or attribute with the semantics and behaviour you require already built in, instead of re-purposing an element and adding an ARIA role, state or property to make it accessible, then do so.
In your case, the <fieldset> HTML element has all your requirements built-in so I would use <fieldset> rather than using something else and re-purposing it with ARIA. Here is an example implementation:
<fieldset>
<legend>We hear that the internet is based on HTML. What is HTML exactly?</legend>
<p>
<input type="radio" name="HTML" id="option1" />
<label for="option1">HTML is a protocol that is used to route data across the internet, via TCP/IP.</label>
</p>
<p>
<input type="radio" name="HTML" id="option2" />
<label for="option2">HTML is a text-based language that is used to structure and present content on the world wide web.</label>
</p>
<p>
<input type="radio" name="HTML" id="option3" />
<label for="option3">HTML is a binary file format that codes web pages for use on the Internet.</label>
</p>
<p>
<input type="radio" name="HTML" id="option4" />
<label for="option4">HTML is a disk file system used in modern operating systems.</label>
</p>
</fieldset>
<input type="submit" value="Submit Answer" />
Keep in mind that this doesn't mean that you have to choose between a native HTML element and ARIA. Always pick the most semantic element first and if you still have additional requirements complement that element with ARIA.
You can find more information about the fieldset technique on this article: H71: Providing a description for groups of form controls using fieldset and legend elements.
I have seen this in jQuery - what does it do?
<label for="name"> text </label>
<input type="text" name="name" value=""/>
The for attribute is used in labels. It refers to the id of the element this label is associated with.
For example:
<label for="username">Username</label>
<input type="text" id="username" name="username" />
Now when the user clicks with the mouse on the username text the browser will automatically put the focus in the corresponding input field. This also works with other input elements such as <textbox> and <select>.
Quote from the specification:
This attribute explicitly associates the label being defined with
another control. When present, the value of this attribute must be the
same as the value of the id attribute of some other control in the
same document. When absent, the label being defined is associated with
the element's contents.
As far as why your question is tagged with jQuery and where did you see it being used in jQuery I cannot answer because you didn't provide much information.
Maybe it was used in a jQuery selector to find the corresponding input element given a label instance:
var label = $('label');
label.each(function() {
// get the corresponding input element of the label:
var input = $('#' + $(this).attr('for'));
});
To associate the <label> with an <input> element, you need to give the <input> an id attribute. The <label> then needs a for attribute whose value is the same as the input's id:
<label for="username">Click me</label>
<input type="text" id="username">
The for attribute associates a <label> with an <input> element; which offers some major advantages:
1. The label text is not only visually associated with its corresponding text input; it is programmatically associated with it too. This means that, for example, a screen reader will read out the label when the user is focused on the form input, making it easier for an assistive technology user to understand what data should be entered.
2. You can click the associated label to focus/activate the input, as well as the input itself. This increased hit area provides an advantage to anyone trying to activate the input, including those using a touch-screen device.
Alternatively, you can nest the <input> directly inside the <label>, in which case the for and id attributes are not needed because the association is implicit:
<label>Click me <input type="text"></label>
Notes:
One input can be associated with multiple labels.
When a <label> is clicked or tapped and it is associated with a form control, the resulting click event is also raised for the associated control.
Accessibility concerns
Don't place interactive elements such as anchors or buttons inside a label. Doing so, makes it difficult for people to activate the form input associated with the label.
Headings
Placing heading elements within a <label> interferes with many kinds of assistive technology, because headings are commonly used as a navigation aid. If the label's text needs to be adjusted visually, use CSS classes applied to the <label> element instead.
If a form, or a section of a form needs a title, use the <legend> element placed within a <fieldset>.
Buttons
An <input> element with a type="button" declaration and a valid value attribute does not need a label associated with it. Doing so may actually interfere with how assistive technology parses the button input. The same applies for the <button> element.
Ref:
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label
I feel the need to answer this. I had the same confusion.
<p>Click on one of the text labels to toggle the related control:</p>
<form action="/action_page.php">
<label for="female">Male</label>
<input type="radio" name="gender" id="male" value="male"><br>
<label for="female">Female</label>
<input type="radio" name="gender" id="female" value="female"><br>
<label for="other">Other</label>
<input type="radio" name="gender" id="other" value="other"><br><br>
<input type="submit" value="Submit">
</form>
I changed the for attribute on the 'male' label to female. Now, if you click 'male' the 'female' radio will get checked.
Simple as that.
a fast example:
<label for="name">Name:</label>
<input id="name" type="text" />
the for="" tag let focus the input when you click the label as well.
You use it with labels to say that two objects belong together.
<input type="checkbox" name="remember" id="rememberbox"/>
<label for="rememberbox">Remember your details?</label>
This also means that clicking on that label will change the value of the checkbox.
FYI - if you are in an typescript environment with e.g.
<label for={this.props.inputId}>{this.props.label}</label>
you need to use htmlFor
<label htmlFor={this.props.inputId}>{this.props.label}</label>
it is used for <label> element
it is used with input type checkbox or redio to select on label click
working demo
The for attribute of the <label> tag should be equal to the id attribute of the related element to bind them together.
It associates the label with an input element. HTML tags are meant to convey special meaning to users of various categories. Here is what label is meant for:
For people with motor disabilities (also for general mouse users): Correctly used label tags can be clicked to access the associated form control. Eg. Instead of particularly clicking the checkbox, user can click on more easily clickable label and toggle the checkbox.
For visually-challenged users: Visually challenged users use screen-readers that reads the associated label tag whenever a form control is focused. It helps users to know the label which was otherwise invisible to them.
More about labelling -> https://www.w3.org/TR/WCAG20-TECHS/H44.html
it is used in <label> text for html
eg.
<label for="male">Male</label>
<input type="radio" name="sex" id="male" value="male"><br>
It's the attribute for <label> tag : http://www.w3schools.com/tags/tag_label.asp
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.