With all the above being said it is worth to note that it is likely to come across multiple same IDs in a document with user-agent-created content (think frameworks, mv*, react, polymer...). That's if anyone was wondering why a very professional looking XYZ site is full of such bad practice coding.
– Lukasz MatysiakAug 21 '17 at 14:34

@corsiKa the consequence is undefined behavior, for example, what does document.getElementById("#foo") or $("#foo") return when there are multiple #foos? You'll run into problems being able to work with these elements from JS, pass them as selectors to libraries/APIs/Flash, etc.
– mrooneyMay 13 '13 at 20:55

53

This is incorrect. It is entirely possible to have multiple elements with the same ID. It's not generally best practice, but it does have its occasional uses. Everyone seems to cite how would selectors work, well if your going in knowing you'll have conflicting IDs, you use your selectors with a parent, where the IDs under the parent would be unique. eg $('div#car span#size) and $('div#truck span#size').
– BJuryJul 2 '14 at 11:33

15

why even use multiple similar id's when you got class for this purpose?
– Max YariOct 14 '14 at 12:22

3

Yes, multiple IDs can, in practice, be replaced by using classes. However, classes are intended for applying styles, not identifying elements, making the scope of names much wider and therefore likely to overlap. Especially if using 3rd party libraries. Id as 'identifier' is not intended to be multiplied so there is clearly a need for something in between. The practical use is componentization of sections of a page/dom into separate logical units. Using (at least) 2-layer identification is hence required.
– Alen SiljakJan 21 '15 at 12:24

So does Chrome (v22 at the time this comment was written). :D
– omninonsenseOct 25 '12 at 18:33

23

According to the spec, this is a MUST, not a SHOULD. (Does it still work in most browsers? Yes. Is it valid HTML? No. Also, for getElementById, the result in such cases is undefined, meaning that there is no way of telling how a browser might chose to handle it.)
– leoApr 9 '14 at 9:14

2

@leo however this is the real world where browsers don't conform fully to the standards. In this case it could be a good thing, as there is no reason to enforce unique IDs.
– BJuryJul 2 '14 at 11:39

1

In HTML5, the spec for getElementById actually does define that the first element with the given ID must be returned (which is how all browsers currently handle the situation anyway) - see my answer below for more.
– mltsyMay 16 '17 at 18:32

Most (if not all) browsers have and still do select the first element with a given ID, when calling getElementById. Most libraries that find elements by ID inherit this behavior. Most (if not all) browsers also apply styles assigned by id-selectors (e.g. #myid) to all elements with the specified ID. If this is what you expect and intend, then there are no unintended consequences. If you expect/intend something else (e.g. for all elements with that ID to be returned, or for the style to apply to only one element) then your expectations will not be met and any feature relying on those expectations will fail.

Some javascript libraries do have expectations that are not met when multiple elements have the same ID (see wootscootinboogie's comment about d3.js)

Conclusion

If you your code works as expected in your current environments, and these IDs are used in a predictable/maintainable way, then there are only 2 practical reasons to consider not to do this:

To avoid the chance that you are wrong, and one of the libraries you use actually does malfunction when multiple elements have the same ID.

To maintain forward-compatibility of your website/application with libraries or services (or developers!) that malfunction when multiple elements have the same ID, that you may encounter in the future.

What would you expect? That every button clicked would execute the click event handler setup with jQuery. Unfortunately it won't happen. ONLY the 1st button calls the click handler. The other 2 when clicked do nothing. It is as if they weren't buttons at all!

So always assign different IDs to HTML elements. This will get you covered against strange things. :)

what if I have a "#content" which I already have referenced in a variable, and a #my-div #content which I only have for a few moments after which I remove the referenced node and forget its variable, after which the #div #content performs a myDiv.outerHTML = myDiv.innerHTML to replace the original. This saves the need to hard copy all styles and contents of #content into #decoy and do the same thing. This makes sense when doing transitions.
– DmitryAug 5 '16 at 4:42

This means that, even if I use 'append' to add multiple element of same id, DOM only considers first element to be real, ideally 1 ID = 1 Element
– Karan KawOct 11 '17 at 15:04

No. two elements with the same id are not valid. IDs are unique, if you wish to do something like that, use a class. Don't forget that elements can have multiple classes by using a space as a delimeter:

The official spec for HTML states that id tags must be unique AND the official spec also states that if the render can be completed, it must (i.e. there are no such thing as "errors" in HTML, only "invalid" HTML). So, the following is how id tags actually work in practice. They are all invalid, but still work:

This:

<div id="unique">One</div>
<div id="unique">Two</div>

Renders fine in all browsers. However, document.getElementById only returns an object, not an array; you will only ever be able to select the first div via an id tag. If you were to change the id of the first div using JavaScript, the second ID would then be accessible with document.getElementById (tested on Chrome, FireFox & IE11). You can still select the div using other selection methods, and it's id property will be returned correctly.

Please note this above issue opens a potential security vulnerability in sites that render SVG images, as SVGs are allowed to contain DOM elements, and also id tags on them (allows script DOM redirects via uploaded images). As long as the SVG is positioned in the DOM before the element it replaces, the image will receive all JavaScript events meant for the other element.

This issue is currently not on anyone's radar as far as I know, yet it's real.

This:

<div id="unique" id="unique-also">One</div>

Also renders fine in all browsers. However, only the first id you define this way is utilized, if you tried document.getElementById('unique-also'); in the above example, you would be returned null (tested on Chrome, FireFox & IE11).

This:

<div id="unique unique-two">Two</div>

Also renders fine in all browsers, however, unlike class tags that can be separated by a space, the id tag allows spaces, so the id of the above element is actually "unique unique-two", and asking the dom for "unique" or "unique-two" in isolation returns null unless otherwise defined elsewhere in the DOM (tested on Chrome, FireFox & IE11).

SLaks answer is correct, but as an addendum note that the x/html specs specify that all ids must be unique within a (single) html document. Although it's not exactly what the op asked, there could be valid instances where the same id is attached to different entities across multiple pages.

Example:

(served to modern browsers) article#main-content {styled one way}
(served to legacy) div#main-content {styled another way}

Probably an antipattern though. Just leaving here as a devil's advocate point.

Good point. Although the dynamically generated content that is supposed to be inserted into another page should avoid ids altogether. Ids are like globals in programming languages, you can use them, and there are valid cases where it's a nice hack that simplifies things. It's a nice practice to consider doing things right before doing hacks.
– psycho brmMay 23 '17 at 8:31

And for what it's worth, on Chrome 26.0.1410.65, Firefox 19.0.2, and Safari 6.0.3 at least, if you have multiple elements with the same ID, jquery selectors (at least) will return the first element with that ID.

Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).