Псевдокласс :nth-last-child()

:nth-last-child() – CSS-псевдокласс, выбирающий элементы по позиции среди соседей с отсчётом от конца родителя: nth-last-child(1) – последний элемент. Принимает те же аргументы, что :nth-child(): число, odd/even, формулу An+B.

4 минуты чтения

Псевдокласс :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()
Критерий: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).

Частые вопросы

Чем :nth-last-child() отличается от :nth-child()?

Только направлением отсчёта: :nth-child() нумерует детей с начала родителя, :nth-last-child() – с конца. Аргументы идентичны: число, odd/even, формула An+B, опциональный of S. Формулы зеркальны: первые три элемента – :nth-child(-n+3), последние три – :nth-last-child(-n+3).

Как выбрать последние N элементов списка через CSS?

Формулой :nth-last-child(-n+N). Например, li:nth-last-child(-n+3) выберет последние три пункта: при n = 0, 1, 2 формула даёт номера 3, 2, 1 с конца, а дальнейшие значения отрицательны и отбрасываются.

Как выбрать все элементы, кроме последнего?

Записью :nth-last-child(n+2) – она матчит все элементы со вторым и большим номером с конца. Альтернатива – :not(:last-child); результат тот же, специфичность в обоих случаях равна одному классу, так что выбор зависит только от читаемости.

Чем :nth-last-child(1) отличается от :last-child?

Результат одинаковый – последний ребёнок родителя, и специфичность у обоих равная: это псевдоклассы весом в один класс. Разница в гибкости: :nth-last-child() принимает формулы и of S, а :last-child короче и читается легче. Для «просто последнего» принято писать :last-child.

Что такое quantity queries и при чём тут :nth-last-child()?

Это приём стилизации в зависимости от количества элементов без JavaScript. Селектор li:nth-last-child(n+3) срабатывает, только когда в списке минимум три пункта, а в паре с li:nth-last-child(3) ~ li правило накрывает весь список. Так вёрстка сама переключает вид «короткого» и «длинного» списка.

Работают ли odd и even с конца списка?

Да, чётность считается от последнего элемента: :nth-last-child(odd) выбирает первый, третий, пятый элементы с конца. В списке из четырёх пунктов это будут четвёртый и второй элементы, если считать с начала.

Можно ли использовать of S внутри :nth-last-child()?

Да, синтаксис общий с :nth-child(): запись li:nth-last-child(-n+3 of li.important) выберет последние три элемента с классом important, не учитывая остальные li при подсчёте. Поддержка of S: Chrome и Edge с версии 111, Firefox со 113, Safari с 9.

Материалы по теме

Валентина Меланина

Нужна консультация?

Разберу ваш сайт и покажу точки роста

Если хотите понять, как этот термин применить к вашему проекту — начнём с аудита.