← На главную

HTML5 элементы списков управляют разметкой и стилями интерфейсов

16.05.2026 16:58 · hackernews

Размещённые ниже HTML-разметка и пояснения иллюстрируют семантически правильные списки в HTML5, включая списки со счётчиком, неупорядоченные списки, описательные списки и меню.

Приспособления (альфавитный порядок) - сода (1 чайная ложка) - бананы (2) (измельчённый) - коричневый сахар (¾ чашки) - масло (½ чашки) - яйца (2) - мука (2 чашки) - соль (¼ чайной ложки)

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

<ol>
  <li>Подготовка:
    <ul>
      <li>Разогрейте духовку до 350 градусов</li>
      <li>Легко обильно смазанный 9x5 форма</li>
      <li>Соберите все ингредиенты</li>
    </ul>
  </li>
  <li>Смешать:
    <ol>
      <li>Подготовка миски 1: Смешайте муку, соду и соль в большой миске</li>
      <li>Подготовка миски 2: 
         <ol>
            <li>Бейте коричневый сахар и масло</li>
            <li>Вмешивайте яйца и пюре из бананов</li>
         </ol>
      </li>
      <li>Вмешать миску 2 в миску 1</li>
    </ol>
 </li>
  <li>Налив: Баттер идёт в предварительно смазанную форму</li>
  <li>Выпекать:
    <ul>
      <li>Выпекать 60 минут&hellip;</li>
      <li>Или, когда деревянная шпажка, вставленная в центр, выходит чистой</li>
    </ul>
  </li>
  <li>Охлаждать:
    <ol>
      <li>Позвольте остыть в форме на 10 минут</li>
      <li>Разместите на проволочной стойке для завершения охлаждения</li>
    </ol>
  </li>
</ol>

Подготовка: - Разогрейте духовку до 350 градусов - Легко обильно смазанный 9x5 форма - Соберите все ингредиенты

Смешать: - Подготовка миски 1: Смешайте муку, соду и соль в большой миске - Подготовка миски 2: - Бейте коричневый сахар и масло - Вмешивайте яйца и пюре из бананов - Вмешать миску 2 в миску 1

Наливать: Баттер идёт в предварительно смазанную форму

Выпекать: - Выпекать 60 минут… - Или, когда деревянная шпажка, вставленная в центр, выходит чистой

Охлаждать: - Позвольте остыть в форме на 10 минут - Разместите на проволочной стойке для завершения охлаждения

Атрибуты, которые следует учитывать Существует причина, по которой я действительно упорствовал на том, чтобы подчеркнуть, что упорядоченный список предназначен для всего, что имеет предписанную последовательность. И потому что есть два атрибута специально для <ol>: - reversed - start

Обратный Атрибут reversed меняет нумерацию последовательности от возрастающего к убывающему. Но это не меняет порядок списка. Это полезно, если вы показываете что-то от «самое к наименьшему», например, ингредиенты и количество:

<h3>Ингредиенты (от большего к меньшему)</h3>
<ol reversed>
  <li>яйца (2)</li>
  <li>мука (2 чашки)</li>
  <li>бананы (2) (измельчённый)</li>
  <li>коричневый сахар (¾ чашки)</li>
  <li>масло (½ чашки)</li>
  <li>сода (1 чайная ложка)</li>
  <li>соль (¼ чайной ложки)</li>
</ol>

Ингредиенты (от большего к меньшему) - яйца (2) - мука (2 чашки) - бананы (2) (измельчённый) - коричневый сахар (¾ чашки) - масло (½ чашки) - сода (1 чайная ложка) - соль (¼ чайной ложки)

Теперь мы можем добавить немного JavaScript, чтобы сделать этот список действительно обратимым:

function reverseList(list) {
  const children = [...list.querySelectorAll('li')].reverse();
  list.innerHTML = '';
  list.append(...children);
  list.toggleAttribute('reversed');
}

orderedList.addEventListener('dblclick', (evt) => { reverseList(orderedList) })

Начинает Устанавливает точку начала. Что, если наш хлеб с бананом был бы серией упорядоченных списков, вместо одного мега-списка? Атрибут start предназначен помочь, позволяя нам указать список, где начать нумерацию. Это полезный инструмент для установления непрерывности между нашими списками.

<h2>1: Подготовить</h2>
<ul>
  <li>Разогрейте духовку до 350 градусов</li>
  <li>Легко обильно смазанный 9x5 форма</li>
  <li>Соберите все ингредиенты</li>
</ul>
<h2>Смешать</h2>
<ol start=2>
  <li>Подготовка миски 1: Смешайте муку, соду и соль в большой миске</li>
  <li>Подготовка миски 2: 
    <ol>
      <li>Бейте коричневый сахар и масло</li>
      <li>Вмешивайте яйца и пюре из бананов</li>
   </ol>
  </li>
  <li>Вмешать миску 2 в миску 1</li>
</ol>
<h2>Наливать</h2>
<ol start=5>
  <li>Баттер идёт в предварительно смазанную форму</li>
</ol>
<h2>6: Выпекать</h2>
<ul>
  <li>Выпекать 60 минут…</li>
  <li>Или, когда деревянная шпажка, вставленная в центр, выходит чистой</li>
</ul>
<h2>Охлаждать</h2>
<ol start=7>
  <li>Позвольте остыть в форме на 10 минут</li>
  <li>Разместите на проволочной стойке для завершения охлаждения</li>
</ol>

1: Подготовить - Разогрейте духовку до 350 градусов - Легко обильно смазанный 9x5 форма - Соберите все ингредиенты

Смешать - Подготовка миски 1: Смешайте муку, соду и соль в большой миске - Подготовка миски 2: - Бейте коричневый сахар и масло - Вмешивайте яйца и пюре из бананов - Вмешать миску 2 в миску 1

Наливать - Баттер идёт в предварительно смазанную форму

6: Выпекать - Выпекать 60 минут… - Или, когда деревянная шпажка, вставленная в центр, выходит чистой

Охлаждать - Позвольте остыть в форме на 10 минут - Разместите на проволочной стойке для завершения охлаждения

Мне нравится называть описательный список «забытым списком», потому что… ну, он забыт. Мы проводим много времени, пытаясь вписать всё в упорядоченный или неупорядоченный список, и весь этот время описательные списки висели в углу.

Когда это был список определений В HTML 4 это называлось список определений вместо описательного списка; его назначение было немного более узким, так как он предназначался только для предоставления определений. Список определений содержал <dt>, которое было определением термин, а затем <dd>, которое было определением определение.

Таким образом, классическое использование в прошлом могло выглядеть так. Обратите внимание, что истинная семантическая точность означает, что мы обёртываем термины, которые определяются, в <dfn>:

<dl>
  <dt><dfn>выброс</dfn></dt>
  <dt><dfn>yeet</dfn></dt>
  <dd>Глагол. Выбросить с высокой скоростью</dd>
  <dt><dfn>no cap</dfn></dt>
  <dd>Междометие. Выражает аутентичность и правдивость, иногда удивление.</dd>
  <dt><dfn>bet</dfn></dt>
  <dd>Междометие. Выражает согласие и утверждение.</dd>
</dl>

выброс yeet Глагол. Выбросить с высокой скоростью no cap Междометие. Выражает аутентичность и правдивость, иногда удивление. bet Междометие. Выражает согласие и утверждение.

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

Не только это, в HTML5 они поняли, что было бы неприятно, если бы спецификация не позволяла нам группировать термины и определения вместе. Поэтому теперь <div> разрешен как не семантическая оболочка, чтобы помочь нам сгруппировать эти термины и определения:

<dl>
 <div class="dl-item">
   <dt>Chrome</dt>
   <dt>Opera</dt>
   <dt>Brave</dt>
   <dt>Edge</dt>
   <dd>Браузеры на базе Blink</dd>
 </div>
 <div class="dl-item">
   <dt>Firefox</dt>
   <dt>Tor</dt>
   <dt>Librewolf</dt>
   <dd>Браузеры на базе Gecko</dd>
 </div>
</dl>

Chrome Opera Brave Edge Браузеры на базе Blink Firefox Tor Librewolf Браузеры на базе Gecko

Используйте <dl> для метаданных Мы должны использовать описательный список для отображения любого вида метаданных. Если это ряд фактов и меток, это описательный список! Профиль пользователя должен быть в <dl>. И если нам не нравится отступаемая природа, мы можем исправить это с помощью нескольких строк CSS:

<dl>
 <dt>Имя</dt>
 <dd>Фрэнк</dd>

 <dt>Фамилия</dt>
 <dd>Тейлор</dd>

 <dt>Возраст</dt>
 <dd>44</dd>

 <dt>Работа</dt>
 <dd>Писатель</dd>

 <dt>Управление</dt>
 <dd>Paceaux</dd>
</dl>
dl {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  width: 10em;
}

dt, dd {
  flex-grow: 1;
  flex-basis: 40%;
}

Имя Фрэнк Фамилия Тейлор Возраст 44 Работа Писатель Управление Paceaux

Используйте <dl> для отображения или отладки JSON Лично я считаю, что одним из лучших применений описательного списка является отладка. Если я хочу отладить кусок JSON в одностраничном приложении, я делаю это с помощью <dl>. Я часто помещаю шаблон debug.vue в свои одностраничные приложения для показа мне объекта JSON, и, конечно же, он использует <dl>. Но это действительно не так много кода, чтобы иметь небольшую утилиту, которая рендерит ваши (не самые любимые) объекты с описательным списком:

class DebugJson {
    constructor(json, containerSelector) {
        this.json = json;
        this.containerSelector = containerSelector;
    }

    get containerEl () {
        return document.querySelector(this.containerSelector)
    }

    static createDt(text) {
        const dtEl = document.createElement('dt');
        dtEl.innerHTML = `<var>${text}</var>`;

        return dtEl;
    }

    static createDd(value) {
        const ddEl = document.createElement('dd');

        if (typeof value === 'object' && !Array.isArray(value)) {
            ddEl.append(DebugJson.createDl(value))
        } else {
            ddEl.innerHTML = `<code>${value.toString()}</code>`;
        }
        return ddEl;
    }

    static createDl(obj) {
        const dl = document.createElement('dl');

        Object.entries(obj).forEach(([key,value]) => {
            const dtEl = DebugJson.createDt(key);
            const ddEl = DebugJson.createDd(value);
            dl.append(dtEl);
            dl.append(ddEl);
        });

        return dl;
    }

    render(json = this.json) {
        this.containerEl.append(DebugJson.createDl(json));      
    }
}

const debugJson = new DebugJson({foo: 'bar', arr: ['a', 'b'], car: 1}, '.container')
debugJson.render();

Мы должны использовать больше описательных списков, ребята.

Этот элемент больше предназначен для интерактивной стороны веб-страниц, чем для рендеринга контента. menu конкретно это список команд; это существует как ещё один повод не использовать <ul>. Если у нас был редактор с богатым текстом, у которого были некоторые элементы управления для изменения текста, это должно было бы находиться в menu:

<menu>
  <li><button onclick="strong()">Жирный</button></li>
  <li><button onclick="emphasize()">Выделение</button></li>
  <li><button onclick="strike()">Зачеркнуть</button></li>
</menu>

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

<div class="player player--video">
  <video source="whatever.mp4" id="vid-123"></video>
  <menu>
    <li><button commandfor="vid-123" command="--play">Играть</button></li>
    <li><button commandfor="vid-123" command="--mute">Затемнить</button></li>
    <li><button commandfor="vid-123" command="--fullscreen">Полноэкранный</button></li>
  </menu> 
</div>

Использование menu означает, что вам не нужно добавлять aria-role="menu" к неупорядоченному списку.

Мы не должны предположать, что наш CSS, что <li> будет находиться только в двух контейнерах. Если мы не хотим, чтобы элементы списка выглядели как элементы списка в наших навигациях, мы не хотим этого для наших menu, тоже. Вы, вероятно, хотите что-то вроде этого в верхней части вашего стиля:

nav li,
menu li {
    list-style-type: none;
    text-indent: 0;
    margin: 0;
}

Довольно сбивающе с толку, элемент <nav> и <menu> похожи, но не являются синонимами.

Читать оригинал →