139

Just browsing the google maps source code. In their header, they have 2 divs with id="search" one contains the other, and also has jstrack="1" attribute. There is a form separating them like so:

<div id="search" jstrack="1">
    <form action="/maps" id="...rest isn't important">
        ...
        <div id="search">...

Since this is google, I'm assuming it's not a mistake.

So how bad can it really be to violate this rule? As long as you are careful in your css and dom selection, why not reuse id's like classes? Does anyone do this on purpose, and if so, why?

danludwig
  • 1,758

5 Answers5

151

Specification says UNIQUE

HTML 4.01 specification says ID must be document-wide unique.

HTML 5 specification says the same thing but in other words. It says that ID attributes must be unique amongst all the IDs in the element's tree, which is basically the document if we read the definition of it.

Avoid duplication

But since HTML renderers are very forgiving when it comes to HTML rendering they tolerate duplicate IDs. This should be avoided if at all possible and strictly avoided when programmatically accessing elements by IDs in JavaScript. I'm not sure what getElementById function should return when several matching elements are found? Should it:

  • return an error?
  • return first matching element?
  • return last matching element?
  • return a set of matching elements?
  • return nothing?

But even if browsers work reliably these days, nobody can guarantee this behavior in the future since this is against specification. That's why I recommend you never duplicate IDs within the same document.

33

You asked "how bad". So to flesh out @RobertKoritnik's (entirely accurate) answer a bit...

That code is incorrect. Incorrect doesn't come in shades of grey. This code violates the standard and is therefore incorrect. It would fail validation checking, and it should.

That said, no browser currently on the market would complain about it, or have any problem with it at all. Browsers would be within their rights to complain about it, but none of the current versions of any of them currently do. Which doesn't mean future versions might not treat this code badly.

Your behavior trying to use that ID as a selector, either in css or javascript, is unguessable and probably varies from browser to browser. I suppose a study could be done to see how each browser reacts to that. I think in the best case, it would treat it just like "class=", and select the list of them. (That might confuse JavaScript libraries, though--if I were the author of jQuery, I might have optimized my selector code so that if you come to me with a selector starting with "#", I expect a single object, and getting a list might bork me completely.)

It also might select the first one, or possibly the last one, or select none of them, or crash the browser entirely. No way to tell without trying it.

"How bad" then depends entirely on how strictly a particular browser implements the HTML spec, and what it does when confronted with a violation of that spec.

EDIT: I JUST happened to come across this today. I'm pulling in various components from search forms on various types of entities to produce a great big all-in-one reporting utility for this site, I'm loading up the remote pages' search forms in hidden divs and slotting them into my report generator when the appropriate entity type is selected as the source for the report. So there's a hidden version of the form, and a version displayed in the report generator. The JavaScript that came with, in all cases, refers to elements by ID, of which there are now TWO on the page--the hidden one, and the displayed one.

What jQuery seems to be doing is selecting me the FIRST one, which in all cases is exactly the one I DON'T want.

I'm working around this by writing selectors to specify the region of the page I want to get my field in (ie: $('#containerDiv #specificElement') ). But there's one answer to your question--jQuery on Chrome definitely behaves a particular way when confronted with this spec violation.

Dan Ray
  • 9,116
  • 3
  • 38
  • 49
  • ... a related question: http://stackoverflow.com/q/29295824/287948 about obligation of IDs in a CSS fast profile. – Peter Krauss Mar 27 '15 at 14:22
  • 6
    "Incorrect doesn't come in shades of grey." I see this a lot and it's one of those things that's technically correct but not "true" in life or in programming. You indirectly cover that pretty thoroughly in your answer and I could expound but this scene from The Big Bang Theory does such a good job that I'll let it speak for me and hopefully make someone laugh... Stuart vs Sheldon https://www.youtube.com/watch?v=F_1zoX5Ax9U – Night Owl Mar 01 '16 at 21:42
  • this is an 8 year old answer, but I think it's very unbalanced how you hyperbole on OP's question yet don't complain much about browsers' permissive and dangerous behaviour about repeated ids, which is way worse than what OP's trying to do. – Guido Tarsia Oct 08 '19 at 15:41
22

How bad is it really?

  1. It makes me cry
  2. It's invalid
  3. Many javascript libraries will not work as expected
  4. It makes your code confusing

Experience says that getElementById in major browsers will return the first matched element in the document. But this may not always be the case in the future.

When jQuery is given an id eg #foo, it uses getElementById and mimics that behaviour. 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.

I often have to write code for other sites, and I have to work around this. In a just world, I would not have to redesign functions to start off by checking if an ID is unique. IDs should always be unique. The world is cruel and that's why I cry.

8

You can do a great many things - but that doesn't mean that you should.

As a programmer (generally speaking) we build our lives on being precise and following the rules - here is a rule that is simple to follow, that is fairly fundamental to what we do - we like (depend upon) unique identifiers within a given scope...

Breaking the rule is something we can do because the browser are way too accommodating - but really we'd all be better off if browsers were strict about needing well formed and valid HTML, the small amount of pain it would have caused would have long since been repaid!

So, is it really that bad? As a programmer how can you even ask? Its a crime against civilisation (-:


Addendum:

You write that browsers are too accommodating like it's bad thing

I do, because it is - we're not talking about complicated rules, we're talking substantially about making things well formed and otherwise applying rules which can be tested mechanically and which in turn make it easier for the result to be processed mechanically. If the browsers had been strict then the tools would very rapidly have adapted to support that - it wasn't so they didn't, some to the extent they exploit that failing instead. Just think on this - email would have been a much nicer medium if MS and Netscape had not screwed it up by allowing unrestricted HTML when a far less complex "email markup language" with explicit support for quoted text would have given us a far better tool... but that ship sailed and similarly we can't close the stable door on what browsers allow (we should, HTML5 should have) but we can't

Murph
  • 7,843
8

In Scripting: getElementByID will return only the first match. In CSS: #id will affect ALL elements with that ID. In Browser Render won't be of any effect.

This is the behavior of w3c standard. Not a possible one, it's the facto defined one.

https://dom.spec.whatwg.org/#interface-nonelementparentnode