What's the point in using <legend>>?
It looks to be the same as a <p> tag, although it cannot be nested inside a div?
Is there a reason to use it?
A legend describes the content of a fieldset.
<fieldset>
<legend>What pets do you like?</legend>
<label> <input type="checkbox" name="pet" value="cats"> Cats </label><br>
<label> <input type="checkbox" name="pet" value="dogs"> Dogs </label><br>
<label> <input type="checkbox" name="pet" value="etc"> Etc </label>
</fieldset>
It has the semantic association with the form controls in that fieldset.
This allows, for example, screen readers to announce the question with each of the possible answers to provide context to what the answers are for.
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.
According to the HTML5 Doctor:
The label 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 for attribute, or by putting the form
control inside the label element itself.
So putting this into a context with radio buttons. In an example of asking you to choose a favourite fruit in a form, if I were to say that the label "Apple" is the <label> for its radio button, to make the label clickable, I would put the radio control inside, such as:
<label>
<input type="radio" name="fruit" value="apple"/> Apple
</label>
And since the <label> element in their example is also shown as the label for the entire input value, that shows my question "Your favourite fruit?" going into a label, thus making the whole section just full of labels?
<label>Your favourite fruit?</label>
<label>
<input type="radio" name="fruit" value="apple"/> Apple
</label>
<label>
<input type="radio" name="fruit" value="banana"/> Banana
</label>
<label>
<input type="radio" name="fruit" value="watermelon"/> Watermelon
</label>
Is that correct?
And then also the for attribute on that first <label> that holds the question in their example refers to the id of the element. But I cannot do that since I have 3 elements, so that means it's impossible for me to use the for attribute?
The semantic way to tackle this would be to group the radio buttons with a fieldset element.
<fieldset>
<legend>Your favourite fruit?</legend>
<label>
<input type="radio" name="fruit" value="apple"/> Apple
</label>
<label>
<input type="radio" name="fruit" value="banana"/> Banana
</label>
<label>
<input type="radio" name="fruit" value="watermelon"/> Watermelon
</label>
</fieldset>
This approach to your scenario is recommended by the W3C's Accessibility Tutorials: https://www.w3.org/WAI/tutorials/forms/grouping/ and MDN's Fieldset Article: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset
The default rendering of fieldsets can be improved with CSS. One example of that is here https://design-system.service.gov.uk/components/radios/
I have a question in HTML form and radioboxes as answers, like this:
<span>What is your favorite fruit?</span>
<input type="radio" name="favFruit" id="banana"><label for="banana">Banana</label>
<input type="radio" name="favFruit" id="orange"><label for="orange">Orange</label>
But I realised, that question is not connected with answers, which is probably bad for SEO, accessibility and and could be bad for future maintenance of application. So I added aria-describedby attribute:
<span id="favFruitQuestion">What is your favorite fruit?</span>
<input type="radio" name="favFruit" id="banana" aria-describedby="favFruitQuestion">
<label for="banana">Banana</label>
<input type="radio" name="favFruit" id="orange" aria-describedby="favFruitQuestion">
<label for="orange">Orange</label>
But at Mozilla Developer Network I found article How to structure an HTML form, when advice is to wrap answers in fieldset tag ans put question in legend tag:
<fieldset>
<legend>What is your favourite fruit?</legend>
<input type="radio" name="favFruit" id="banana"><label for="banana">Banana</label>
<input type="radio" name="favFruit" id="orange"><label for="orange">Orange</label>
</fieldset>
But it could not be trustworthy at 100%, because, because there is written:
This article is in need of a technical review.
Is it really a best way to indicate a question with radioboxes as answers? If it's not, what is the best way? Thank you in advance for every answer.
Yes. <legend> / <fieldset> is the correct tool to use.
Avoid overlong legends though. Some screen readers will read out the entire legend before each label.
I would like to know if I could insert a legend inside a header. This way the legend can have also its hierarchy related to the whole document.
I have more text below which is relevant but needs to be highlighted for the readers. In this case personal information would be legend and h2 at the same time. h1 would be another element in the site which I chose not to display.
<fieldset>
<h2>
<legend>Personal information</legend>
</h2>
<h3>
Credentials
</h3>
<label for="username">
Username
</label>
<input id="username" type="text">
<label for="surname">
Surname
</label>
<input id="surname" type="text">
<h3>
Contact details
</h3>
<label for="street">
Street
</label>
<input id="street" type="text">
<label for="house-number">
House number
</label>
<input id="house-number" type="number">
</fieldset>
As stated in https://developer.mozilla.org/it/docs/Web/HTML/Element/legend
Permitted parent elements: A <fieldset> whose first child is this <legend> element
In your example the <legend> element is not the first child of its ancestor <fieldset>, so it is not valid HTML5 markup.
Furthermore note that also reverting the order of the elements like so
<legend><h2>Personal information</h2></legend>
the markup would not be still valid, since <legend> allows phrasing content only
Element legend is not allowed as child of element h1.
Only as a child of a fieldset.
Quote from W3C validator -
Contexts in which element legend may be used:
As the first child of a fieldset element.
Does the label tag work with radio buttons? If so, how do you use it? I have a form that displays like this:
First Name: (text field)
Hair Color: (color drop-down)
Description: (text area)
Salutation: (radio buttons for Mr., Mrs., Miss)
I'd like to use the label tag for each label in the left column to define its connection to the appropriate control in the right column. But If I use a radio button, the spec seems to indicate that suddenly the actual "Salutation" label for the form control no longer belongs in the label tag, but rather the options "Mr., Mrs., etc." go in the label tag.
I've always been a fan of accessibility and the semantic web, but this design doesn't make sense to me. The label tag explicitly declares labels. The option tag selection options. How do you declare a label on the actual label for a set of radio buttons?
UPDATE:
Here is an example with code:
<tr><th><label for"sc">Status:</label></th>
<td> </td>
<td><select name="statusCode" id="sc">
<option value="ON_TIME">On Time</option>
<option value="LATE">Late</option>
</select></td></tr>
This works great. But unlike other form controls, radio buttons have a separate field for each value:
<tr><th align="right"><label for="???">Activity:</label></th>
<td> </td>
<td align="left"><input type="radio" name="es" value="" id="es0" /> Active
<input type="radio" name="es" value="ON_TIME" checked="checked" id="es1" /> Completed on Time
<input type="radio" name="es" value="LATE" id="es2" /> Completed Late
<input type="radio" name="es" value="CANCELED" id="es3" /> Canceled</td>
</tr>
What to do?
Does the label tag work with radio buttons?
Yes
If so, how do you use it?
Same way as for any other form control.
You either give it a for attribute that matches the id of the control, or you put the control inside the label element.
I'd like to use the label tag for each label in the left column
A label is for a control, not a set of controls.
If you want to caption a set of controls, use a <fieldset> with a <legend> (and give a <label> to each control in the set).
<fieldset>
<legend> Salutation </legend>
<label> <input type="radio" name="salutation" value="Mr."> Mr. </label>
<label> <input type="radio" name="salutation" value="Mrs."> Mrs. </label>
<!-- etc -->
</fieldset>
Ah yes. Here’s how it works.
<label> labels individual fields, hence each <input type="radio"> gets its own <label>.
To label a group of fields (e.g. several radio buttons that share the same name), you use a <fieldset> tag with a <legend> element.
<fieldset>
<legend>Salutation</legend>
<label for="salutation_mr">Mr <input id="salutation_mr" name="salutation" type="radio" value="mr"><label>
<label for="salutation_mrs">Mrs <input id="salutation_mrs" name="salutation" type="radio" value="mrs"><label>
<label for="salutation_miss">Miss <input id="salutation_miss" name="salutation" type="radio" value="miss"><label>
<label for="salutation_ms">Ms <input id="salutation_miss" name="salutation" type="radio" value="ms"><label>
</fieldset>
You can use the aria-role="radiogroup" to associate the controls without using a <fieldset>. This is one of the techniques suggested by WCAG 2.0.
<div role="radiogroup" aria-labelledby="profession_label" aria-describedby="profession_help">
<p id="profession_label">What is your profession?</p>
<p id="profession_help">If dual-classed, selected your highest leveled class</p>
<label><input name="profession" type="radio" value="fighter"> Fighter</label>
<label><input name="profession" type="radio" value="mage"> Mage</label>
<label><input name="profession" type="radio" value="cleric"> Cleric</label>
<label><input name="profession" type="radio" value="theif"> Thief</label>
</div>
However, I noticed that using this technique the WebAim Wave tool to give a warning about a missing <fieldset>, so I'm not sure what AT support for this is like.
You can't declare a label for a set of buttons, but for each button.
In this case, the labels are "Mr.", "Mrs." and "Miss", not "Salutation".
UPDATE
Maybe you should just use another tag for this "label" of yours - since it's not really a label.
<tr>
<th align="right" scope="row"><span class="label">Activity:</span></th>
<td> </td>
<td align="left"><label><input type="radio" name="es" value="" id="es0" /> Active </label>
[... and so on]
</tr>
my 2 cents to the topic, or rather a side node (it does not use implicit association to be able to be placed anywhere, but linking):
grouping is done by the name attribute, and linking by the id attribute:
<ol>
<li>
<input type="radio" name="faqList" id="faqListItem1" checked />
<div>
<label for="faqListItem1">i 1</label>
</div>
</li>
<li>
<input type="radio" name="faqList" id="faqListItem2" />
<div>
<label for="faqListItem2">i 2</label>
</div>
</li>
<li>
<input type="radio" name="faqList" id="faqListItem3" />
<div>
<label for="faqListItem3">i 3</label>
</div>
</li>
</ol>
To answer your question: no, you can't connect Salutation to one of the radio buttons. It wouldn't make sense that if you'd click on Salutation, one of the options would be selected. Instead, you can give Mr, Mrs and Miss their own labels, so if someone clicks on one of those words, the corresponding radio button will be selected.
<input id="salutation_mr" type="radio" value="mr" name="salutation">
<label for="salutation_mr">Mr.</label>
<input id="salutation_mrs" type="radio" value="mrs" name="salutation">
<label for="salutation_mrs">Mrs.</label>
<input id="salutation_miss" type="radio" value="miss" name="salutation">
<label for="salutation_miss">Miss</label>
I do think that you could still wrap Salutation inside a <label> element, you just can't use the for attribute. I stand corrected, see the comments below. Although it's technically possible, it's not what <label> was meant for.
The Label's 'for' attribute corresponds to the Radio buttons ID. So...
<label for="thisRad">Radio Button 1</label>
<input type="radio" id="thisRad" />
Hope it helps.
You'd want yours to look something like this...
Salutation<br />
<label for="radMr">Mr.</label><input type="radio" id="radMr" />
<label for="radMrs">Mrs.</label><input type="radio" id="radMrs" />
<label for="radMiss">Miss.</label><input type="radio" id="radMiss" />