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

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

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

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

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

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

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

3 ответа

Решение

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

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

Например:

document.getElementById('red');

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

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

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


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

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

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

Безопасно ли присваивать нескольким элементам одинаковый идентификатор на одной странице?

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

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

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

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

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

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

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

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

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

#chapter1

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

*#z98y

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

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

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

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

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

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

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

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

Другие вопросы по тегам