Атрибут id задаёт элементу страницы уникальное название: <h2 id="price">. По этому названию на элемент ссылаются из адреса (#price), из CSS, из JavaScript и из других атрибутов, например for у label. Атрибут глобальный, его можно прописать любому тегу, но одно и то же значение на странице должно встречаться один раз.
<a href="#price">К ценам</a>
<h2 id="price">Цены</h2>
В этой статье
- Атрибут id в HTML: что это и на каких тегах работает
- Значение атрибута id: правила записи
- Атрибуты id и class (и name): чем отличаются
- Какие атрибуты принимают id как значение
- Атрибут id как якорь: ссылка на часть страницы
- Атрибут id в CSS и JavaScript
- Что будет, если id повторяется
- Частые ошибки с атрибутом id
- Шпаргалка по атрибуту id
Атрибут id в HTML: что это и на каких тегах работает
Название атрибута сокращает слово identifier, «идентификатор». Он входит в глобальные атрибуты и применим к любому HTML-тегу. Значение задаётся строкой, и у элемента оно только одно. Общие правила записи атрибутов разобраны в уроке Теги, атрибуты и вложенность.
У id четыре задачи:
- Адрес части страницы. Ссылка
#priceведёт к элементу с таким id, подробности в разделе про якоря. - Выбор в CSS. Селектор
#priceописывает ровно один элемент. - Поиск в JavaScript. Метод
getElementByIdвозвращает элемент по его id. - Связь элементов. Ряд атрибутов хранит id другого элемента:
forуlabel,aria-labelledby,popovertargetи другие, список в таблице.
Прописывать id каждому элементу не нужно, он нужен только тем элементам, на которые ссылаются. Чтобы оформить сразу несколько блоков, подходит class, различия показаны в сравнении.
Значение атрибута id: правила записи
Что нужно знать о значении id:
- Уникальность. В документе нет другого элемента с таким id.
- Непустое значение. Запись
id=""считается ошибкой. - Без пробельных символов. Пробел, табуляция и перенос строки запрещены. Для нескольких слов берут дефис:
main-menu. - Регистр различается.
Menuиmenu- два разных id.
Всё остальное разрешено: цифра в начале, дефис, подчёркивание, точка, кириллица. Но допустимое в HTML не всегда удобно в CSS. Селектор #1st вызывает ошибку, а #x.y читается как id x вместе с классом y. Поэтому id записывают латиницей, строчными буквами, через дефис и начинают с буквы: main-menu, price-table. Подробное описание есть в справочнике MDN.
Пример: какое значение id можно записать
Выберите значение и посмотрите, можно ли так записать id. Верхняя строка показывает, как значение выглядит в теге.
Атрибуты id и class (и name): чем отличаются
Три атрибута похожи тем, что хранят строку, но решают разные задачи. id задаёт название одному элементу, class объединяет группу, name задаёт название данных у полей формы и нескольких других тегов.
| Признак | id | class | name |
|---|---|---|---|
| Сколько элементов с одним значением | Один на странице | Сколько угодно | Сколько угодно, у радиокнопок группа с общим названием |
| Сколько значений у одного элемента | Одно | Несколько через пробел: class="a b" | Одно |
| На каких тегах | На любом | На любом | Только на отдельных: поля формы, form, iframe, map, meta, details |
| Для чего нужен | Единственный элемент: якорь, скрипт, связь с другим тегом | Оформление и выбор группы элементов | Название данных при отправке формы |
| Селектор в CSS | #price | .price | [name="price"] |
| Вес в CSS | Выше, чем у любого числа классов | Меньше, чем у id | Как у класса |
Переход по ссылке #значение | Да | Нет | Нет, кроме устаревшего a name |
Если элемент один и на него нужна ссылка или связь, прописывают id. Если стиль повторяется на нескольких блоках, прописывают class. Как браузер выбирает победителя между id и классом, объясняет урок Каскад и специфичность: что побеждает в CSS, а сами селекторы описаны в уроке Селекторы типа, класса и id.
Какие атрибуты принимают id как значение
Значение id записывают не только в самом элементе. Ряд атрибутов других тегов указывает на элемент именно по этому значению. Если связь нарушена, она просто не срабатывает, а ошибку браузер не показывает.
| Атрибут | Где работает | На какой id указывает | Пример |
|---|---|---|---|
for | label, output | Поле формы. У output список id через пробел | <label for="email"> |
form | button, fieldset, input, object, output, select, textarea | Форма, даже если элемент находится снаружи | <input form="search"> |
list | input | Список подсказок datalist | <input list="cities"> |
headers | td, th | Ячейки-заголовки, список id через пробел | <td headers="h1 h2"> |
popovertarget | button, input | Элемент с атрибутом popover | <button popovertarget="tip"> |
commandfor | button | Элемент, которому адресована команда | <button commandfor="dlg"> |
itemref | Любой тег с itemscope | Элементы с микроразметкой, список через пробел | <div itemref="author"> |
aria-labelledby | Любой тег | Элементы, чей текст служит названием, список через пробел | <section aria-labelledby="title"> |
aria-describedby | Любой тег | Элементы с пояснением, список через пробел | <input aria-describedby="hint"> |
aria-controls | Любой тег | Элементы, которыми управляет этот элемент | <button aria-controls="menu"> |
href | a, area | Якорь: адрес со знаком решётки | <a href="#price"> |
Самая частая связь - for и id у поля формы. Подробности по этим связям на страницах label, output и datalist, а для ячеек таблицы - на странице th. Атрибут usemap у картинки ссылается не на id, а на значение name у карты, см. страницу map.
<label for="email">Почта</label>
<input id="email" type="email">
Клик по надписи переводит фокус в поле, потому что значение for совпадает с id. Если изменить одно из значений, связь пропадёт.
Атрибут id как якорь: ссылка на часть страницы
Если после адреса страницы записать знак решётки и id, браузер откроет страницу сразу на этом элементе. То же делает ссылка href="#price" внутри страницы. Регистр учитывается: ссылка #Price к элементу с id="price" не приведёт, страница останется на месте. Значения на кириллице тоже работают, браузер сам кодирует их в адресе. Ссылки # и #top ведут в начало страницы, даже если такого id нет.
<a href="#price">К ценам</a>
<h2 id="price">Цены</h2>
:target {
background: #fff3b0;
}
h2[id] {
scroll-margin-top: 80px;
}
Псевдокласс :target описывает элемент, на который указывает адрес. Свойство scroll-margin-top оставляет отступ сверху, чтобы закреплённая шапка не закрывала заголовок после перехода. Если на странице несколько элементов с одним id, переход ведёт к первому, это показано в разделе про повторы. Ссылкам на часть страницы посвящён раздел урока Ссылка на часть текущей страницы, а о самом теге читайте на странице a.
Атрибут id в CSS и JavaScript
В CSS id записывают после решётки. Такой селектор весомее любого количества классов, поэтому правило с id трудно переопределить. Для оформления группы блоков лучше выбирать класс, id оставляют для единственного элемента. Если значение начинается с цифры или содержит точку, символы экранируют обратной косой чертой: #\31 st вместо #1st. Вычислять код вручную не нужно: его выдаёт метод CSS.escape().
#price {
color: #c0392b;
}
#\31 st {
font-weight: 700;
}
В JavaScript элемент находят по id методом getElementById. Ему передают значение без решётки. Для селектора с решёткой подходят querySelector и querySelectorAll. Само значение читается и меняется через свойство id, а удалить его можно методом removeAttribute.
const title = document.getElementById("price");
const same = document.querySelector("#price");
title.id; // "price"
title.id = "cost"; // новый id
title.removeAttribute("id");
document.querySelector("#" + CSS.escape("1st"));
Браузер также создаёт на window свойства с названиями из id, поэтому в скрипте можно написать price вместо поиска. Пользоваться этим не стоит. Если в скрипте уже есть переменная с таким названием, побеждает переменная, а при повторе id вместо элемента вернётся коллекция.
Что будет, если id повторяется
Браузер повтор id не блокирует и ошибки не показывает. Страница продолжает работать, но разные части разметки ведут себя по-разному: getElementById и ссылка вида #card берут первый элемент, селектор #card находит оба, а window.card возвращает коллекцию. Такая разница и делает ошибку трудной для поиска. Валидатор Nu сообщает о повторе как об ошибке.
Пример: что находит скрипт при повторе id
При одинаковом id метод getElementById находит только блок A. Когда id разные, находятся оба блока.
Частые ошибки с атрибутом id
Чаще всего id ломают повтором, пробелом, регистром и забытым экранированием.
| Ошибка | Что происходит | Как исправить |
|---|---|---|
<li id="item"> в каждом пункте списка | Скрипт и ссылка находят только первый пункт | Дать пунктам class или разные id: item-1, item-2 |
id="main menu" с пробелом | Стандарт запрещает такое значение, а селектор #main menu ищет тег menu внутри #main | Писать через дефис: main-menu |
#1st в CSS или в querySelector | Ошибка записи селектора, правило не применяется | Начинать id с буквы или записать #\31 st, а в скрипте брать CSS.escape |
| id вместо class для нескольких блоков | Стиль работает, но скрипт и ссылка находят только первый блок, валидатор сообщает об ошибке, а высокий вес правила мешает переопределить стиль | Прописать class и селектор .card |
href="#Price" при id="price" | Ссылка не прокручивает страницу | Писать значения одинаково, лучше строчными буквами |
for="mail" при id="email" | Клик по надписи не переводит фокус в поле | Сверить значения символ в символ |
id="#price" со знаком решётки внутри | Ссылка #price ищет id price и элемент с id #price не находит, а в CSS нужен #\#price | Решётку в значение не записывать |
data-id="5" вместо id="5" | Это другой атрибут, getElementById его не видит и якорь не срабатывает | Нужен якорь или поиск - прописать id, нужны данные для скрипта - оставить data-id |
Шпаргалка по атрибуту id
| Правило | Что запомнить |
|---|---|
| Где работает | На любом теге |
| Значений у элемента | Одно |
| Повторы на странице | Не допускаются |
| Пустое значение | Нельзя |
| Пробелы | Нельзя, вместо них дефис |
| Регистр | Различается: Menu и menu |
| Начало значения | Лучше с буквы |
| Ссылка на элемент | href="#значение" |
| Поиск в JavaScript | getElementById("значение") |
| Селектор в CSS | #значение, спецсимволы через CSS.escape |