Несколько элементов с одинаковым идентификатором, отвечающим одному из селекторов идентификаторов CSS

Можно ли предоставить несколько элементов одному и тому же идентификатору на одной странице? Например, это часто случается при использовании некоторых jquery-плагинов, когда вы запускаете слайдер или галерею дважды или более. Мы знаем, что разработчики хотели бы предоставить некоторый ID контейнеру html, чтобы script работал быстрее.

Давайте прочитаем документацию w3.org:

Что делает атрибуты типа ID особенными, так это отсутствие двух таких атрибуты могут иметь одинаковое значение; независимо от языка документа, Идентификатор атрибута может использоваться для однозначной идентификации его элемента.

Но следующий пример с двумя элементами с одинаковым идентификатором отлично работает во всех браузерах, хотя он недействителен:

#red {
  color: red;
}
<p id="red">I am a red text.</p>
<p id="red">I am a red text too.</p>

Ответ 1

Браузеры всегда стараются "терпеть неудачу". Это означает, что даже если ваш HTML недействителен, браузер попытается угадать, каковы ваши намерения, и обработать его соответствующим образом.

Однако отклонение от спецификации может вызвать некоторые очень непредвиденные побочные эффекты.

Например:

document.getElementById('red');

вы получите только первый.

Вам также придется тестировать свою страницу во всех браузерах, которые могут использовать ваши пользователи, чтобы убедиться, что ваш код работает по назначению. Вы не можете просто предположить, что он сработает.

Короче: Не делайте этого! Если вам нужно настроить таргетинг на несколько элементов с одним и тем же CSS, используйте имя класса. Это то, что они были предназначены для...


Сказав это; если вы действительно должны выбрать несколько элементов с одинаковым идентификатором, используйте селектор атрибутов:

document.querySelectorAll('p[id="red"]');

Обратите внимание, что это не работает в IE7 и ниже...

Ответ 2

Можно ли предоставить несколько элементов одному ID на одной странице?

Как вы знаете, это против правил проверки, чтобы предоставить более одного элемента один и тот же идентификатор на одной странице. Однако правила нарушены, и в мире сумок HTML-тегов браузеры должны учитывать эти нарушенные правила, не разбивая страницы, следовательно, поведение, которое вы наблюдаете.

Хотя браузеры показали, что они ведут себя одинаково, даже если вы это сделаете (к счастью, в ситуациях, когда это не может помочь), я бы не назвал это полностью "безопасным", чтобы сделать это, поскольку такое поведение может не быть последовательным или надежным.

Лучше всего следовать правилам так же верно, как вы можете, и только нарушать правила, если у вас есть очень, очень веские причины (и вы почти никогда не будете, так что даже рассмотрим его). В противном случае как сказал Джозеф Сильбер, используйте классы, разработанные специально для классификации или группировки нескольких элементов.

Кто-нибудь может объяснить эту странную ситуацию?

Уникальность идентификаторов в HTML-документе не применяется или не используется CSS; вместо этого спецификация Selectors просто устанавливает это:

Селектор ID представляет экземпляр элемента, который имеет идентификатор, который соответствует идентификатору в селекторе ID.

Обратите внимание на использование слова "an" во всем этом предложении.

Вслед за этим утверждением используются некоторые примеры, в которых вместо этого используется слово "any":

Следующий идентификатор селектора представляет любой элемент, чей атрибут с идентификатором имеет значение "chapter1":

#chapter1

Следующий селектор представляет любой элемент, чей атрибут с идентификатором имеет значение "z98y".

*#z98y

Предположение о согласованном документе уточняется уровнем 3 спецификации Selectors рядом с началом раздела (выделение мое):

Что делает атрибуты специального идентификатора типа, что два таких атрибута не могут иметь одно и то же значение в согласованном документе, независимо от типа элементов, которые их переносят; независимо от языка документа, атрибут с идентификатором может использоваться для однозначной идентификации его элемента.

Где "соответствие" относится к соответствию HTML, а не CSS. Имейте в виду, что этот текст отсутствует в спецификации уровня 2, который вы указываете в своем вопросе.

Имейте в виду, что цитируемый текст не является нормативным. Хотя это способ помочь разработчикам разрабатывать случаи обработки ошибок, это не обязательное правило, которым нужно следовать, и действительно, любая реализация может вести себя по-другому, не нарушая спецификации. Не пишите недействительный HTML, чтобы воспользоваться тем, что может показаться ожидаемым или последовательным поведением, потому что вы не можете гарантировать, что такое поведение останется таким. Любая реализация CSS может свободно сопоставлять элементы, которые используют один и тот же идентификатор по-разному или даже полностью согласуют их, если он решает, как он должен обрабатывать документы, нарушающие это правило.

Другими словами: только потому, что вы можете, это не значит, что вы должны.

Ответ 3

Это работает с простым стилем HTML, но не будет работать с запросами.

Из документации API jQuery:

Каждое значение id должно использоваться только один раз в документе. Если больше, чем одному элементу был присвоен одинаковый идентификатор, запросы, которые используют этот идентификатор будет выбирать только первый согласованный элемент в DOM. Это поведение не следует полагаться, однако; документ с более чем одним элемент с использованием того же идентификатора недействителен.