Счётчики CSS
Список <ol> нумерует пункты сам. Но иногда номера нужны там, где списка нет: у заголовков статьи, у шагов инструкции, у рисунков. Для этого в CSS есть счётчики — именованные переменные-числа, которые браузер увеличивает по мере обхода страницы.
Три шага
Работа со счётчиком всегда состоит из трёх частей: создать его, увеличивать и вывести. counter-reset создаёт счётчик со значением 0, counter-increment прибавляет единицу, а функция counter() в свойстве content псевдоэлемента показывает текущее значение:
<style>
.steps { counter-reset: step; }
.steps p { counter-increment: step; }
.steps p::before { content: "Шаг " counter(step) ": "; font-weight: bold; }
</style>
<div class="steps">
<p>Смелите кофе.</p>
<p>Нагрейте воду.</p>
<p>Залейте и подождите четыре минуты.</p>
</div>Номеров в разметке нет — их дописал CSS. Добавьте ещё один абзац, и нумерация продолжится сама.
Свойства и функции
| Запись | Что делает |
|---|---|
counter-reset: step | создаёт счётчик step, равный 0 |
counter-reset: step 10 | создаёт счётчик со значением 10 |
counter-increment: step | прибавляет 1 |
counter-increment: step 5 | прибавляет 5 (можно и отрицательное) |
counter(step) | выводит значение |
counter(step, upper-roman) | выводит в другом стиле: I, II, III |
Вторым аргументом counter() принимает те же стили, что и list-style-type: lower-alpha, upper-roman, decimal-leading-zero.
Нумерованные заголовки
Счётчиков может быть несколько. Типичный пример — разделы и подразделы документа: при каждом новом h2 счётчик подразделов начинается заново:
<style>
article { counter-reset: section; }
h2 { counter-increment: section; counter-reset: sub; font-size: 20px; }
h3 { counter-increment: sub; font-size: 16px; }
h2::before { content: counter(section) ". "; }
h3::before { content: counter(section) "." counter(sub) " "; }
</style>
<article>
<h2>Установка</h2>
<h3>Требования</h3>
<h3>Загрузка</h3>
<h2>Настройка</h2>
<h3>Первый запуск</h3>
</article>У второго раздела подразделы снова начались с 2.1: counter-reset: sub у h2 обнулил счётчик.
Вложенная нумерация: counters()
Для списков любой глубины есть функция counters() с буквой s на конце. Каждый вложенный <ol> создаёт новую копию счётчика, а counters() выводит все копии от внешней к внутренней через указанный разделитель:
<style>
ol { counter-reset: item; list-style: none; padding-left: 20px; }
li { counter-increment: item; }
li::before { content: counters(item, ".") ". "; color: steelblue; }
</style>
<ol>
<li>Введение</li>
<li>Основы
<ol>
<li>Теги</li>
<li>Атрибуты
<ol>
<li>Глобальные</li>
</ol>
</li>
</ol>
</li>
<li>Итоги</li>
</ol>list-style: none убрал стандартные номера, чтобы они не дублировались.
Свой стиль: @counter-style
Правило @counter-style описывает собственную систему нумерации. Например, system: cyclic перебирает символы по кругу:
<style>
@counter-style stars {
system: cyclic;
symbols: "★" "☆";
suffix: " ";
}
ul { list-style: stars; }
</style>
<ul>
<li>Капучино</li>
<li>Латте</li>
<li>Раф</li>
</ul>Готовый стиль используют в list-style и во втором аргументе counter(). Правило поддерживается во всех основных браузерах.
Частая ошибка
counter-reset на том же элементе, который увеличивает счётчик. Каждый абзац заново создаёт счётчик с нуля и тут же прибавляет единицу — у всех получается 1:
<style>
.bad p { counter-reset: n; counter-increment: n; }
.good { counter-reset: n; }
.good p { counter-increment: n; }
p::before { content: counter(n) ". "; }
</style>
<div class="bad"><p>Первый</p><p>Второй</p></div>
<div class="good"><p>Первый</p><p>Второй</p></div>Создавайте счётчик у общего родителя, а увеличивайте — у элементов внутри.