Can a label only refer to input elements? - html

W3Schools have this to say about labels:
The <label> tag defines a label for an input element.
[Emphasis mine]
Does this mean that the following HTML isn't valid?
<!doctype html>
<html>
<head>
<title>Example document</title>
</head>
<body>
<label for="x">Label</label>
<hr>
<div id="q" contentEditable="true">Hello</div>
<hr>
<div id="x" contentEditable="true">World</div>
</body>
</html>
Both Chrome and IE8 give focus to World when Label is clicked, Firefox does not.
Which is correct?

According to the W3C it applies to Form Controls, and Form Controls are defined as:
Buttons
Checkboxes
Radio buttons
Menus
Text input
File select
Hidden controls
Object tags
So FireFox is technically right, although I'd hardly consider it to be "breaking" if a browser didn't restrict it to those elements.

The HTML spec says, about label's "for" attribute, "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."
So the id references in "for" should be that of a control. What's a control? The spec basically says any input is a control, as is button, select, or object. So Firefox is technically right -- a div is not a control.

I would say it was not an appropriate use of the markup, because label semantics are that they are specifically for controls.
The LABEL element is used to specify
labels for controls that do not have
implicit labels,
http://www.w3.org/TR/html401/interact/forms.html#h-17.9.1

The latest WhatWG spec has this to say:
Some elements, not all of them form-associated, are categorized as labelable elements. These are elements that can be associated with a label element.
button, input (if the type attribute is not in the Hidden state), meter, output, progress, select, textarea
...
The for attribute may be specified to indicate a form control with which the caption is to be associated. If the attribute is specified, the attribute's value must be the ID of a labelable element in the same tree as the label element.
(Source: https://html.spec.whatwg.org/multipage/forms.html.)
In other words, the standard only allows for attributes to point at elements of one of the 7 tag types listed above. The HTML exhibited in the question (which uses a for element to point to an editable div) is therefore technically invalid HTML under the current spec.
The Nu Html Checker (which is endorsed by WhatWG) agrees; if you ask it to validate the HTML document from the question, it will say:
Error: The value of the for attribute of the label element must be the ID of a non-hidden form control.

Related

Turn invalid an empty non required input field

I need to know how to make an empty-non-required input element invalid.
For example:
<input pattern="[0-9]+" title="" />
This field is :valid by default, as is not required. I need to turn it :invalid if it is empty.
Thank you all in advance. Cheers.
EDIT:
HTML:
<div>
<input type="text" name="Country" pattern="[a-zA-Z ]+" title="" placeholder="Country" />
Toggle
</div>
CSS:
input:valid + a
{
color: blue;
}
The <a> starts blue since there is no text inside the <input> which is not required.
The pseudo-class :valid state for an empty-non-required <input> element is true.
I need the <a> to remain uncolored when the <input> field is empty.
You need to add the attribute required, which has the same (limited, but growing) browser support as the pattern attribute. There is no way to make an “empty non-required” element invalid, because the required attribute means that the value must be non-empty.
The description of the pattern attribute in HTML5 CR says the attribute is used in constraint validation only if the value is not empty. This could also be said so that an empty string is always regarded as matching the pattern (but it really isn’t even checked against it).
This answer addresses the clarified/modified question, which seems to be about styling. An input element cannot match the selector :invalid if its value is empty, since such an element is exempted from constraint validation (as explained in my first answer). There is no selector for checking that the value of an input element is empty or non-empty. (The :empty pseudo-class tests for the content being empty, and an input element always has empty content.)
So this cannot be done in CSS (alone). You can use JavaScript e.g. so that any input operation causes the input element value to be checked. If the value is nonempty, put the input element to a class, say ok. Modify the CSS selector accordingly.
<style>
input:valid + a.ok {
color: blue;
}
</style>
<input ... oninput=check(this)>
...
<script>
function check(el) {
el.nextElementSibling.className = el.value ? 'ok' : '';
}
This works in sufficiently modern browsers. If wider browser coverage is needed, you may need to add event attributes like onkeypress and onpaste etc. that are used to run the same check. (And nextElementSibling might need to be replaced by some clumsier way of getting at the next element.)
Update, as per the comment below, you can simplify the code somewhat by setting the class on the input element rather than the a element. This means that the CSS selector would be input:valid.ok + a and the JavaScript assignment statement would have just el.className as the left-hand side. Regarding browser coverage, it’s probably not an issue here as compared with the basic restriction caused by the use of the :valid pseudo-class, which isn’t supported by IE 9 and earlier.

HTML form label has two options

I normally style my forms in the format
<label for="CompanyNameTextBox">
<span>Company</span>
<input name="CompanyNameTextBox" type="text" id="CompanyNameTextBox" />
</label>
This way I can style the CSS like so:
.input[type=text] span
{
display: inline-block;
width: 200px;
}
and I get a nice side by side arrangement with my labels to the left of the form elements. This works for all elements I should add.
Now, I have a field: Credit Card Expiry Date.
This is special, I have two select lists in a single label:
<label>
<span>Expiry Date</span>
<select name="ExpiryDateMonthDropDownList" id="ExpiryDateMonthDropDownList">
...
</select>
<select name="ExpiryDateYearDropDownList" id="ExpiryDateYearDropDownList">
...
</select>
</label>
If I try to select the latter (Year) it defaults back to selecting the first (Month), even though I haven't specified a for attribute on the label.
So the question would be, what can I do? I can't work out if I'm doing forms wrong (I shouldn't in fact put the input inside the label) or if I have to do some silly workaround like stick the second select inside it's own label.
MDN on <label> says:
The HTML Element represents a caption for an item in a user
interface. It can be associated with a control either by using the for
attribute, or by placing the control element inside the label element.
Such a control is called the labeled control of the label element.
and
No labelable elements other than the labeled control are allowed.
So if you put an control element inside a label it is the same as writing a label for this element, so you see where the problem appears when you place two input fields inside a label.
You can just place the second control outside, or both outside the label and make a for for the first input element, or yes you can make two separate labels for the two input fields, any of this combinations should work when you specify the forattribute.
The specs for HTML5 "w3.org: 4.10.6 The label element" say:
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.
For HTML 4 "w3.org: 17.9.1 The LABEL element it's even more strict:
The label element may be used to attach information to controls. Each label element is associated with exactly one form control.
So you may have to wrap both in a container to get the same visual output:
<div class="multiple_inputs">
<label>
<span>Expiry Date</span>
<select name="ExpiryDateMonthDropDownList"></select>
</label>
<select name="ExpiryDateYearDropDownList"></select>
</div>
Of course you can add another <label> to the second field as well.
As already said in Should I put input tags inside a label tag? this is perfectly valid according to w3 but may produce problems with WCAG and some browser implementations.
In this case, you have two input elements inside just one label, which is not good, as there should be one label for each input element. So my proposal is to add another label and just put one element inside of each.
Perhaps if form elements are in label, it selects first element by default. But you can specify second field as for attribute (may be browser-specific, works in firefox 22).

What is the use of name, id and value?

Why do we use the the name, id and value attributes with html elements? What are they important and how are they interpreted? What are the differences between them? I have looked at w3schools and every tutorial but I would like a simple explanation from a person.
What is the difference between just doing:
<form>
<input type="text" />
</form>
and
<form>
<input type="text" name="name" />
</form>
what are the benefits of using these attributes?
name - passed to the server in forms
id - a unique identifier to the HTML element
value - the value of an input or textarea element
The presence of a name attribute in an input element causes a name=value pair to be included in the form data, if the value is not empty. In the absence of such an attribute, the form field does not make any contribution to the form data.
The id attribute can be used to give an element a unique identifier that can be used in client-side scripting and styling. It has nothing to do with the functionality of the name attribute.
The value attribute in a text input box specifies the initial (default) content of the input field.
Each form element in your application must save some information for you. Those are value.
When you want process your forms using a server-side programming language, you must point to your wanted element. Here, you need name to fetch your form elements values.
Also, sometimes you might need to process your form client-side or do something else on elements in your HTML document, now one way to point to them can be an id.
id is usually referred to by, or used in relation to, CSS styling. name is usually referred to by data-related php or or other server-side scripting , and value is the "content" ascribed to that element, so if input value = "hello", then that is what will appear in the text input field.
One point that the other answers don't make clear, is that the purpose of an attribute can differ depending on which element it belongs to.
So while an id attribute identifies an element no matter where it is, the name attribute serves a different purpose on the iframe and object than it does on the meta element, which is again different from its purpose on the submittable elements button, input, keygen, object, select and textarea. The param element and the map element both have name attributes, each for a different purpose, while the form element, fieldset element and output element use their name attributes for a more or less common purpose, but different from the other elements.
Similarly, the value attribute on the input, button and option elements serve similar but slightly different purposes, and the progress and meter elements share a similarly purposed value attribute, but each of the param, li, and data (WHATWG HTML living standard only) elements has a value attribute with a purpose dedicated to that particular element.
To understand all the purposes properly, I recommend that you at least read the spec.

Undefined behaviour in (X)HTML?

Is there such a thing as undefined behaviour in (X)HTML?
I have wondered this after playing around with the <button> tag, which allows HTML to be rendered as button. Nothing new so far...
But I noticed that one can also use the <a> tag. Complete example:
<button>
normal text
<b>bold text</b>
linked text
</button>
This is rendered as following on Firefox:
And in Google Chrome:
Now, On firefox, the link target is NOT clickable, only the button... However, on Chrome, the link is clickable, and will redirect to the IANA RFC2606 Page.
Is this undefined behaviour? Are there more cases in (X)HTML that could be described as undefined behaviour?
It's a little more complex than just inspecting the DTD as given by Yi Jiang and mu is too short.
It's true that the XHTML 1.0 DTDs explicitly forbid <a> elements as children of <button> elements as given in your question. However it does not forbid <a> elements as descendants of <button> elements.
So
<button>
normal text
<b>bold text</b>
<span>linked text</span>
</button>
is XHTML 1.0 Strict DTD conforming. But it has the same behavioural difference between Firefox and Chrome as the button fragment in the question.
Now, it is known that DTDs have problems describing limitations on descendant relationships, so it's maybe not surprising that the above sample is DTD conforming.
However. Appendix B of the XHTML 1.0 spec normatively describes descendant limitations in addition to the DTD. It says:
The following elements have
prohibitions on which elements they
can contain (see SGML Exclusions).
This prohibition applies to all depths
of nesting, i.e. it contains all the
descendant elements.
button
must not contain the input, select, textarea, label, button, form,
fieldset, iframe or isindex elements.
Note that it does not contain an exclusion for the <a> element. So it seems that XHTML 1.0 does not prohibit the <a> element from being non-child descendant of <button> and the behaviour in this case is indeed undefined.
This omission is almost certainly a mistake. The <a> element should have been in the list of elements prohibited as descendants of button in Appendix B.
HTML5 (including XHTML5) is much more thorough on the matter. It says:
4.10.8 The button element
Content model:
Phrasing content, but there must be no interactive content descendant.
where interactive content is defined as
Interactive content is content that is
specifically intended for user
interaction.
a
audio (if the controls attribute is present)
button
details
embed
iframe
img (if the usemap attribute is present)
input (if the type attribute is not in the Hidden state)
keygen
label
menu (if the type attribute is in the toolbar state)
object (if the usemap attribute is present)
select
textarea
video (if the controls attribute is present)
So in (X)HTML5 the <a> element is prohibited from being a descendant of the <button> element.
The HTML 4 specifications declares the <button> as such:
<!ELEMENT BUTTON - -
(%flow;)* -(A|%formctrl;|FORM|FIELDSET)
-- push button -->
Which, if my reading of the DTD is correct (and I'm not exactly familiar with this), <a> elements are explicitly forbidden from being nested in buttons, so what you're looking at there is invalid HTML, and therefore it is undefined behavior.
XHTML says this about <button>:
<!-- button uses %Flow; but excludes a, form and form controls -->
<!ENTITY % button.content
"(#PCDATA | p | %heading; | div | %lists; | %blocktext; |
table | %special; | %fontstyle; | %phrase; | %misc;)*">
So <a> is explicitly excluded from XHTML as well. The allowable elements inside <button> appear to be pretty much the same in XHTML-1.0 as in HTML-4.0.
To add to Alohci's good answer, but more specifically to answer the question: If your (X)HTML is invalid, behaviour is always, per definitionem, undefined. In this case, browsers are free to interpret the markup as they like (or whatever chance will make out of it), or even to reject it (what no real browser does).
This is exactly the problem that the tag soup introduced and that was the origin of XML's strict parsing rules and the HTML5 spec growing to >500 pages.

With nested HTML forms, is it possible to target which one's content is transmitted upon submit?

I have a form within another form:
<form id="a">
<form id="b">
<input type="submit">
When the submit button is clicked, it seems that the outer form is submitted.
Is there a way to target which form is submitted?
No, nested forms aren't supported:
There can be several forms in a single document, but the FORM element can't be nested.
-- http://www.w3.org/MarkUp/html3/forms.html
The HTML DTD specifically forbids a form element from containing another form element:
<!ELEMENT FORM - - (%block;|SCRIPT)+ -(FORM) -- interactive form -->
http://www.w3.org/TR/html401/interact/forms.html#edef-FORM
Like others have said...nested forms aren't allowed.
However, that doesn't mean some browsers won't do something with such. In the example that you have presented, the browser appears to be ignoring the second <form> tag in a similar fashion to how an unknown tag (i.e. <notAValidTag>) is also ignored. Since JavaScript also doesn't allow for embedded form collections, the best way to ensure that FormB's information is submitted is to make it no longer a nested form. This will break up your markup and UI into more distinct sections which may be beneficial from a UX perspective as well.
i think this is not allowed by the html standard.
In HTML 5, yes. Each input element can have a "form" attribute signalling which form it belongs to. However, it is still invalid to nest forms in HTML and HTML parsers won't allow this to happen.
However, it is possible to construct nested forms via JavaScript. In the absence of the form attribute, the rules for determining which form an input belongs to are quite complex, but they are described in full with an example at http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#association-of-controls-and-forms
Specifically, step 5 of Reset the Form Owner says:
Otherwise, if element has an ancestor form element, then associate element with the nearest such ancestor form element.
Clearly, "nearest" would not need to be said if form nesting was impossible.
Then step 4 explains how the required form can be targeted, by associating the submit button to the required form though the "form" attribute on the button.
If element is listed, has a form content attribute, and is connected, then:
If the first element in element's tree, in tree order, to have an ID that is identical to element's form content attribute's value, is a form element, then associate the element with that form element.