Псевдокласс :nth-last-child() входит в группу структурных псевдоклассов CSS вместе с :nth-child(), :first-child и :last-child. Он появился в спецификации Selectors Level 3, а в Selectors Level 4 получил расширенный аргумент of S. Задача у него одна: выбирать элементы по номеру позиции среди соседей, но нумерация идёт от конца родителя, а не от начала. Это делает его незаменимым там, где известно расстояние до конца списка, а не до начала: «последние три», «все, кроме последнего», «предпоследний».
Как это работает
Браузер берёт всех детей родителя, нумерует их с конца начиная с 1 и сравнивает номер с аргументом псевдокласса. Аргументы те же, что у :nth-child(): конкретное число, ключевые слова odd и even, формула An+B, где n принимает значения 0, 1, 2 и далее, а отрицательные и нулевые результаты формулы отбрасываются. Считаются все соседи одного уровня независимо от тега; если нужен счёт с конца только среди одноимённых тегов, есть парный псевдокласс :nth-last-of-type(), устроенный по аналогии с :nth-of-type().
- :nth-last-child(1) – последний элемент, полный аналог :last-child.
- :nth-last-child(2) – предпоследний элемент.
- :nth-last-child(-n+3) – последние три элемента.
- :nth-last-child(n+2) – все элементы, кроме последнего.
- :nth-last-child(odd) – нечётные с конца: последний, третий с конца и так далее.
/* последние три строки таблицы */
tr:nth-last-child(-n + 3) { background-color: pink; }
/* все строки, кроме последней */
tr:nth-last-child(n + 2) { color: blue; }
/* предпоследняя строка */
tr:nth-last-child(2) { font-weight: 600; }Отфильтровать подсчёт по произвольному селектору позволяет синтаксис of S: правило li:nth-last-child(-n+3 of li.important) выберет последние три элемента с классом important, пропуская остальные li при нумерации. Поддержка of S уже, чем у самого псевдокласса, поэтому для критичных интерфейсов стоит предусматривать запасной вариант.
:nth-last-child() и :nth-child() – в чём разница
| Критерий | :nth-child() | :nth-last-child() |
|---|---|---|
| Направление отсчёта | С начала родителя | С конца родителя |
| Индекс 1 | Первый ребёнок | Последний ребёнок |
| Типовая задача | «Первые N», «каждый третий» | «Последние N», «все, кроме последнего» |
| Реакция на добавление | Номера существующих элементов не меняются | Добавление в конец сдвигает номера всех элементов |
| Синтаксис of S | Поддерживается | Поддерживается |
Последняя особенность – одновременно и подводный камень. В динамических списках вроде ленты комментариев или каталога с подгрузкой добавление элемента в конец сдвигает нумерацию всех остальных с точки зрения :nth-last-child(): браузер пересчитает стили автоматически, но «последними тремя» визуально станут другие элементы. Это стоит учитывать при анимациях и подсветке.
Зачем это нужно
Базовые сценарии – стилизация конца списка без дополнительных классов и JavaScript: убрать нижнюю границу у последнего пункта меню, выделить последние строки таблицы, оставить отступ у всех карточек, кроме последней. Для «всех, кроме последнего» существует и альтернатива через :not() – запись li:not(:last-child) даёт тот же результат с той же специфичностью, выбор зависит от читаемости и привычек команды.
Quantity queries: стилизация по количеству элементов
Главный козырь: :nth-last-child() – единственный способ средствами чистого CSS среагировать на количество элементов в контейнере. Логика такая: селектор li:nth-last-child(n+3) матчит элементы, после которых идут ещё минимум два соседа, то есть срабатывает только в списках из трёх и более пунктов. В паре с комбинатором ~ получается правило «если элементов три и больше – стилизуем все»:
/* если пунктов >= 3 – красим весь список */
li:nth-last-child(n + 3),
li:nth-last-child(3) ~ li { color: red; }Первая часть выбирает все элементы, кроме двух последних, вторая – соседей после третьего с конца, то есть эти два последних. Вместе они накрывают список целиком, но только при достаточном количестве пунктов. Приём называется quantity queries и показан в справочнике MDN, а в русскоязычных разборах :nth-last-child() почти не встречается, хотя решает реальные задачи вёрстки: сжать карточки, когда их стало много, перевести меню в компактный режим, скрыть анонсы в тесной сетке – без единой строки JavaScript и без медиазапросов.
Пример
Сетка кейсов на Битрикс-сайте: пока элементов один или два, карточки выводятся крупными, с полным анонсом; когда их становится три и больше, анонсы скрываются, чтобы сетка оставалась компактной.
.case-card:nth-last-child(n + 3) .case-card__preview,
.case-card:nth-last-child(3) ~ .case-card .case-card__preview {
display: none;
}Компонент news.list выводит столько карточек, сколько вернул инфоблок, и вёрстка сама подстраивается под количество: не нужны ни подсчёт элементов в шаблоне, ни JavaScript. Специфичность правила остаётся низкой – псевдокласс весит столько же, сколько обычный класс, поэтому такие правила легко переопределять; подробнее в статье о специфичности CSS.
Поддержка: по данным MDN, :nth-last-child() имеет статус Baseline Widely Available и работает во всех браузерах с июля 2015 года, исторически – начиная с IE9 (Selectors Level 3). Расширение of S моложе: Chrome и Edge 111 (март 2023), Firefox 113 (май 2023), Safari – с версии 9 (2015).