CSS Counters

CSS Counters — механизм автоматической нумерации элементов с помощью свойств counter-reset, counter-increment и функции counter в content.

Зачем нужно

CSS Counters позволяют нумеровать заголовки, шаги, пункты списка и другие повторяющиеся элементы без JavaScript и без ручного проставления номеров в HTML. Это удобно для документации, пошаговых инструкций, кастомных нумерованных списков с особым форматированием.

Где используется

  • Автонумерация заголовков в документации
  • Нумерованные шаги туториала
  • Кастомные ol-списки с нестандартным стилем
  • Счётчик элементов формы
  • Нумерация строк в таблицах

Основной контент

Основные свойства

/* counter-reset — объявить и обнулить счётчик */
/* counter-increment — увеличить счётчик */
/* counter — получить текущее значение */

ol {
  counter-reset: item; /* объявить счётчик "item", начать с 0 */
  list-style: none;
  padding: 0;
}

ol li {
  counter-increment: item; /* увеличить на 1 при каждом li */
}

ol li::before {
  content: counter(item) '. '; /* вставить значение */
}

Кастомный нумерованный список

.steps {
  counter-reset: steps;
  list-style: none;
  padding: 0;
}

.steps li {
  counter-increment: steps;
  display: flex;
  align-items: flex-start;
  gap: 16px;
  margin-bottom: 24px;
}

.steps li::before {
  content: counter(steps);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  background: #0070f3;
  color: white;
  border-radius: 50%;
  font-weight: bold;
  flex-shrink: 0;
}

Вложенные счётчики

/* Нумерация 1. 1.1. 1.2. 2. 2.1. */
article {
  counter-reset: section;
}

h2 {
  counter-reset: subsection;
  counter-increment: section;
}

h2::before {
  content: counter(section) '. ';
}

h3 {
  counter-increment: subsection;
}

h3::before {
  content: counter(section) '.' counter(subsection) '. ';
}

Начальное значение и шаг

ol {
  counter-reset: item 0;    /* начать с 0 (по умолчанию) */
  counter-reset: item 9;    /* начать с 9 */
}

li {
  counter-increment: item 2; /* шаг 2: 2, 4, 6... */
  counter-increment: item -1; /* обратный счёт */
}

Форматирование значения

li::before {
  content: counter(item, decimal);       /* 1, 2, 3 */
  content: counter(item, lower-alpha);   /* a, b, c */
  content: counter(item, upper-roman);   /* I, II, III */
  content: '(' counter(item) ')';        /* (1), (2), (3) */
  content: 'Шаг ' counter(item) ':';    /* Шаг 1: */
}

Частые ошибки

  • counter-reset на неправильном родителе — счётчик должен быть объявлен на предке элементов, которые его инкрементируют
  • content без ::before/::aftercounter работает только в свойстве content, только на псевдоэлементах
  • Счётчик не сбрасывается между списками — нужен counter-reset на каждом новом списке отдельно

Связанные темы

Ресурсы