Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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?

share|improve this question
57  
"Since this is google, I'm assuming it's not a mistake." --> Google are not infallible. They make mistakes like the rest of us. –  Joeri Sebrechts Dec 27 '11 at 17:28
12  
actually the guys at google have SEARCH bolted in their minds so they can't think of any other id's :P –  Pankaj Upadhyay Dec 27 '11 at 17:53
7  
I have a feeling that that page is rendered from different html fragments so one developer in one fragment used that id, and the same happened with other developer in the other fragment. –  Luciano Dec 27 '11 at 18:20
7  
The whole question of "how bad is it really" just reminds me of this: xkcd.com/292 –  Daniel Roseman Dec 28 '11 at 17:47
2  
@DanielRoseman xkcd does it as well: what-if.xkcd.com/23/#question –  SQB Jul 17 at 5:55

5 Answers 5

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 must be unique in its home subtree 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 permit duplicate IDs. This should be avoided if at all possible and strictly avoided when programatically 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 behaviour in the future since this is against specification. That's why I recommend you never duplicate IDs within the same document.

share|improve this answer
1  
@missingno: I added a link to HTML 5 specification that talks about the same thing but in different wording. –  Robert Koritnik Dec 27 '11 at 20:26
1  
According to the DOM spec, "If more than one element has an ID attribute with that value, what is returned is undefined" (by which it means that there is no defined "correct" result, rather than the actual value undefined). It's rarely a good idea to rely on undefined behaviour. –  lonesomeday Dec 28 '11 at 0:22
1  
Worth noting with HTML5, the data- attribute comes in handy for when one might be tempted to assign multiple things the same ID. This lets you have many different ID's with one common data-something attribute in common. Still, all browsers that I know of ignore unknown attributes, so they're probably safe in just about every modern-ish browser lacking full HTML support. –  Tim Post Mar 3 '12 at 15:53
1  
@JoachimSauer: When you use data attributes you can have key-value pairs which is not true when you use CSS classes. In that case they're all like boolean properties. An element either has a CSS class or not. If you'd want values with CSS classes then you'd have to somehow combine them into CSS class name and parse that afterwards. I hope you can now see benefits of using data attributes. And they're also supported directly out of the box by jQuery when you simply refer to data-something="123" attribute with $(elem).data("something"). –  Robert Koritnik Sep 4 '12 at 10:39
1  
@RobertKoritnik: Of course! I didn't think of that use-case. I only thought about the case of id="search". –  Joachim Sauer Sep 4 '12 at 10:46

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.

share|improve this answer

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

share|improve this answer
    
You write that browsers are too accommodating like it's bad thing, but surely you don't believe that? –  KaptajnKold Dec 27 '11 at 22:42
4  
I can't speak for Murph, but I for sure think it is a really bad thing. Then again, without this level of forgiveness, the web may not have had the impulse to grow like we know it. –  Andrea Dec 27 '11 at 23:37
    
@Andrea: The internet would not have grown as we know it. It would have grown more slowly. But it would also have had a more solid basis of what is and is not correct code. Fast-but-sloppy may work, but I much prefer slower-but-correct. Especially since it's not like we'd only be talking about a couple of years of growth or so. –  Nicol Bolas Dec 28 '11 at 5:40
2  
@Andrea I'd bet that it would have grown almost as quickly - the tools would simply have evolved to deal with the problem. Whereas in many cases the tools were the root cause of poor markup. The fact is that people tend to do the least necessary - the step to "well formed" is a relatively small one and easy enough to test for and enforce and people would have accommodated that without significant stress –  Murph Dec 28 '11 at 11:36
1  
It's not horrible that browsers are accommodating. It IS horrible that they're all accommodating in different ways. –  Dan Ray Dec 29 '11 at 18:45

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.

share|improve this answer
2  
You forgot the 'god kills a kitten' in your list. –  Milky ways patterns Mar 6 at 19:04

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.

share|improve this answer
5  
This is one possible behaviour. getElementById could perfectly return any element, or even a null object. CSS effect could be on any elements, or none or all of them. Or the browser could crash. Out of the standard, the behaviour is undefined –  rds Dec 27 '11 at 22:35
    
It's not out of the standard because the standard specify what to do in those situations. So no, getElementById could not return any element, the standard says explicit that i will return the first match. I agree that behaviour out of the standard is undefined, what you don't understand is that all those cases are part of the standard. –  Bart Apr 3 at 21:27

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.