Задача «застилизовать только первые три пункта списка» решается на чистом CSS одним селектором – без дополнительных классов и JavaScript. Ключ к этому – псевдокласс :nth-child() с отрицательным коэффициентом. Разберём, почему формула работает именно так, и что нового появилось к 2026 году.
Формула :nth-child(-n+3)
Селектор li:nth-child(-n+3) выбирает первые три пункта списка. Псевдокласс :nth-child() принимает выражение вида an+b, где n последовательно принимает значения 0, 1, 2, 3 и так далее, а браузер оставляет только те позиции, которые получаются в результате.
Подставим значения в -n+3:
n=0→ позиция 3;n=1→ позиция 2;n=2→ позиция 1;n=3→ 0 – позиции 0 не существует, дальше все значения отрицательные и игнорируются.
Итог – позиции 1, 2 и 3, то есть первые три элемента. Здесь -n означает коэффициент a = -1, а +3 задаёт границу отсчёта.
/* Первые три пункта списка */
li:nth-child(-n+3) {
font-weight: 700;
}
Выбрать последние три: :nth-last-child
Зеркальная задача решается псевдоклассом :nth-last-child(), который считает элементы с конца:
/* Последние три пункта списка */
li:nth-last-child(-n+3) {
opacity: .6;
}
Диапазоны и «каждый n-й»
Формула гибкая. Например, li:nth-child(-3n+12) выберет каждый третий пункт в пределах первых двенадцати – позиции 3, 6, 9 и 12. А чтобы выбрать элементы с 4-го по 8-й, комбинируют два условия:
/* С 4-го по 8-й элемент включительно */
li:nth-child(n+4):nth-child(-n+8) {
background: #f5f5f5;
}
Синтаксис of S (2026)
Selectors Level 4 добавил в :nth-child() необязательную часть of S – фильтр по селектору. Браузер сначала отбирает элементы, подходящие под S, и только среди них считает позиции:
/* Первые три товара В НАЛИЧИИ, даже если между ними есть скрытые */
li:nth-child(-n+3 of .in-stock) {
border: 2px solid #0a0;
}
Это принципиально отличается от li.in-stock:nth-child(-n+3), который проверяет позицию среди всех детей, а затем отбрасывает те, у кого нет класса. Про фильтрацию по :not() внутри такого выражения – в гайде «Фильтрация элементов с помощью псевдокласса :not()».
Отличие :nth-child от :nth-of-type
:nth-child() считает все дочерние элементы родителя подряд, независимо от их тега. :nth-of-type() считает только элементы того же типа. Если внутри контейнера вперемешку лежат <h3> и <p>, эти два псевдокласса дадут разный результат – частая причина «почему стиль применился не к тому элементу».
Частые ошибки
- Путаница со счётом. Нумерация в
:nth-child()начинается с 1, а не с 0. - Неверный родитель. Псевдокласс смотрит позицию среди siblings конкретного родителя, а не среди всех совпавших по селектору элементов на странице.
- Ожидание фильтрации без of S.
li.item:nth-child(-n+3)– это не «первые три с классом item», а «первые три ребёнка, если они с классом item».
Поддержка браузеров
Базовые :nth-child() и :nth-last-child() поддерживаются во всех браузерах уже много лет. Синтаксис of S новее и доступен в актуальных версиях Chrome, Edge, Firefox и Safari – перед использованием в продакшене сверяйтесь с caniuse.com или заложите запасной вариант через классы. Похожие приёмы отсчёта пригодятся в шаблоне постраничной навигации и при выводе количества элементов в разделе.