Чтобы отображать полные пути разделов, например 1.2.1, вкладывайте упорядоченные списки и используйте CSS-функцию counters(), чтобы объединить их уровни. В этом руководстве создаётся локальный HTML-файл на Mac, сохраняется порядок структуры и показывается, как проверять нумерацию после правок.
Как работает нумерация полных путей?
Полный путь раздела указывает положение элемента на каждом уровне. Например, 1.2.1 означает первый элемент во втором дочернем элементе первого элемента верхнего уровня. В CSS есть специальная функция counters() для объединения значений вложенных счётчиков: она считывает их от самого внешнего к самому внутреннему и вставляет выбранный вами разделитель. MDN: функция counters() в CSS
Для этой задачи структура представляет собой упорядоченный список с вложенными ветвями. Это не автоматически сгенерированное оглавление для заголовков в других частях документа. Согласно HTML, элементы упорядоченного списка расположены в порядке дерева, поэтому исходный порядок должен соответствовать предполагаемому порядку чтения. Стандарт HTML: элемент ol
В примере используются три правила: создать счётчик для каждого участвующего списка, увеличивать его для каждого элемента и отображать объединённый путь перед меткой элемента. Это соответствует описанному MDN шаблону вложенных счётчиков, а селекторы ограничены этой структурой. MDN: Использование счётчиков CSS
Создайте файл структуры на Mac
Вам понадобятся TextEdit и браузер, например Safari. Полный пример содержит собственную таблицу стилей и условное демонстрационное содержимое; пакеты, инструменты сборки и JavaScript не требуются.
- Откройте TextEdit и выберите
File > New. - Выберите
Format > Make Plain Text. - Вставьте полный пример ниже.
- Выберите
File > Save, назовите файлoutline.htmlи сохраните его в удобном месте, например на рабочем столе. - Если TextEdit спросит, какое расширение использовать, выберите
Use .html.
Apple описывает этот процесс создания HTML-файлов в TextEdit в режиме обычного текста. Apple: Работа с HTML-документами в TextEdit на Mac
Ниже приведён полный документ. Скопируйте содержимое блока кода, не включая строки с маркерами Markdown.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Nested outline example</title>
<style>
body {
max-width: 48rem;
margin: 2rem auto;
padding: 0 1rem;
font-family: system-ui, sans-serif;
line-height: 1.6;
}
.outline,
.outline ol {
counter-reset: outline-section;
list-style-type: none;
padding-inline-start: 1.5rem;
}
.outline li {
counter-increment: outline-section;
margin-block: 0.35rem;
}
.outline li::before {
content: counters(outline-section, ".") " ";
font-weight: 600;
}
</style>
</head>
<body>
<h1>Sample document outline</h1>
<ol class="outline" role="list">
<li>Node A
<ol role="list">
<li>Node B</li>
<li>Node C
<ol role="list">
<li>Node D</li>
<li>Node E</li>
</ol>
</li>
<li>Node F</li>
</ol>
</li>
<li>Node G
<ol role="list">
<li>Node H</li>
</ol>
</li>
<li>Node I</li>
</ol>
</body>
</html>
Откройте Safari, затем перетащите outline.html из Finder в окно Safari. Редактируйте исходный код в TextEdit, а в Safari проверяйте отображение структуры. После каждой правки сохраняйте файл и обновляйте страницу браузера.
Оставьте TextEdit в режиме редактирования кода
При повторном открытии файла вместо исходного кода может отображаться форматированный документ. Apple описывает два варианта: выберите File > Open, нажмите Show Options и установите флажок Ignore rich text commands; либо включите параметр Display HTML files as HTML code instead of formatted text в меню TextEdit > Settings > Open and Save. Apple: Работа с HTML-документами в TextEdit на Mac
Сверьте полные пути с примером
Ниже показана ожидаемая структура. Метки условные; номера определяются расположением элементов.
1 Node A
1.1 Node B
1.2 Node C
1.2.1 Node D
1.2.2 Node E
1.3 Node F
2 Node G
2.1 Node H
3 Node I
Этот пример проверяет три разных перехода. Node D начинает третий уровень внутри Node C. Node F продолжает второй уровень после завершения этой ветви. Node G продолжает верхний уровень, а его первый дочерний элемент начинается с 2.1. Детерминированный обход дерева примера подтвердил ожидаемые пути; при подготовке пример не проверялся в браузере.
Зачем нужно каждое правило CSS
Сброс применяется к .outline и .outline ol. Для каждого вложенного списка нужен новый экземпляр outline-section; сброс только внешнего списка не создаст отдельный счётчик для каждого уровня. Увеличение счётчика для каждого элемента списка продвигает значение текущего экземпляра. MDN: Использование счётчиков CSS
Правило отображения использует counters(outline-section, "."). Эта функция во множественном числе собирает все активные экземпляры с таким именем. Если заменить её на функцию в единственном числе counter(outline-section), будет отображаться только значение текущего уровня, и вложенный элемент получит метку 1 вместо полного пути. MDN: функция counters() в CSS
В примере убраны стандартные маркеры списка, поскольку используются собственные префиксы. У каждого списка также есть role="list": MDN отмечает, что иначе Safari может не включать списки со стилем list-style-type: none в дерево доступности. Сохраняйте этот атрибут при добавлении вложенных списков. MDN: свойство CSS list-style-type
Редактируйте структуру, не нарушая её
Размещайте каждый вложенный <ol> внутри <li>, которому принадлежит ветвь. Например, дочерний список Node C находится перед закрывающим тегом </li> этого элемента. Вложенный список не должен быть непосредственным дочерним элементом другого упорядоченного списка. MDN: элемент HTML для упорядоченного списка
Для практической проверки вставьте новый элемент непосредственно перед Node C. Его новый путь должен быть 1.2; путь Node C должен стать 1.3; а пути Node D и Node E должны стать 1.3.1 и 1.3.2. Путь Node G должен остаться 2. Эти ожидаемые изменения следуют из иерархии примера и помогают проверить, что нумерация соответствует структуре ветвей.
Чтобы переместить ветвь, переместите весь элемент списка, которому она принадлежит, включая вложенные списки и закрывающий тег. Если переместить только метку, дочерние элементы останутся на месте. Чтобы создать четвёртый уровень, повторите существующую структуру вложенного списка внутри нужного элемента; не вписывайте дополнительный номер в метку.
Если дочерние элементы должны образовывать одну непрерывную последовательность, оставьте в ветви один дочерний список. В этой реализации создание ещё одного соседнего дочернего списка приводит к новому сбросу, поэтому локальная нумерация начинается заново. В примере MDN такой перезапуск показан на отдельных вложенных списках внутри одного элемента. MDN: Использование счётчиков CSS
Диагностируйте ошибки нумерации в удобном порядке
Сначала проверьте структуру, затем правила счётчиков и после этого оформление. Изменение отступов не исправит отсутствующий уровень вложенности.
| Что вы видите | Что проверить | Исправление для этого примера |
|---|---|---|
| У каждого вложенного элемента отображается одно число | Функцию в content |
Используйте counters() во множественном числе с точкой в качестве разделителя. |
Нумерация каждого элемента на одном уровне начинается с 1 |
Селектор сброса | Сбрасывайте счётчик для списков, а не для каждого элемента. |
| Рядом с полными путями отображаются стандартные номера | Правило стиля списка | Примените list-style-type: none к внешнему и вложенным спискам. |
| У ветви неожиданный префикс | Расположение вложенного списка | Оставьте дочерний список внутри элемента, которому он принадлежит. |
| У другого списка появились префиксы | Область действия селектора счётчика | Сохраняйте префикс .outline в правилах. |
Также проверьте, не скрыт ли элемент. Операции со счётчиками CSS не выполняются для элементов, которые не генерируют блок, включая элементы с display: none. Напротив, visibility: hidden по-прежнему создаёт блок, поэтому такой элемент может влиять на подсчёт. Осознанно решите, должен ли пропущенный элемент занимать позицию. W3C: Счётчики в элементах, не создающих блоки
Что делать с пользовательскими начальными номерами?
В этом примере намеренно используется пользовательский счётчик, который начинается с нуля и увеличивается до единицы. Атрибуты HTML, такие как start, reversed и value элемента списка, управляют стандартной нумерацией упорядоченного списка; показанные здесь пользовательские правила outline-section эти атрибуты не считывают. Поэтому одно лишь добавление start="4" не заставит отображаемый префикс в этом примере начинаться с 4. Стандарт HTML: упорядоченные списки и элементы списка
Если вам нужна прерывистая нумерация или обратный отсчёт во вложенных ветвях, определитесь с этим требованием до адаптации таблицы стилей. Сохраняйте соответствие отображаемых путей предполагаемым значениям упорядоченного списка, а не добавляйте атрибуты, которые игнорируются пользовательским отображением.
Решите, являются ли номера оформлением или содержимым документа
Префиксы в этом руководстве генерируются с помощью CSS. Они подходят для визуальной структуры, однако важные ссылки требуют дополнительного внимания: MDN отмечает, что содержимое, добавленное через ::before, ненадёжно доступно программам чтения с экрана. Добавление role="list" сохраняет распознавание списка, но не гарантирует озвучивание каждого сгенерированного пути. MDN: псевдоэлемент CSS ::before
Если полный путь должен быть частью самого текста, например при экспорте в виде обычного текста, включите его в документ как текст или сгенерируйте на этапе экспорта. Это меняет требования к обслуживанию: при правках нужно будет обновлять и сохранённые пути. Не полагайтесь на визуальный префикс как на источник важного текста во всех форматах вывода.
Для локальной визуальной структуры проверьте все девять путей примера, вставьте элемент на том же уровне и убедитесь, что нумерация затронутой ветви изменилась ожидаемым образом. Когда эти проверки пройдут в браузере, замените условные метки, сохранив вложенность и исходный порядок.
Источники
- Работа с HTML-документами в TextEdit на Mac — Apple.
- Стандарт HTML: группировка содержимого — WHATWG.
- Использование счётчиков CSS — MDN Web Docs.
- Функция counters() в CSS — MDN Web Docs.
- Элемент HTML для упорядоченного списка — MDN Web Docs.
- Свойство CSS list-style-type — MDN Web Docs.
- Псевдоэлемент CSS ::before — MDN Web Docs.
- Модуль CSS Lists and Counters, уровень 3 — W3C.