Thursday, December 22, 2011

Using duplicate IDs in HTML

Well today I'm being a bit controversial. Let us see what the HTML5 spec says about unique IDs in a HTML file.
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.
An element's unique identifier can be used for a variety of purposes, most notably as a way to link to specific parts of a document using fragment identifiers, as a way to target an element when scripting, and as a way to style a specific element from CSS.
Yes its been mentioned almost everywhere on the planet that ID must be unique. Now let us look at the below code,



#p2 {
  background-color: yellow; 


<!DOCTYPE html>
    <title>Duplicate ID Tester</title>
<link rel="stylesheet" href="dup.css" />
<p><a href="#p1">1</a></p>
<p><a href="#p2">2</a></p>
<p><a href="#p2">3</a></p>
    <div id="p1">
<p>ID IS 1</p>
    <div id="p2">
<p>ID IS 2</p>
    <div id="p2">
<p>ID IS 3</p>
<p>Now lets get ID 2 again using javascript</p>

I've committed a big sin in this HTML code. Yes there are 2 div elements that use the same ID "p2". What should happen when you render this page now? I have tried this code on the famous five (Chrome, Firefox, IE, Safari and Opera) and also on the Android, Opera Mobile and Firefox Mobile browsers, and they all behave exactly the same way. You will actually see that the three major criteria mentioned in the HTML5 spec, seem to work just fine.
  • Linking to a document fragment: Reduce your browser size and click on link 2, it will navigate to the first div with the ID p2
  • Styling: Both the divs with the ID p2 are styled
  • Targeting the element using JavaScript: You will see that the text (ID IS 2) of the first div with ID p2 is printed using javascript at the end of the html doc.
To summarize, linking and picking up the first element with matching ID is done and all matching elements are styled. 

But the question is, why do browsers behave this well in spite of the spec mandating the ID to be unique? The answer is that browsers have come away from the strict mode and are more relaxed in the way they handle bad code (even more so now with HTML5). They are quite developer friendly and try to render as much as possible and fail gracefully where possible. Yes, that is the way to go!

But still a word of caution, it is not recommended to use duplicate IDs as it is against the spec and the browsers could change their implementation anytime. A hundred different things could go wrong in your code and you will spend hours figuring out what the issue is.


  1. I think you meant "they are quite bad-developer friendly"

    1. Mauricio, why bad? :)
      I meant 'the browsers' are developer friendly and try to render as much as ....

    2. bad, because only bad developers use duplicated ids ;-)

  2. I don't know why I should put any stock in a standards document that uses silly words like "amongst".

  3. Does JQM use the page ID to cache page views? In a dynamic app I have problems with previous versions of pages being displayed. Would adding a time stamp to the page id force JQM to never show the cached view?

  4. I understand that browsers are so relaxed because many already existing websites have duplicate IDs. Hence having a strict implementation of this spec (ie. not render the page) would make the relevant web browser extremely impopular.

    As a compromise it'd be nice to at least be prompted for duplicate IDs in the developer tool console. No idea why this is not the case.

  5. I'm developing an automation on a site that uses this "trick," and it's quite the hassle. Here's a quick js function to clean it, if you're encountering the same problem. Of course this may not be useful for sites with scripts or styles that rely on it, though:

    function dedupid(idstring) {
    var elementlist = [];
    var messy = true;
    var counter = 1;
    var cap = 1000;
    while(messy) {
    var newid = document.getElementById(idstring);
    if(newid != null) { = + counter.toString();
    counter = counter + 1;
    else {
    messy = false;
    cap = cap - 1;
    if(cap <= 0) {
    messy = false;
    return elementlist;

  6. Can someone help me here - I have this exact issue with my website, unfortunately, I don't know what I should be using instead of duplicate IDs :-(