Спецификация HTML5 допускает практически любое значение атрибута id — пользуйтесь с умом

Автор оригинала: Roger Johansson
  • Перевод
Как я упоминал какое-то время назад в статье «Создание правильных id», HTML 4.01 достаточно ограничен с точки зрения допустимых значений атрибута id:
Атрибуты ID и NAME должны начинаться с буквы ([A-Za-z]), за которыми могут следовать любое количество букв, цифер ([0-9]), дефисов ("-"), подчеркиваний ("_"), двоеточий (":") и точек (".").

HTML5 допускает использование почти любого значения атрибута id:
Спецификация HTML5 3.2.3.1 о атрибуте id:
Значение должно быть уникально относительно всех остальных значений ID в рамках дерева элементов, содержащего данный и должно содержать как минимум один символ. Значение не должно содержать пробелов.
Как минимум один символ, без пробелов.

Это позволяет использовать в качестве значений атрибута id специальные символы. А еще это дает нам массу возможностей поставить себя в идиотское положение, так как мы можем использовать значения, которые вызовут проблемы как с CSS таки и с JavaScript, если вы не будете осторожны.

Рассмотрим следующий HTML код:
<div id="#id"></div>
<div id="div>p+p:first-child"></div>


Конфликты с селекторами CSS


Что бы обратиться к вышеуказанным элементам с помощью CSS использовать нормальный синтаксис не получится:
##id {}
#div>p+p:first-child {}


Так как id содержит символ, для которого есть предопределенное значение в CSS, вам понадобится немного поколдовать над CSS селекторами, что бы заставить их работать как надо. Один из способов — использовать селектор по значению атрибута, вместо #:
[id="#id"] {}
[id="div>p+p:first-child"] {}


Еще один способ — экранировать вызывающие конфликт символы:
#\#id {}
#div\>p\+p\:first-child {}


Проблемы с JavaScript


Если вы используете JavaScript библиотеку, вроде jQuery, для работы над нашими элементами, то это вызовет затруднения:
$("#div>p+p:first-child").css("fontSize", "2em");


Как и с CSS, вам придется экранировать специальные символы:
$("#div\\>p\\+p\\:first-child").css("fontSize", "2em");


Осмысленное именование элементов


HTML5 дает нам большую свободу в выборе значений атрибута id элементов. Это может быть иногда полезно. Но, по-моему, использовать символы, которые вызывают конфликт с CSS и JavaScript, значит просто напрашиваться на неприятности. Тоже самое с использованием клевых символов, вместо нормального читабельного текста. Пользуйтесь, если достоинства будут превалировать над рисками. Но не стоит использовать новые возможности именования только потому, что можете.

Похожие публикации

AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 71

    +20
    Не могу придумать ни одного адекватного применения данным извращениям. Просвятите плз.
      +11
      Данным извращениям применения нет. Это абстрактные примеры. Но вот проблема — вполне практического свойства. Я уже неоднократно встречал использование странных unicode символов в именовании элеменетов. Например:

      <article class="
        +1
        Хабр не вынес использования unicode символов.
          +1
          Opera 10.63 отказывается выводить всё, что идёт дальше слова «Например:» в вашем предыдущем комментарии :)
            0
            11ая тоже =(
            +5
            Хорошо, что в Опере можно править исходный код страницы =)
              0
              это просто опера не обрабатывает ничего если тэг не закрыт
                0
                тэг code (привет парсер)
              0
              злой вы: (
                +2
                Специально запустил оперу чтоб проверить — вы и правда сломали хабр)
                  0
                  FF4 тоже:)
                  0
                  В опере прекрасно, все что ниже — пустота, обновляешь комментарии и тебя переносит по белой странице.
                  +3
                  Когда данные приходят от куда-то (к примеру из бд) под своим номером (порядковым) и этот номер нужно использовать в качестве id, то в соответствии с готовящейся спецификацией не нужно будет к этому номеру делать префикс, т.к. id может полностью состоять из чисел. Мне кажется не я один сталкивался с подобным…
                    +4
                    Цифры — это хорошо и полезно, но для чего в id могут понадобиться символы вроде >#+ до сих пор непонятно.
                • НЛО прилетело и опубликовало эту надпись здесь
                    0
                    Сама спецификация дает огромное количество преимуществ.
                    Хотя бы — превосходные новые теги.
                  • НЛО прилетело и опубликовало эту надпись здесь
                      +3
                      Страшно даже представить на что тогда способны сами авторы этой спецификации?
                      • НЛО прилетело и опубликовало эту надпись здесь
                          +1
                          да и поздно
                      +4
                      из серии «меньше знаешь — крепче спишь»)
                        +2
                        Под «клевыми» имеются в виду «клёвые» или «левые»?
                          0
                          По моему, и то и то)
                          –1
                          Единственно, как использую, начну в повторяющихся блоках цифры писать первыми, а не в конце.
                          Хотя, учитывая.рф и UTF8, можно кириллицу начать насаждать.
                            +2
                            >>Спецификация HTML5 допускает практически любое значение атрибута id — пользуйтесь с умом
                            Я думал, что статья будет о магии JS и CSS c новыми стандартами и как можно умно их использовать.
                              +1
                              > Проблемы с JavaScript
                              Я б скорее всего назвал это «проблемы с jQuery», т.к. в примере проблемы в использовании фреймворка (а если еще точнее, все те же селекторы). С самим JS проблем не должно быть: document.getElementById("#id") должен отработать на ура.

                              А если честно, проблема надуманная. Хочешь юзай, хачешь нет. Они ж не заставляют использовать символы, имеющие значение в селекторах. Использование id не ограничевается только селекторами.
                                +2
                                А document.querySelector?
                                  +1
                                  Да, не подумал про querySelector. Но все равно все сводится к одному — к селекторам. Так что резюмируя увиденное, правильней будет сказать, что конфликт МОЖЕТ БЫТЬ с селекторами, и не важно где они юзаются: js, какой-нибудь js-фреймфорк, css или еще что.
                                    0
                                    Так и есть.
                                +1
                                Извращение конечно еще то :) но знать способы лечения полезно любому веб-кодеру
                                  0
                                  Вы сломали Хабр!((
                                    0
                                    хабр не закрыл...
                                      +2
                                      Наконец-то по стандарту будет множество способов отстрелить себе ногу.
                                        +2
                                        Как минимум это будет полезно при обфускации. Плюс, это можно использовать при генерации динамических структур джаваскриптом вместо всяких там id=«element_1291201520733».
                                          +2
                                          <div id="div>p+p:first-child"></div>
                                          такой атрибут приведет и к еще одной проблеме, одним из очень распространенных шаблонов поиска тэгов (для удаления, например) регулярными выражениями является такой — /<\/?[^^>]+>/. В данном случае он поломается, так как отработает на скобке внутри значения id. Как и множество других шаблонов построенных на исключении символа >

                                          Может я тупой, но я не понимаю зачем в атрибутах допустили спецсимволы самого языка, ни к чему хорошему это не приведет и привести не может.
                                            0
                                            Полностью согласен. Сам в некотором недоумении.
                                              0
                                              Думаю автор ошибся назвав этот id допустимым. По-моему, все <, > и & должны быть экранированы, даже в аттрибутах.
                                                0
                                                Спецификация утверждает обратное -)
                                                  0
                                                  В спецификации написано немного замутно, но все же там описано, что недопустимо использовать < и >. Амперсанд можно использовать только тогда, когда он не является частью сущности.
                                                    0
                                                    Можно цитату и ссылочку? Не могу найти.
                                                      0
                                                      Конечно можно. Вот тут написано следующее:

                                                      Unquoted attribute value syntax
                                                      … followed by the attribute value, which, in addition to the requirements given above for attribute values, must not contain any literal space characters, any U+0022 QUOTATION MARK characters ("), U+0027 APOSTROPHE characters ('), U+003D EQUALS SIGN characters (=), U+003C LESS-THAN SIGN characters (<), U+003E GREATER-THAN SIGN characters (>), or U+0060 GRAVE ACCENT characters (`),…


                                                      и чуть ниже формулировка звучит
                                                      ...followed by the attribute value, which, in addition to the requirements given above for attribute values...


                                                      Исключения для разных случаев в спеке размазаны тонким слоем. Именно поэтому кажется, что разрешено все.
                                                  0
                                                  В том то и дело, что похоже что нет. Вот такой пример:

                                                  <!DOCTYPE html>
                                                  <head><title></title></head>
                                                  <div id=">">aaa</div>
                                                  

                                                  валидацию в случае html5 проходит, а в случае html4.01 — нет (character ">" is not allowed in the value of attribute «ID»)

                                                  А ведь туда и кавычку теперь можно…
                                                    –1
                                                    Вот уроды (с)

                                                    Думаю всё это изменится. Потому как в случае id="&quot;" не совсем ясно как искать: через getElementById('"') или getElementById('&quot;'). Для тех кто считает что и так и так, есть еще "&amp;" с которым можно и в рекурсию уйти :)
                                                      +2
                                                      <!DOCTYPE html>
                                                      <head><title></title></head>
                                                      <div title=">">aaa</div>
                                                      


                                                      в случае html4.01 проходит валидацию, а парсер все равно упадет ;)
                                                        0
                                                        жесть
                                                  0
                                                  Ваш пример некорректен, > можно указать в любом аттрибуте. Поддерживаю denver, все < и > не должны использоваться нигде, кроме как для тегов, в остальных местах должны использоваться < и >
                                                    0
                                                    упс, должны использоваться &lt; и &gt;
                                                    +1
                                                    Парсеры вообще сложная штука. Я с некоторых пор предпочитаю использовать готовые, ибо полумеры вроде этой регулярки только добавляют проблем.
                                                      0
                                                      Ну, для нового языка надо переписывать шаблоны согласно его спецификации, либо скармливать парсеру только те строки, которые совместимы с шаблоном.
                                                      +2
                                                      Может не совсем в тему, но в html5 есть узаконенные микроформаты, начинающиеся с «data»: , предназначенные для хранения любой информации в тегах. Так что фиг с ним, с id-ом
                                                        0
                                                        1. data- не имеют ничего общего с микроформатами. На роль микроформатов в w3c придумал RDFa www.w3.org/TR/2010/WD-rdfa-core-20101026/
                                                        Хотя, да, его можно использовать и так. Только не ясно, кто это будет интерпретировать и зачем так делать, если еcть RDFa.

                                                        2. А какое это отношение имеет к id? Вы в нем хранили какие то данные (кроме уникального id записи в базе ничего в голову не приходит)?
                                                          0
                                                          id из базы нельзя хранить, потому что атрибут id должен начинаться с буквы.
                                                            0
                                                            А кто сказал, что id должен начинаться не с буквы? :)
                                                              0
                                                              1. В HTML5 не должен. Минимум 1 символ. Без пробелов.
                                                              2. префиксов это не отменяет.
                                                          0
                                                          Ну, во-первых, HTML5 всё ещё в разработке.

                                                          Во-вторых, в CSS непринято использовать ID — это привилегия JS. Поэтому у хорошего верстальщика такой проблемы не возникнет. Плюс есть эскейпы.

                                                          В-третьих, с JS проблем нет, потому как jQuery не JS, а сторонняя либа, а querySelector находится в скоупе Selectors API Level 1, которая до сих пор Candidate и формально не финализирована. К тому же есть эскейпы, так что даже в случае формализации ничего не поломается. У вас же, я надеюсь, JS не ломается от того, что вы внутрь строк кавычки вставляете?

                                                          Проблему считаю надуманной.
                                                            0
                                                            в CSS непринято использовать ID — это привилегия JS.

                                                            Угу, а селекторы для адресации через ID придумали в качестве злой шутки.
                                                            На самом деле вы конечно правы. Действительно не принято и на то есть ряд причин.
                                                            Но надеятся на то, что то непринятно нельзя. Я регулярно встречаю макеты с адресацией блоков через id.
                                                            Как минимум блоки типа подвала/шапки/враппера основнога контентного блока.

                                                            Что касается проблемы… автор, помоему, хотел намекнуть, что ограничения все же не помешали бы. И он это проиллюстрировал чудесным примером.
                                                              0
                                                              p.s. проблема будет надуманной, пока вы не столкнетесь с необходимостью отладить здоровенный скрипт, который не работает при переносе на новую верстку. Особенно это можно прочувствовать, если понадобится его весь перебрать, что бы обезопасить генерируемые в процессе работы селекторы.
                                                                0
                                                                Ну смотрите, если у вас есть готовый проект и к нему есть готовый JS и вот пришло задание поменять HTML целиком и полностью оставив скрипты рабочими. Неужто вы HTML измените так, чтобы JS поломался? Я думаю нет, иначе это камень уже в ваш огород. Так что проблема всё-таки надумана.
                                                                  0
                                                                  js и html могут делать разные подрядчики.
                                                                    0
                                                                    Если они не будут согласовывать свои действия, то фигня выйдет в любом случае. Более понятный пример: вы заказываете у одного подрядчика автомобиль, а у другого — поставку топлива. Если они ничего не знаю друг о друге никаким образом, то вам дадут автомобиль с дизельным двигателем, а топливо поставят в виде бензина. Что получится? Фигня. Заметьте, это не проблема самих подрядчиков, а также не проблема технологии производства топлива или изготовления двигателей. Это проблема отсутствия мозга у заказчика.
                                                                0
                                                                в CSS не принято использовать ID — это привилегия JS.

                                                                Не принято кем? С каких пор это привилегия JS? Пруф, в какой спеке это описано?
                                                                ID нужен для обозначения уникального блока, а не «для того, чтобы использовать в JS».
                                                                  0
                                                                  Ответ ниже, промазал…
                                                                0
                                                                У выражений «не принято» и «запрещено» разный смысл. В спеках редко пишут что принято, а что нет. Если вы не занимаетесь вёрсткой профессионально, то советую посмотреть и почитать доклад Виталия Харисова, чтобы понимать как этим занимаются. Доклад на русском, всё будет понятно. Он доступен в архиве Я.Субботников — company.yandex.ru/public/subbotnik/ и называется Вёрстка элементов страниц в общем виде.
                                                                  0
                                                                  а кто это такой? я вас не подъёбываю, но почему этот источник — авторитетный. между прочим, школьная ошибка на личном сайте (у меня тёмный дизайн системы):
                                                                  />
                                                                  А ведь много раз описано — меняете бекграунд — меняйте и цвет шрифта. Даже если вам нужен чёрный. Мне даже Идея, когда я в ней верстал, подчёркивала эту ошибку.

                                                                  В спецификации есть много не только явных указаний, но и рекомендаций.
                                                                  Имхо, использование JavaScript отталкиваясь от АйДи — это архаизм с тех времен, когда не было таких удобных инструментов, как querySelector для получения нужного элемента. Если вёрстка нормальная — джаваскрипт программист _вообще_ не должен трогать её. Даже для того, чтобы добавить АйДи.
                                                                    0
                                                                    Картинка:
                                                                      0
                                                                      Виталий — человек в теме (:

                                                                      Вот вы сами говорите, что ID сегодня и в JS редко нужны, но в CSS их вам сунуть сильно хочется. Зачем?
                                                                        0
                                                                        кто сказал, что мне «хочется»? я считаю, что они должны стоять там, где должны стоять. и их явно должны ставить не жс-программисты
                                                                          0
                                                                          жс-программисты вообще вёрстку трогать не должны в идеале
                                                                            0
                                                                            А конкретно с этим я и не спорю. Но как это повлияет на js и css? Да, собственно, никак.
                                                                      +1
                                                                      Двоеточия и точки в идентификаторах HTML 4 уже конфликтуют с синтаксисом CSS.
                                                                        0
                                                                        Горловина бензобака автомобиля дает нам большую свободу в выборе субстанции, которую можно поместить внутрь бензобака. Это может быть иногда полезно. Но, по-моему, использовать вещества, которые не предназначены для использования в качестве топлива для ДВС, значит просто напрашиваться на неприятности. Тоже самое с использованием воды или песка, вместо нормального бензина. Пользуйтесь, если достоинства будут превалировать над рисками. Но не стоит использовать возможности горловины бензобака только потому, что можете.

                                                                        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                                        Самое читаемое