I am using jQuery and I am just wondering, does ID have to be always unique in the whole page? Class, I know, can be repeated as many times as you like, what about ID?
Yes, it must be unique.
HTML4:
https://www.w3.org/TR/html4/struct/global.html#h-7.5.2
Section 7.5.2:
id = name [CS]
This attribute assigns a name to an element. This name must be unique in a document.
HTML5:
https://www.w3.org/TR/html5/dom.html#element-attrdef-global-id
The id attribute specifies its element's unique identifier (ID). The
value must be unique amongst all the IDs in the element's home subtree
and must contain at least one character. The value must not contain
any space characters.
Does an ID have to be unique in the whole page?
No.
Because the HTML Living Standard of March 15, 2022, clearly states:
The class, id, and slot attributes may be specified on all HTML elements. …….
When specified on HTML elements, the id attribute value must be unique amongst all the IDs in the element’s tree and must contain at least one character. The value must not contain any ASCII whitespace.
and a page may have several DOM trees. It does, for example, when you’ve attached (Element.attachShadow()) a shadow DOM tree to an element.
TL; DR
Does an ID have to be unique in the whole page?
No.
Does an ID have to be unique in a DOM tree?
Yes.
from mdn
https://developer.mozilla.org/en/DOM/element.id
so i guess it better be...
Technically, by HTML5 standards ID must be unique on the page - https://developer.mozilla.org/en/DOM/element.id
But I've worked on extremely modular websites, where this is completely ignored and it works. And it makes sense - the most surprising part.
We call it "componentization"
For example, you might have a component on your page, which is some kind of widget. It has stuff inside with their own unique IDs eg "ok-button"
Once there are many of these widgets on the page, you technically have invalid HTML. But it makes perfect sense to componentize your widgets so that they each, internally, reference their own ok button eg if using jquery to search from it's own root it might be: $widgetRoot.find("#ok-button")
This works for us, though technically IDs shouldn't be used at all, once they're not unique.
As cited above, even YouTube does it, so it's not so renegade.
Jan 2018, here is Youtube HTML , you can see id="button" id="info" are duplicated.
That's basically the whole point of an ID. :) IDs are specific, can only be used once per page. Classes can be used as pleased.
Browsers used to be lenient on this (many years ago when css was young) and allow the ID to be used more than once. They have become more strict.
However, yes ID's are to be unique and only used once.
If you need to use css formatting more than once use CLASS.
With Javascript, you can only reference to one element using ID. document.getElementById and jQuery's $ selector will return only the first element matching. So it doesn't make sense using the same ID on multiple elements.
There are great answers for the same question at https://softwareengineering.stackexchange.com/questions/127178/two-html-elements-with-same-id-attribute-how-bad-is-it-really.
One tidbit not mentioned above is that if there are several identical ids one the same page (which happens, even though it violates the standard):
If you have to work around this (that's sad), you can use $("*#foo") which will convince jQuery to use getElementsByTagName and return a list of all matched elements.
Yes, IDs are unique. Class are not.
IDs always have to be unique.
Everybody has a unique identification number (ex. Social Security number), and there are lots of people in a social class
I'm adding to this question, because I feel it has not been answered adequately in any of the above,
As a point reference: I've implemented non-unique id's, and all works just fine (across all browsers). Importantly, when coding, I've not run into any css logic errors, which is where the rubber hits the road (IMO) on this question. Have also not run into any conflicts in js (as one can glean out id's in context with classes)
So, why do id's have to be unique? Obvious answer (as stated and re-stated above) is 'cause the 'standards' say so. The missing part for me is why?
i.e. what actually goes awry (or could theoretically go awry) if (heaven forbid) someone inadvertently used the same id twice?
The reference with all browsers these days?
Makes div possible in such terms of being used multiple times.
There is no rule that it must be unique. When all browsers understand:
<script>div#some {font-size: 20px}</script>
<div id="some"><p>understand</p></div>
<div id="some"><h1>me too</h1></div>
When you add new style CSS codes you have the possibility to use the addition of styles. Since that even is not supposed to be unique it describes the opposite use, so make more styles but do not make more objects? And as you can; assign several div objects, so why didn't they tell you that class must be unique? That's because the class does not need unique value. And that makes the ID in legal terms obsolete if not being unique.
<script>.some {font-size: 25px}</script>
<div class="some"><p>enter</p></div>
<div class="some"><h1>enter</p></div>
"When there is no rule when a rule is said. Then the rule is not fulfilled. It's not inherent to exist. By only in the illusion of all rules that it should have existed only to make life much harder."
Just because some people say div must be unique, this might be right, but at least through their professional perspective to say it, they have to say it. Unless they didn't check the modern browsers, which from nearly the beginning were able to understand the code of several different div objects with the same style.
ID must be unique - One reason for that is, that in the Browser-JavaScript-Context exists a methode: Document.getElementById()
This method can only return one element.
If a Document has not unique IDs, this function behaves in an undocumented and unforeseeable way.
I think, this is reason enough to only use one ID per Document.
Reference:
https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById
In lit-element, in most of the cases passing data from parent-component to child-component via attributes and via properties result in the same thing.
I wonder in which case I should use attributes while which case properties?
The difference between attributes and properties is that attributes are expressed in the DOM, while properties are not. The element can decide to reflect the properties back to attributes, but that is somewhat orthogonal. Example:
<my-button raised></my-button>
Here, raised is a boolean attribute, and it is convenient to pass data that way because you can do it declaratively in the DOM. <my-button>'s implementation does not have to know whether the attribute or the property was used to pass this data, because attributes get converted to properties automatically (if a property with a matching name was declared).
The following works as well (lit-element specific), but assigns the property directly.
<my-button .raised=true></my-button>
The implementation of my-button can decide if changes to the property get reflected back to the attribute. This is useful if you want to use the attribute, for example, in CSS for styling.
Generally, however, you just assign properties and let the custom element decide whether the property gets reflected back to the attribute. Say you want to control the button programmatically, you would just assign the property
this.button_.raised = true;
instead of writing
this.button_.setAttribute('raised', true);
Note, this always works with custom elements and even a few native elements (e.g., input's value is a property, too). But you can't write:
this.myDiv_.id = 'container';
because <div>s don't have properties, and you have to use setAttribute().
We all know that in HTML, an element ID is (and must be) unique.
From the standard:
The value must be unique amongst all the IDs in the element's home subtree and must contain at least one character.
Yet in the same standard, the for attribute in the <label> element it reads:
If the attribute is specified and there is an element in the Document whose ID is equal to the value of the for attribute, and the first such element is a labelable element, then that element is the label element's labeled control.
That would mean there could be more then one element with an ID equal to the value of the for attribute.
So which is it? Unique - or not?
It's covering the case where someone may not have made a unique id, since really there isn't anything hard preventing anyone from breaking standard, and specifies the behavior in such a case. Basically a secondary line enforcing the idea that there should only be 1 id with a certain value.
I was working on a page and noticed they had an element bound to document (ex. document.formNameId). I was thinking it must be the JavaScript and not being able to find a place where it was set, I removed all the JavaScript on the page. I still found the element name set on the document.
After playing with it, it seems form elements that have a name attribute set are added to document. Are there any other elements that are by default bound like that?
EDIT:
Upon further inspection, you can even find elements inside that form element by the same API.
So if I do something like this to get an input element: document.formName.inputName
Check this example out.
Yes, these are called (in HTML5) Named Properties
The description in the spec says:
The Document interface supports named properties. The supported
property names at any moment consist of the values of the name content
attributes of all the applet, exposed embed, form, iframe, img, and
exposed object elements in the Document that have non-empty name
content attributes, and the values of the id content attributes of all
the applet and exposed object elements in the Document that have
non-empty id content attributes, and the values of the id content
attributes of all the img elements in the Document that have both
non-empty name content attributes and non-empty id content attributes.
The supported property names must be in tree order, ignoring later
duplicates, with values from id attributes coming before values from
name attributes when the same element contributes both.
So these happens for a number of elements. There is also a description at the above link of how the values of such properties are determined, including how for forms, it becomes the list of controls on the form.
https://developer.mozilla.org/en-US/docs/Web/API/document has a good overview over all properties and methods of the document object.
[obsolete: document.formNameId is missing there and I could not find it on this website, so it seems it is not a default property but was added by a script (a quick google search for "document.formnameid" lists only this stackoverflow question).]
What's the best way to get a ol to start from 'x'?
The start tag is deprecated and everything I have found on Google has used the :before pseudo class which doesn't work in IE6 or 7. Didn't have much luck when searching stack either.
Only thing I can think of is manually go through and number the lists myself and style accordingly?
Any help appreciated.
While the start attribute in HTML 4 is indeed deprecated, looking at the HTML 5 docs, I see:
The start attribute, if present, must be a valid integer giving the ordinal value of the first list item.
If the start attribute is present, user agents must parse it as an integer, in order to determine the attribute's value. The default value, used if the attribute is missing or if the value cannot be converted to a number according to the referenced algorithm, is 1 if the element has no reversed attribute, and is the number of child li elements otherwise.
The first item in the list has the ordinal value given by the ol element's start attribute, unless that li element has a value attribute with a value that can be successfully parsed, in which case it has the ordinal value given by that value attribute.
which tells me I am safe using start with ol and value with li elements.
With ordered lists ol, you could use the various counter CSS instructions: Examples here. But, they also won't work with IE6 and 7. I don't think there is a non-Javascript way to make this work in them.