Skip to main content

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 :-(



Post a Comment

Popular posts from this blog

Minimal required code in HTML5

I've encountered this question repeatedly of late. "What are the tags required at bare minimum for a html file?" Earlier there were a bunch of mandatory tags that were required for any html file. At bare minimum, the recommended structure was: (ref: ) <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" ""> <HTML>   <HEAD>     <TITLE>A small HTML</TITLE>   </HEAD>   <BODY>     <P>Small HTML file!</P>   </BODY> </HTML> Yes, using capitals for the tags was the way to go! Those were the days of the purists and strict was the way to be. Now open your notepad and copy the above code, save the file as old.html and launch it in Chrome or Firefox. You will see only one line "Small HTML file!" shown. Now launch the developer tools in Chrome or Inspect Element in Firefox. Thi

Fixing Date, Time and Zone on RHEL 6 command line

Had to fix all time related issues on a remote RHEL 6 server which runs without any windowing system. Plain ol' command line. Documenting steps here for future reference: Check to see if your date and timezone settings are accurate: # date # cat /etc/sysconfig/clock The server I accessed had wrong settings for both the commands. Here are the steps I used to correct: Find out your timezone from the folder /usr/share/zoneinfo # ls /usr/share/zoneinfo Mine was pointing to America/EDT instead of  Asia/Calcutta Update and save the /etc/sysconfig/clock file to # sudo vi /etc/sysconfig/clock ZONE="Asia/Calcutta" UTC=true ARC=false Remove the /etc/localtime # sudo rm /etc/localtime Create a new soft link to your time zone # cd /etc # sudo ln -s /usr/share/zoneinfo/Asia/Calcutta /etc/localtime # ls -al localtime Now it should show the link to your time zone Set your hardware clock to UTC # sudo hwclock --systohc --utc # hwclock --show Update your t