Тег dl (от английского description list, «список описаний») собирает пары «название и значение». Внутри него записывают группы: dt (description term) задаёт название, а dd (description details) — значение или описание. Это парные теги, закрывающие </dt> и </dd> можно опустить. Браузер выводит название с новой строки, а описание сдвигает вправо: ни маркеров, ни номеров у такого списка нет.
Урок «Когда использовать dl вместо обычного списка» объясняет, когда вместо обычного списка нужен dl. Здесь разберём другое: как записать группы так, чтобы разметка прошла проверку, собрать две колонки без сбоя при двух dd, сделать адаптив и точки-заполнители в прайсе.
<dl>
<dt>HTML</dt>
<dd>Язык разметки страниц</dd>
<dt>CSS</dt>
<dd>Язык стилей страниц</dd>
</dl>
В этой статье
- Тег dl в HTML: что это и из чего состоит список определений
- Где можно записать тег dl и что допустимо внутри него
- Группы dt и dd в теге dl: один к одному и один ко многим
- Тег dl с div-обёрткой: одна группа - один div
- Что записать внутри dt и dd тега dl: p, ul, a и вложенный dl
- Для чего нужен тег dl: характеристики, глоссарий, вопросы и ответы
- Отступы тега dl по умолчанию: margin у dl и dd
- Две колонки в теге dl через grid и ловушка с двумя dd
- Адаптивный тег dl: одна колонка на узком блоке
- Длинные слова в теге dl: minmax и overflow-wrap
- Прайс на теге dl: точки-заполнители между dt и dd
- Тег dl и float: почему dd уезжает от своего dt
- Оформление тега dl: двоеточие, линии и зебра
- Тег dl в JavaScript: собрать из данных и найти описание
- Атрибуты тега dl: только глобальные
- Вопросы про тег dl: dt и dd в одну строку и колонки без разрыва
- Частые ошибки с тегом dl
Тег dl в HTML: что это и из чего состоит список определений
Тег dl блочный: он занимает всю ширину и отделяется от соседей отступами 1em сверху и снизу (16px при шрифте 16px). Название dt выводится обычным шрифтом, а не жирным, как часто думают. Описание dd получает отступ слева 40px. Других стилей у этих трёх тегов нет, поэтому весь вид настраивается в CSS.
dl {
margin: 1em 0;
}
dd {
margin-inline-start: 40px;
}
Пример: пары в списке dl и стили по умолчанию
Выберите список: под результатом отступы и шрифт, которые браузер вычислил для этого списка.
Где можно записать тег dl и что допустимо внутри него
Сам dl записывают там, где допустим блок: в div, section, li, dd и прямо в теле страницы. Вложенный список определений записывают внутри dd, а не внутри самого dl. Внутри dl допустимы только dt, dd и обёртки div: текст, p и span валидатор считает ошибкой. Запись dl внутри абзаца p тоже неверна: браузер закрывает абзац перед списком, а лишний </p> создаёт пустой абзац.
<div>
<dl>
<dt>Цвет</dt>
<dd>Зелёный</dd>
</dl>
</div>
Пример: где допустим dl и что нельзя записать внутри
Выберите запись: вверху её код, под результатом написано, допустима ли она. Для dl в p показано дерево, которое построил браузер.
Группы dt и dd в теге dl: один к одному и один ко многим
Группа в dl состоит из одного или нескольких dt, за которыми идут один или несколько dd. Поэтому допустимы три схемы: один dt и один dd, несколько dt на одно dd (синонимы) и один dt с несколькими dd (несколько значений). Первым в группе всегда идёт dt, а dt без dd валидатор считает ошибкой. Одно название дважды в одном dl даёт предупреждение: значения лучше собрать под одним dt.
<dl>
<dt>Страна</dt>
<dd>Япония</dd>
<dd>Китай</dd>
</dl>
Пример: допустимые и неверные группы dt и dd
Выберите запись: вверху код, под результатом вывод валидатора. Для записи без закрывающих тегов показано дерево браузера.
Тег dl с div-обёрткой: одна группа - один div
Чтобы оформить группу целиком (линия, фон, рамка), её записывают в div. Стандарт разрешает такую обёртку, а смысл списка при этом не меняется. Правило одно: один div вмещает одну группу, то есть один или несколько dt и за ними один или несколько dd. Нельзя записывать две группы в один div, смешивать обёрнутые и необёрнутые группы, вкладывать div в div и оставлять в div один dt. Подробнее про блок div рассказывает страница про тег div.
<dl>
<div>
<dt>Цвет</dt>
<dd>Зелёный</dd>
</div>
<div>
<dt>Вес</dt>
<dd>100 г</dd>
</div>
</dl>
Пример: div вокруг группы и неверные обёртки
Выберите запись: пунктирная рамка показывает div, под результатом написано, допустима ли запись.
Что записать внутри dt и dd тега dl: p, ul, a и вложенный dl
В dd допустим любой поток: абзацы, списки, ссылки тега a, картинки, таблицы и вложенный dl. У вложенного dd те же 40px, поэтому отступы складываются. Обычно в dt записывают короткий строчный текст: strong, span, abbr. Заголовки, header, footer и секции внутри dt не допускаются.
<dl>
<dt>Чай</dt>
<dd>
<p>Бывает разный.</p>
<ul>
<li>Зелёный</li>
<li>Чёрный</li>
</ul>
</dd>
</dl>
Пример: что записать внутри dt и dd
Выберите запись: вверху код, под результатом вывод. У вложенного dl показаны отступы, которые измерил браузер.
Для чего нужен тег dl: характеристики, глоссарий, вопросы и ответы
Тег dl подходит там, где у каждого значения есть название: характеристики товара, глоссарий, контакты, рецепт с граммовками, вопросы и ответы. Это не только термины: стандарт прямо допускает метаданные и пары «вопрос и ответ». Если у пунктов названий нет, нужен обычный список ul, а если у каждой строки несколько значений в колонках, нужна таблица table.
<dl>
<dt>Можно ли вернуть товар?</dt>
<dd>Да, в течение 14 дней.</dd>
</dl>
Пример: что записать в dl, а что нет
Выберите задачу: вверху разметка, под результатом написано, подходит ли для неё dl.
Отступы тега dl по умолчанию: margin у dl и dd
Отступы задают три правила браузера: margin по 1em сверху и снизу у самого dl и margin-inline-start: 40px у dd. Свойство inline-start следует направлению письма: при dir="rtl" отступ у dd оказывается справа, а не слева. Чтобы убрать отступ слева, записывают margin: 0 у dd, а если нужен отступ без сдвига блока, добавляют padding-left.
dd {
margin: 0;
padding-left: 20px;
}
Пример: отступы dl и dd
Выберите правило: под результатом отступы, которые вычислил браузер.
Две колонки в теге dl через grid и ловушка с двумя dd
Две колонки собирают через display: grid у dl: каждый dt попадает в первую колонку, каждый dd — во вторую, а margin у dd нужно обнулить. Но сетка заполняется по порядку, поэтому при двух dd на один dt второй dd занимает первую колонку, а следующий dt сдвигается во вторую, и сбой идёт до конца списка. Исправляют явными колонками: dt в первую, dd во вторую. Обёртка div с display: contents действует так же, как её отсутствие, а div со своей сеткой удерживает сбой внутри группы, но второй dd всё равно попадает в первую колонку.
dl {
display: grid;
grid-template-columns: 120px 1fr;
}
dt {
grid-column: 1;
}
dd {
margin: 0;
grid-column: 2;
}
Пример: колонки dl и сбой с двумя dd
Выберите вариант: под результатом перечислены элементы, которые попали не в свою колонку. В списке у Страны два значения.
Адаптивный тег dl: одна колонка на узком блоке
На узком блоке две колонки сжимают значение до нескольких букв. Вместо @media, который смотрит на ширину окна, лучше правило @container: оно смотрит на ширину самого блока, поэтому список одинаково ведёт себя и в боковой колонке, и на всю страницу. Блоку-обёртке задают container-type: inline-size, а при узкой ширине сетку переводят в одну колонку.
.box {
container-type: inline-size;
}
@container (max-width: 300px) {
dl {
grid-template-columns: 1fr;
}
}
Пример: dl меняет колонки по ширине блока
Двигайте ползунок и переключайте правило: под результатом ширина блока, число колонок и ширина значения.
Длинные слова в теге dl: minmax и overflow-wrap
Длинное слово или хэш в dd растягивают колонку 1fr до своей ширины, и появляется горизонтальная прокрутка: минимальная ширина у 1fr равна самому длинному слову. Колонка minmax(0, 1fr) не растягивается, но слово выходит за её край, поэтому нужен ещё и перенос. Правило overflow-wrap: anywhere разрешает разорвать слово в любом месте и работает даже с 1fr, а overflow-wrap: break-word при 1fr не помогает: колонка уже растянута.
dd {
overflow-wrap: anywhere;
}
Пример: длинное слово в dd
Выберите правило: рядом с каждым написано, растянулась ли колонка и вышло ли слово за край.
Прайс на теге dl: точки-заполнители между dt и dd
Точки между названием и ценой делают флексом: каждую группу записывают в div с display: flex, а dt растягивают и делают флекс-контейнером, чтобы его псевдоэлемент ::after заполнил свободное место пунктирной линией. Цена в dd остаётся справа, а длинное название переносится на следующую строку.
div {
display: flex;
}
dt {
display: flex;
flex: 1;
}
dt::after {
content: '';
flex: 1;
border-bottom: 2px dotted;
margin: 0 6px;
}
Пример: прайс с точками-заполнителями
Выберите вариант: вверху правила, под результатом пояснение. Последнее название длинное, чтобы было видно перенос.
Тег dl и float: почему dd уезжает от своего dt
Раскладка через float ломается, когда название выше описания: dd следующей пары встаёт рядом с предыдущим dt, а не со своим. Даже с clear: left у dt сам dt уходит вниз под первый, а его dd остаётся наверху. Правило overflow: hidden у dd не помогает: следующее описание всё равно встаёт рядом с высоким плавающим dt. Помогает очистка внутри dd: псевдоэлемент ::after с clear: both растягивает dd на высоту названия. Проще взять grid, как в разделе про две колонки.
dt {
float: left;
clear: left;
width: 100px;
}
dd {
margin: 0 0 0 110px;
}
dd::after {
content: '';
display: block;
clear: both;
}
Пример: float у dt и очистка внутри dd
Выберите вариант: под результатом число пар, где описание стоит на одной строке со своим названием.
Оформление тега dl: двоеточие, линии и зебра
Двоеточие после названия добавляет dt::after, поэтому в разметке его писать не нужно. Линию между группами рисует селектор div + div, а зебру — div:nth-child(even): обоим нужна обёртка div. Без обёртки dt:nth-of-type(even) красит только названия, потому что считает одни dt и не трогает dd. Для второго и следующих значений одного названия подходит dd + dd.
dt::after {
content: ':';
}
div + div {
border-top: 1px solid #ccc;
}
div:nth-child(even) {
background: #FFF1EA;
}
Пример: двоеточие, линии и зебра
Выберите правило: вверху его код, под результатом написано, что выделилось.
Тег dl в JavaScript: собрать из данных и найти описание
Список определений собирают из массива пар: для каждой пары создают dt и dd и добавляют оба методом append. Текст записывают через textContent, чтобы символы < и & из данных не превратились в разметку.
dl.replaceChildren();
for (const [k, v] of data) {
const dt = document.createElement('dt');
dt.textContent = k;
const dd = document.createElement('dd');
dd.textContent = v;
dl.append(dt, dd);
}
Пример: собрать dl из массива пар
Нажимайте кнопки: вверху выполненная команда, под списком число пар в данных и тегов в dl.
Чтобы найти описание названия, берут dt.nextElementSibling, а для нескольких описаний идут по соседям, пока встречаются dd. С обёртками div соседи dt и dd остаются теми же, но dl.children возвращает группы, а не отдельные теги: названия считают через dl.querySelectorAll('dt').
const dt = document.querySelector('#t');
const list = [];
let n = dt.nextElementSibling;
while (n && n.tagName === 'DD') {
list.push(n.textContent);
n = n.nextElementSibling;
}
Пример: найти все описания названия
Выберите команду: вверху код, под списком результат, который скрипт посчитал в этом кадре.
Атрибуты тега dl: только глобальные
У dl нет собственных атрибутов: работают только глобальные, например class, id, lang, dir и title. Устаревший атрибут валидатор отмечает предупреждением, а на вид списка он не влияет. Атрибуты compacttype и nowrap у dl, dt и dd недопустимы. Роли term и definition лишние: у dt и dd такая роль уже есть. Список глобальных атрибутов приведён в стандарте WHATWG.
| Атрибут | Статус | Что делает | Пример записи |
|---|---|---|---|
class, id, style, lang, dir, title | актуален | Глобальные атрибуты: работают у dl, dt и dd. Например, dir="rtl" переносит отступ у dd вправо | <dl class="specs"> |
compact | устарел | Когда-то просил сжать список. Сейчас на вид не влияет, валидатор выдаёт предупреждение | <dl compact> |
role="term", role="definition" | лишний | У dt и dd такая роль задана самим тегом, валидатор выдаёт предупреждение | <dt role="term"> |
type, nowrap | недопустим | Для dl, dt и dd такие атрибуты не определены, валидатор считает их ошибкой | <dl type="1"> |
Вопросы про тег dl: dt и dd в одну строку и колонки без разрыва
Два вопроса, которых нет в разделах выше: как вывести dt и dd в одну строку и как не разорвать пару в колонках.
Как вывести dt и dd в одну строку без grid?
Для этого dt и dd делают display: inline. У dd при этом остаётся горизонтальный margin-left: 40px, поэтому его обнуляют, а между парами добавляют перенос через dd::after с content: '\A' и white-space: pre. Двоеточие после названия добавляет dt::after.
dt,
dd {
display: inline;
margin: 0;
}
dt::after {
content: ': ';
}
dd::after {
content: '\A';
white-space: pre;
}
Пример: название и значение в одну строку
Выберите вариант: под результатом расстояние между dt и dd и число строк.
Как не разорвать пару dt и dd в колонках?
При columns браузер может оставить dt внизу одной колонки, а dd перенести в следующую. Это исправляет break-after: avoid у dt или обёртка div с break-inside: avoid.
dl {
columns: 2;
}
dt {
break-after: avoid;
}
Пример: dl в две колонки без разрыва пары
Выберите правило: под результатом написано, осталась ли пара целиком в одной колонке. Высота списка ограничена, чтобы колонки заполнялись по порядку.
Частые ошибки с тегом dl
Типичные ошибки с тегом dl и как их исправить.
| Ошибка | Что происходит | Как исправить |
|---|---|---|
dt без dd | Ошибка валидатора: у группы нет описания | Записать dd или убрать dt |
dd раньше dt | Ошибка валидатора: группа начинается с dt | Поменять порядок: сначала название |
p, span или текст прямо в dl | Ошибка валидатора: допустимы только dt, dd и div | Записать содержимое внутри dd |
Две группы в одном div | Ошибка валидатора: div вмещает одну группу | Один div на каждую группу |
Часть групп в div, часть без него | Ошибка валидатора: нельзя смешивать | Обернуть все группы или ни одной |
h3 внутри dt | Ошибка валидатора: заголовок в dt запрещён | Записать название текстом или в strong |
dl внутри p | Браузер закрывает абзац, остаётся пустой p | Записать dl рядом с абзацем |
dl прямо в ul или внутри dl | Ошибка валидатора | Записать внутри li или внутри dd |
Пары «название и значение» через div и b | Название и значение ничем не связаны | Записать их как dt и dd |
Grid с двумя dd без grid-column | Второй dd в колонке названий, следующий dt сдвинулся | Задать dt первую колонку, dd вторую |
Колонка 1fr и длинное слово в dd | Колонка растянулась, появилась горизонтальная прокрутка | Колонка minmax(0, 1fr) и overflow-wrap: anywhere |
float у dt при высоком названии | dd встаёт рядом с чужим dt | Использовать grid или очистку в dd::after |
dt:nth-of-type(even) для зебры | Закрашены только названия | Обернуть группы в div и взять div:nth-child(even) |
role="term" у dt | Предупреждение валидатора: роль лишняя | Убрать role |