Can multiple HTML elements have the same ID if they're of different element types? Is a scenario like this valid? Eg:

div#foo
span#foo
a#foo

Solution 1

No.

Element IDs should be unique within the entire document.

Solution 2

I think there is a difference between whether something SHOULD be unique or MUST be unique (i.e. enforced by web browsers).

Should IDs be unique? YES.

Must IDs be unique? NO, at least IE and FireFox allow multiple elements to have the same ID.

Solution 3

Can multiple elements have the same ID?

Yes - whether they are the same tag or not, browsers will render the page even if multiple elements have the same ID.

Is it Valid HTML?

No. This is still true as of the HTML 5.1 spec. However, the spec also says getElementById must return the first element with the given ID, making the behavior not undefined in the case of an invalid document.

What are the consequences of this type of invalid HTML?

Most (if not all) browsers select the first element with a given ID, when calling getElementById. Some libraries that find elements by ID inherit this behavior, while newer libraries (as gman points out in his answer) will use the more explicit querySelector and querySelectorAll methods, which unambiguously select either the first or all matching elements, respectively. 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 by getElementById, 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

It's best to stick to the standards, but if you know 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 not to do this:

  1. 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.
  2. To maintain forward-compatibility of your website/application with libraries or services (or developers!) you may encounter in the future, that do malfunction when multiple elements have the same ID - which is a reasonable possibility since this is not, technically, valid HTML.

The power is yours!

Solution 4

Even if the elements are of different types it can cause you some serious problems...

Suppose you have 3 buttons with the same id:

<button id="myid" data-mydata="this is button 1">button 1</button>
<button id="myid" data-mydata="this is button 2">button 2</button>
<button id="myid" data-mydata="this is button 3">button 3</button>

Now you setup some jQuery code to do something when myid buttons are clicked:

$(document).ready(function ()
{
    $("#myid").click(function ()
    {
        var buttonData = $(this).data("mydata");

        // Call interesting function...
        interestingFunction();

        $('form').trigger('submit');
    });
});

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. :)

<button id="button1" class="mybtn" data-mydata="this is button 1">button 1</button>
<button id="button2" class="mybtn" data-mydata="this is button 2">button 2</button>
<button id="button3" class="mybtn" data-mydata="this is button 3">button 3</button>

Now if you want the click event handler to run when any of the buttons get clicked it will work perfectly if you change the selector in the jQuery code to use the CSS class applied to them like this:

$(document).ready(function ()
{
    $(".mybtn").click(function ()
    {
        var buttonData = $(this).data("mydata");

        // Call interesting function...
        interstingFunction();

        $('form').trigger('submit');
    });
});

Solution 5

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:

<div class="myclass sexy"></div>

Solution 6

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).

Solution 7

How about a pragmatic answer.

Let's go to youtube and run this code

Object.fromEntries(Object.entries([...document.querySelectorAll('[id]')].reduce((s, e) => { s[e.id] = (s[e.id] || 0) + 1; return s; }, {})).filter(([k,v]) => v > 1))

and see all the repeated ids.

Changing the code above to show ids repeated more than 10 times here's the list it produced

additional-metadata-line: 43
avatar: 46
avatar-link: 43
button: 120
buttons: 45
byline-container: 45
channel-name: 44
container: 51
content: 49
details: 43
dismissable: 46
dismissed: 46
dismissed-content: 43
hover-overlays: 45
img: 90
menu: 50
meta: 44
metadata: 44
metadata-line: 43
mouseover-overlay: 45
overlays: 45
repeat: 36
separator: 43
text: 49
text-container: 44
thumbnail: 46
tooltip: 80
top-level-buttons: 45
video-title: 43
video-title-link: 43

Other sites that use the same id more than once include Amazon.com, ebay.com, expedia.com, cnn.com

clearly ids are just another piece of metadata on an element.

getElementById is pretty much obsolete. You can use querySelectorAll for all elements or querySelector for the first, regardless of selector so if you want all elements with id foo then

document.querySelectorAll('#foo')  // returns all elements with id="foo"

where as if you want only the first element use querySelector

document.querySelector('#foo')  // returns the first element with id="foo"
document.querySelector('.foo')  // returns the first element with class "foo"
document.querySelector('foo')   // returns the first <foo> element
document.querySelector('foo .foo #foo') // returns the first element with
                                        // id="foo" that has an ancestor
                                        // with class "foo" who has an
                                        // ancestor <foo> element.

And we can see that using selectors we can find different elements with the same id.

function addClick(selector, add) {
  document.querySelector(selector).addEventListener('click', function() {
    const e = this.parentElement.querySelector('#value');
    e.textContent = parseInt(e.textContent) + add;
  });
}
addClick('.e #foo', 1);
addClick('.f #foo', 10);
body { font-size: x-large; font-weight: bold; }
.a #foo { color: red; }
.b #foo { color: green; }
div:nth-child(3) #foo { color: blue; }
#foo { color: purple }
<div class="a"><span id="foo">a</span></div>
<div class="b"><span id="foo">b</span></div>
<div><span id="foo">c</span></div>
<span id="foo">d</span>
<div class="e"><button type="button" id="foo">+1</button>: <span id="value">0</span></div>
<div class="f"><button type="button" id="foo">+10</button>: <span id="value">0</span></div>

Where it matters that id is unique

  • <a> tags can reference ids as in <a href="#foo">. Clicking it will jump the document to the first element with id="foo". Similarly the hash tag in the URL which is effectively the same feature.

  • <label> tags have a for attribute that specifies which element they are labeling by id. Clicking the label clicks/activates/give-the-focus-to the corresponding element. The label will only affect the first element with a matching id

Otherwise, id is just another tool in your toolbox.

Solution 8

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.

Solution 9

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.

e.g.

<div id="one">first text for one</div>
<div id="one">second text for one</div>

and

alert($('#one').size());

See http://jsfiddle.net/RuysX/ for a test.

Solution 10

Well, using the HTML validator at w3.org, specific to HTML5, IDs must be unique

Consider the following...

<!DOCTYPE html> 
<html>
    <head>
        <meta charset="UTF-8">
        <title>MyTitle</title> 
    </head>
    <body>
        <div id="x">Barry</div>
        <div id="x">was</div>
        <div id="x">here</div>
    </body>
</html>

the validator responds with ...

Line 9, Column 14: Duplicate ID x.      <div id="x">was</div>
Warning Line 8, Column 14: The first occurrence of ID x was here.       <div id="x">Barry</div>
Error Line 10, Column 14: Duplicate ID x.       <div id="x">here</div>
Warning Line 8, Column 14: The first occurrence of ID x was here.       <div id="x">Barry</div>

... but the OP specifically stated - what about different element types. So consider the following HTML...

<!DOCTYPE html> 
<html>
    <head>
        <meta charset="UTF-8">
        <title>MyTitle</title> 
    </head>
    <body>
        <div id="x">barry
            <span id="x">was here</span>
        </div>
    </body>
</html>

... the result from the validator is...

Line 9, Column 16: Duplicate ID x.          <span id="x">was here</span>
Warning Line 8, Column 14: The first occurrence of ID x was here.       <div id="x">barry

Conclusion:

In either case (same element type, or different element type), if the id is used more than once it is not considered valid HTML5.

Solution 11

Yes they can.

I don't know if all these anwers are outdated, but just open youtube and inspect the html. Try to inspect the suggested videos, you'll see that they all have the same Id and repeating structure as follows:

<span id="video-title" class="style-scope ytd-compact-radio-renderer" title="Mix - LARA TACTICAL">

Solution 12

<div id="one">first text for one</div>
<div id="one">second text for one</div>

var ids = document.getElementById('one');

ids contain only first div element. So even if there are multiple elements with the same id, the document object will return only first match.

Solution 13

It's possible to have duplicate ids. I have tried adding the todoitem from javascript and it added to the dom successfully. This is the html code and javscript code.

Solution 14

Nope, IDs have to be unique. You can use classes for that purpose

<div class="a" /><div class="a b" /><span class="a" />

div.a {font: ...;}
/* or just: */
.a {prop: value;}

Solution 15

Is it possible to have more than one student in a class having same Roll/Id no? In HTMLid attribute is like so. You may use same class for them. e.g:

<div class="a b c"></div>
<div class="a b c d"></div>

And so on.

Solution 16

We can use class name instead of using id. html id are should be unique but classes are not. when retrieving data using class name can reduce number of code lines in your js files.

$(document).ready(function ()
{
    $(".class_name").click(function ()
    {
        //code
    });
});

Solution 17

I think you can't do it because Id is unique you have to use it for one element . You can use class for the purpose