Is it possible to use one label element for multiple select elements in an HTML5 form? - html

I am working on an assignment for an online web development course I am taking. The assignment is to create an HTML form.
One of the requirements is for there to be 3 dropdown menus - one for month, day, and year. A label of "Birthday:" is to precede these three menus.
The course's assignment solution showed three select elements nested inside of one label element. I tried this and, although it looked normal in the browser, when I uploaded the file to W3C I received the following error:
"Error: The label element may contain at most one button, input, meter, output, progress, select, or textarea descendant."
Is there a proper way to use one label element to be applied to multiple select elements? Or is this a poor practice and instead each day, month, and year should each get its own label?
Here is my code:
<div>
<label>Birthday:
<select name="month" required>
<option value="">Month</option>
<option value="Jan">Jan</option>
<option value="Feb">Feb</option>
<option value="Mar">Mar</option>
<option value="Apr">Apr</option>
</select>
<select name="day" required>
<option value="">Day</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<select name="year" required>
<option value="">Year</option>
<option value="1918">1918</option>
<option value="1988">1988</option>
<option value="1998">1998</option>
<option value="2008">2008</option>
</select>
</label>
</div>
-

In HTML, <input /> fields are »primitive«, which means, each one represents a single value primitive value like a number, string, boolean, etc. A Birth date, consisting of three values, one for the year, the month and the day is »complex« in that context. So you cannot make HTML »understand« that you are trying to create a »complex« field in that way.
That's why (imho) you should not attach the label (complex) to any of the fields (primitive) and use the label as »decoration« without any connection to any field, than you wont get any validation errors.
<label>'s as wrapping elements can be helpful (especially for radio buttons) to expand the »clicking area/hitbox« and to apply some css, depending on the fields value, without any javascript. Otherwise linking labels to fields is cool for search engines and stuff, but since HTML does not have a standardized definition about: »how to label complex inputs«, it is difficult to say if the proposed approach is helpful, or will be in the future (afik).
So in your case, I would just:
<form>
<div class="complex field-group">
<label>…</label>
<div class="fields">
<!-- eventually to help bots
<label for="x" style="display:none;">…</label>
-->
<input id="x"/>
…
</div>
</div>
</form>

Related

Why is my select element hiding proceeding elements?

Currently trying to style a responsive form using bootstrap. This form actually didn't have any responsive design applied within a separate css file before applying bootstrap, everything was purely type and effects.
But I'm having a lot of issues with a select element within this form.
For whatever reason, a select element, which comes before a series of paired radio buttons (themselves grouped within fieldsets), is cutting off both the legend element and the label element for the first radio input. It looks like this:
select element viewed w/ element picker
It looks like content-box is taking up a ton of space. Or that space is "saved" for an active select dropdown? I'm not sure why there's so much blue there ^_^ I'm probably missing something very simple.
I've sectioned the select element off (using semantic section), I've wrapped it within its own row, I've tried applying some small-but-noticeable amount of extra margin-bottom (mb-4 for example).
None of this has worked. Here's my code for this particular section:
<section class="col-8 col-md-4" id="recommend">
<label class="col-form-label" for="select">Would you recommend your stay at the Aperture
Science computer-aided Enrichment Center?</label>
<select class="form-control mb-5" name="select" id="select" required>
<option value="">-- Please select an option --</option>
<option value="yes">Yes</option>
<option value="absolutely">Absolutely</option>
<option value="of_course">Of course!</option>
</section>
Any ideas? :D
You should probably end your <select> element, as this could have unknown effects on the rest of the DOM.
<select class="form-control mb-5" name="select" id="select" required>
<option value="">-- Please select an option --</option>
<option value="yes">Yes</option>
<option value="absolutely">Absolutely</option>
<option value="of_course">Of course!</option>
</select> <!-- <- this was missing -->

Proper way to label a group select elements [duplicate]

I have on this check in form:
<label>Check in date </label>
<select id="day">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<select id="month">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<select id="year">
<option value="1">2012</option>
<option value="2">2013</option>
</select>
As you can see, the user will choose the month, the day and the year on different select boxes, however, only one label should exist for all three.
What would be the proper way to do this with HTML ?
Update:
I'm concerned with the accessibility hit that we may have on developing something like the code above. I mean, a blind user should be able to listen each label in order to fill this form...
The problem with using one label for all three input boxes is that an non-sighted user is not going to know which of three boxes the focus is in because the same text will be read out in each case. There's a number of approaches possible. Maybe the safest is to have a label for each box, but hide those labels off to the left side of the viewport. Another possibility which ought to work, but I haven't tested would be this:
<fieldset>
<legend>Check in date</legend>
<select id="day" aria-label="day">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<select id="month" aria-label="month">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<select id="year" aria-label="year">
<option value="1">2012</option>
<option value="2">2013</option>
</select>
</fieldset>
Following with the answer from #Alohci, you can also use aria-labelledby and reverse the naming reference (which I think is a bit closer to the convention you were looking for):
<label id="date">Check in date</label>
<select aria-labelledby="date">
<!-- ... -->
</select>
<select aria-labelledby="date">
<!-- ... -->
</select>
<select aria-labelledby="date">
<!-- ... -->
</select>
Also note, as per the W3C on labelled-by:
If the label text is visible on screen, authors SHOULD use aria-labelledby and SHOULD NOT use aria-label. Use aria-label only if the interface is such that it is not possible to have a visible label on the screen. User agents give precedence to aria-labelledby over aria-label when computing the accessible name property.
You cannot associate a label element with more than one control. This is described in the definition of label.
You could give each select element its own label.
A better approach is to have a single text input field for a date. Then there is no problem with label. It means more work, since you have to parse the data server-side, and you should also parse it client-side (for checks, so that the user can immediately be informed of problems). But it is better usability (surely it is faster to type in a date than to use three clumsy dropdowns) and better accessibility. You need to decide on a date format and clearly tell the user what the expected format is.
There is no proper way; a label refers to one element. Just point it to the first one.
<label for="day">Check in date </label>
You could also use a specifically-styled <fieldset> if you like semantics, but I think that's a bit overkill. An <input type="date"> is probably the best option here, as it is one element that can be pointed to by your <label>, is more semantic, and can be somewhat friendlier if you implement a good date picker to go along with it.
If you want to stick with the <select>s, try giving each one a title attribute for accessibility.
Trying to improve #Bracketworks answer:
<label id="date">Check in date</label>
<label for="day" id="label_day">Day</label>
<select id="day" aria-labelledby="date label_day">
<!-- ... -->
</select>
<label for="month" id="label_month">Month</label>
<select id="month" aria-labelledby="date label_month">
<!-- ... -->
</select>
<label for="year" id="label_year">Year</label>
<select id="year" aria-labelledby="date label_year">
<!-- ... -->
</select>
See example 1 of MDN's "Using the aria-labelledby attribute".
HTML5's input type="date" might be useful too, particularly if you're using month/day/year select boxes as a way to limit date selection possibilities. This input element supports min and max date attributes, so you can apply your limitations. It's not supported by older browsers, but I've seen smart cookies use jQueryUI's datepicker as a shim (by using capabilities detection to determine type="date" support, then loading in and invoking the datepicker only if it isn't supported natively).

Can a class in Input element be referenced to a label in html? [duplicate]

I know that you can associate a label with an input using the for and id attributes. However can you use a class and not an id? Thanks
<label for="rooms">Number of rooms</label>
<select id="rooms">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
Classes are not unique (you can have multiple elements with the same class), so no.
If you want to associate a label to an input without using ID, you can implicitly assign it by including said input inside of the label:
<label>Number of rooms
<select name="rooms">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
</label>
Here is an example of when you wouldn't want to use an ID or nest the control:
I'm creating a BackboneJS application that uses templates. Because the template can be duplicated, it's important to refrain from using IDs, as it will create multiple elements in the DOM with the same ID.
I'm also using Bootstrap, which will present the control in a different (and undesirable) way if it's wrapped inside the <label> element.
At this point, the only solution I can find is to wrap the control element and tweek the default CSS to get the desired output. If someone has a more elegant solution, please chime in.
No, you cannot use the class of an element, because the same class can be used by multiple elements - in which case, which element would the label be for?
No, you can't. The only attribute you can use is the id attribute.
It doesn't make sense to use a class (which describes a group of related elements) since a label can be associated only with exactly one form control.
you can do this :
<label class="col-md-12 input-group input-group-sm">
<span class="col-sm-5 control-label text-nowrap">Code</span>
<input class="form-control listen code" type="text" size="15" required/>
</label>

Associate label to input with class not id?

I know that you can associate a label with an input using the for and id attributes. However can you use a class and not an id? Thanks
<label for="rooms">Number of rooms</label>
<select id="rooms">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
Classes are not unique (you can have multiple elements with the same class), so no.
If you want to associate a label to an input without using ID, you can implicitly assign it by including said input inside of the label:
<label>Number of rooms
<select name="rooms">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
</label>
Here is an example of when you wouldn't want to use an ID or nest the control:
I'm creating a BackboneJS application that uses templates. Because the template can be duplicated, it's important to refrain from using IDs, as it will create multiple elements in the DOM with the same ID.
I'm also using Bootstrap, which will present the control in a different (and undesirable) way if it's wrapped inside the <label> element.
At this point, the only solution I can find is to wrap the control element and tweek the default CSS to get the desired output. If someone has a more elegant solution, please chime in.
No, you cannot use the class of an element, because the same class can be used by multiple elements - in which case, which element would the label be for?
No, you can't. The only attribute you can use is the id attribute.
It doesn't make sense to use a class (which describes a group of related elements) since a label can be associated only with exactly one form control.
you can do this :
<label class="col-md-12 input-group input-group-sm">
<span class="col-sm-5 control-label text-nowrap">Code</span>
<input class="form-control listen code" type="text" size="15" required/>
</label>

How can I hide one field of an HTML form?

I have a simple HTML form that I'm using to drive site search for a website I'm creating.
Two of the fields should not be used together, such as "make" and "model" of a car. You wouldn't want someone searching for a "Ford Ram Truck," for instance.
How can I modify my form so that if a certain value in one of the fields is selected, the other field disappears?
Thank you for your help!
<select name="make">
<option value="item 1">item 1</option>
<option value="item 2">item 2</option>
</select>
<select name="model">
<option value="item 1">item 1</option>
<option value="item 2">item 2</option>
</select>
<input name="" type="submit" />
You would need to use javascript and hook up to the change event of the radio buttons.
In your javascript you can set the visibility of any form element to hidden or visible (depending on which you want).
You would still need to validate/check on the server side in order to avoid such a search (since javascript may be off or a malicious user might override your client side validation).
I think Chained Select Menu can solve your problem.