Псевдоклассы CSS: nth-child и nth-of-type. CSS3 - новые псевдоклассы

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

Обозначения

Описание Пример
<тип> Указывает тип значения. <размер>
A && B Значения должны выводиться в указанном порядке. <размер> && <цвет>
A | B Указывает, что надо выбрать только одно значение из предложенных (A или B). normal | small-caps
A || B Каждое значение может использоваться самостоятельно или совместно с другими в произвольном порядке. width || count
Группирует значения. [ crop || cross ]
* Повторять ноль или больше раз. [,<время>]*
+ Повторять один или больше раз. <число>+
? Указанный тип, слово или группа не является обязательным. inset?
{A, B} Повторять не менее A, но не более B раз. <радиус>{1,4}
# Повторять один или больше раз через запятую. <время>#
×

Значения

odd Все нечётные номера элементов, начиная с конца. even Все чётные номера элементов, начиная с конца. <число> Порядковый номер дочернего элемента относительно своего родителя. Нумерация начинается с 1, это соответствует последнему элементу в списке. <выражение> Задаётся в виде an±b , где a и b целые числа, а n - счётчик, который автоматически принимает значение 0, 1, 2...

Если a равно нулю, то оно не пишется и запись сокращается до b . Если b равно нулю, то оно также не указывается и выражение записывается в форме an . a и b могут быть отрицательными числами, в этом случае знак плюс меняется на минус, например: 5n-1.

За счёт использования отрицательных значений a и b некоторые результаты могут также получиться отрицательными или равными нулю. Однако на элементы оказывают влияние только положительные значения из-за того, что нумерация элементов начинается с 1.

В табл. 1 приведены некоторые возможные выражения и ключевые слова, а также указано, какие номера элементов будут задействованы. Отсчёт ведётся от последнего элемента.

Табл. 1. Результат для различных значений псевдокласса
Значение Номера элементов Описание
1 1 Последний элемент, является синонимом псевдокласса :last-child .
5 5 Пятый элемент с конца.
2n 2, 4, 6, 8, 10,… Все чётные элементы, начиная с конца; аналог значения even .
2n+1 1, 3, 5, 7, 9,… Все нечётные элементы, начиная с конца; аналог значения odd .
3n 3, 6, 9, 12,… Каждый третий элемент, начиная с конца.
3n+2 2, 5, 8, 11, 14,… Каждый третий элемент, начиная с предпоследнего.
n+4 4, 5, 6, 7, 8,… Все элементы, кроме последних трёх.
-n+3 3, 2, 1 Последние три элемента.
5n-2 3, 8, 13, 18, 23,…
even 2, 4, 6, 8, 10,… Все чётные элементы, начиная с конца.
odd 1, 3, 5, 7, 9,… Все нечётные элементы, начиная с конца.

Пример

nth-last-child

21342135 213621372138
Нефть1634 627457
Золото469 725647
Дерево773 793486
Камни2334 8853103

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

Рис. 1. Применение псевдокласса:nth-last-child к колонкам таблицы

Спецификация

Каждая спецификация проходит несколько стадий одобрения.

  • Recommendation (Рекомендация ) - спецификация одобрена W3C и рекомендована как стандарт.
  • Candidate Recommendation (Возможная рекомендация ) - группа, отвечающая за стандарт, удовлетворена, как он соответствует своим целям, но требуется помощь сообщества разработчиков по реализации стандарта.
  • Proposed Recommendation (Предлагаемая рекомендация ) - на этом этапе документ представлен на рассмотрение Консультативного совета W3C для окончательного утверждения.
  • Working Draft (Рабочий проект ) - более зрелая версия черновика после обсуждения и внесения поправок для рассмотрения сообществом.
  • Editor"s draft (Редакторский черновик ) - черновая версия стандарта после внесения правок редакторами проекта.
  • Draft (Черновик спецификации ) - первая черновая версия стандарта.
×

CSS nth-child — это псевдокласс, используемый для выбора элементов с помощью числового выражения. Его синтаксис на первый взгляд может показаться немного запутанным.

В этой статье мы рассмотрим:

  • различные способы использования :nth-child ;
  • более гибкий селектор :nth-of-type ;
  • и связанные с ними селекторы :nth-last-child и :nth-last-of-type .

:nth-last-of-type

:nth-last-of-type выбирает дочерние элементы, если их позиция в документе совпадает с шаблоном, описываемым алгебраическим выражением.

Селектор :nth-last-of-type выглядит примерно так:

li:nth-child(выражение); {}

«Выражение » может быть представлено ключевыми словами even или odd , целым числом или формулой по типу an+b , где a и b — целые числа, положительные или отрицательные.

Поскольку псевдокласс CSS nth child может использоваться для выбора диапазона различных элементов. Давайте рассмотрим несколько примеров, чтобы стало понятнее.

У меня есть маркированный список из 12 элементов. Посмотрим, как можно использовать :nth-child для выбора определенного элемента или набора элементов по шаблону:

  • lorem ipsum
  • lorem ipsum
  • lorem ipsum
  • lorem ipsum
  • lorem ipsum
  • lorem ipsum
  • lorem ipsum
  • lorem ipsum
  • lorem ipsum
  • lorem ipsum
  • lorem ipsum
  • lorem ipsum

Чтобы выбрать третий элемент списка, нужно указать li:nth-child(3) . Чтобы выбрать все четные элементы, можно использовать ключевое слово even. И наоборот, можно использовать :nth-child(odd) , чтобы выбрать все элементы с нечетным номером.

CSS nth child каждый 3 й — указываем li:nth-child(3n) . Чтобы выбрать первые четыре элемента, используем li:nth-child(-n+4) . Чтобы выбрать все, кроме первых четырех элементов, можно использовать li:nth-child(n+5) .

Выражение an + b

Альтернативой использованию ключевого слова odd является использование выражения 2n+1 . Но как это работает?

Когда выражение в формате an+b содержит отличные от ноля значения a и b , дочерние элементы разбиваются на группы. Если это выражение 2n+1 , дочерние элементы разбиваются на группы по два. Каждому элементу в группе присваивается индекс, начиная с 1 . Соответствующий элемент в каждой группе — это индекс номер b . В нашем примере это будет первый элемент.

Если выражение 3n+2 , элементы группируются по три элемента, и второй элемент в каждой группе соответствует выражению.

Если значение b является отрицательным, соответствующим в группе является элемент с индексом b . Но отсчитывается он в обратном направлении от индекса 1 . В этом случае соответствующий элемент будет принадлежать не данной, а предшествующей группе.

Ключевое слово even в CSS nth child может быть выражено как 2n . В этом случае у нас нет значения b , поэтому выбирается каждый элемент группы с индексом a ; 2n выбирает каждый второй элемент, 3n — каждый третий, 4n — каждый четвертый и так далее.

Лично я считаю, что концепция разбивки дочерних элементов на группы и поиска индекса соответствия для каждой группы очень запутана. Хотя именно так их описывает спецификация CSS-селекторов .

Мне больше нравится концепция поиска каждого n-ного элемента — каждого 2-го, 3-го или 4-го и т.д. А потом мне проще представить, что вторая часть выражения — это смещение.

В случае 2n+1 я читаю это выражение следующим образом: «Найти каждый второй элемент и переместить выделение вниз на 1 ».

Если выражение 3n-5 , оно будет читаться так: «Найти каждый третий элемент и переместить выделение вверх на 5 ».

Другие селекторы:nth-child

:nth-child имеет соответствующий ему псевдокласс :nth-last-child , который работает наоборот.

li:nth-last-child(3n) начинает с последнего дочернего элемента и обрабатывает их в обратном направлении, сопоставляя каждый третий элемент с конца списка.

Этот псевдокласс менее распространен. Тем не менее, часто необходимо выбрать первый или последний дочерний элемент. Это можно сделать с помощью :nth-child(1) или :nth-last-child(1) , но этот метод встречается не так часто, как псевдоклассы :first-child и :last-child . При этом только :first-child работает в IE8 , а :last-child и :nth-селекторы — нет.

:nth-of-type

Что меня часто не удовлетворяет, так это то, что псевдокласс CSS nth child отбирает дочерние элементы по индексу и не учитывает тип элемента.

Рассмотрим следующий пример.

lorem ipsum;

Aenean commodo ligula eget dolor. Vestibulum dapibus nunc ac augue;

Nunc sed turpis. Donec posuere vulputate arcu;

Есть раздел с заголовком, подзаголовком и несколькими абзацами. Я хочу, чтобы первый абзац немного выделялся с помощью увеличенного размера шрифта 1.5em .

Можно попробовать применить код section p:first-child , так как нужно задать дополнительный стиль для первого абзаца в этом разделе. Но это не сработает, поскольку первый дочерний элемент раздела — h1 . В этом случае необходимо использовать селектор :first-of-type .

Существует целый ряд селекторов этого типа — :first-of-type , :last-of-type , :nth-of-type и :nth-last-of-type . Они ведут себя так же, как :nth-child , но отбирают n-ые экземпляры элементов определенного типа.

Эти селекторы довольно сложны, но они предоставляют большие возможности. Они поддерживаются всеми браузерами, начиная с IE9 , в IE8 поддерживается только :first-child . В прошлом они не раз помогли мне решить несколько сложных задач.

Перевод статьи «AtoZ CSS Screencast: nth-child and nth-of-type » дружной командой проекта

  • Перевод

Вам когда-нибудь хотелось прямо в CSS коде посчитать, в меню 4 элемента или 10? Для четырех задать им ширину по 25%, а если набралось десять - прижать их друг к другу и уменьшить отступы?
Как выяснилось, CSS умеет работать с разным количеством элементов, позволяя избавиться от головных болей и лишнего кода на js.

/* "больше-чем-один" будут иметь уменьшенный размер шрифта */ button { font-size: 2em; } button:not(:only-of-type) { font-size: 1.25em; }

N элементов

Применять стили, основываясь на «больше-чем-один» и «меньше-чем-два» это ловкий трюк, но нам нужен более гибкий инструмент, позволяющий оперировать с любым числом. Мы хотим использовать селекты “больше или равно N” для любого N. Кроме этого, хочется иметь селект «ровно 745» или «суммарно ровно 6».

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

Всё становится интереснее, когда мы совмещаем:nth-last-child(6) и:first-child, в результате получая все элементы, которые являются шестыми с конца и при этом первыми с начала.

Li:nth-last-child(6):first-child { /* зеленый кальмар */ }
Если такой элемент существует, это будет значить, что у нас ровно 6 элементов. Таким образом, я написал CSS код, который может сказать, сколько элементов я вижу перед собой.

Осталось теперь воспользоваться этим одновременно «шестым с конца и первым с начала» элементом, чтобы еще и поселектать все остальные 5 элементов. Для этого я воспользуюсь общим соседним комбинатором .

Если вы не знакомы с этим комбинатором, то объясняю, ~ li в селекте li:nth-last-child(6):first-child ~ li значит «любой li, который идёт после li:nth-last-child(6):first-child». В нашем случае, элементы будут иметь зеленый цвет шрифта, если их ровно 6 штук.

Li:nth-last-child(6):first-child, li:nth-last-child(6):first-child ~ li { color: green; }

Больше или равно 6

Селектать фиксированное количество, будь то 6, 19 или 653 - не очень-то полезно, так как подобная необходимость очень редка. Это как в media queries - не очень удобно использовать фиксрованную ширину вместо min-width или max-width:

@media screen and (width: 500px) { /* стили для ширины вьюпорта ровно в 500px */ }
В навигационном меню я хочу переключать стили с границей, основанной на количестве элементов, например, поменять нужные стили, если у меня 6 и больше элементов (а не ровно шесть).

Вопрос в том, как сделать такой селектор? и это вопрос смещений.

Параметр n+6

Селектор:nth-child() может принимать параметром не только число, но и формулу “n + [число]”. Например, :nth-child(n+6) будет применён ко всем элементам, начиная с шестого.


Хоть этот селектор и является мощным инструментом сам по себе, он не позволяет оперировать с количеством. Он применится не тогда, когда у нас больше шести элементов, а просто к элементам, у которых номер больше пяти.

Чтобы обойти эту проблему, нам нужно создать такой селект, который выделит все элементы, кроме последних пяти. Используя обратный к:nth-child(n+6) селект:nth-last-child(n+6) мы сможем выделить все элементы «от с шестого с конца и до самого первого с начала».

Li:nth-last-child(n+6) { /* здесь стили */ }
Такой селект отсекает последние пять элементов от набора любой длины, что означает, что если у вас меньше шести элементов, то в селект ничего и не попадет.

Если же в списке шесть или больше элементов, нам остаётся прибавить к селекту оставшиеся пять элементов. Это легко - если элементов больше шести, то срабатывает условие nth-last-child(n+6), и комбинируя его с "~" мы сможем поселектать все нужные нам элементы.

Такая вот короткая запись и является решением нашей проблемы:

Li:nth-last-child(n+6), li:nth-last-child(n+6) ~ li { /* здесь стили */ }
Разумеется, тут может быть любое положительное целое число, даже 653,279.

Меньше или N

Как и в предыдущем примере с:only-of-type, селектор можно использовать в обе стороны, и как «больше или равно N» и как «меньше или равно N». Какой вариант вы будете использовать? Зависит от того, какую сетку вы будете считать основной.
В случае «Меньше или N» мы берем n с минусом и добавляем условие:first-child.

Li:nth-last-child(-n+6):first-child, li:nth-last-child(-n+6):first-child ~ li { /* здесь стили */ }
В результате, использование "-" меняет направление селекта: вместо того, чтобы считать от начала и до шести, отсчёт будет идти от конца до шести. В обоих случаях, шестой элемент будет включён в селект.

nth-child против nth-of-type

Заметьте, что в предыдущих примерах я использовал:nth-child() и:nth-last-child(), а не:nth-of-type() с:nth-last-of-type(). Так как я селектал теги
  • и правильными потомками
      могут быть только они, :last-child() и:last-of-type() оказываются одинаково результативны.

      Обе группы селектов:nth-child() и:nth-of-type() имеют свои преимущества, исходя из того, чего вы хотите добиться. Так как:nth-child() не привязан к конкретному тегу, описанную выше технику можно применять к смешанным дочерним элементам:

      ...

      Container > :nth-last-child(n+3), .container > :nth-last-child(n+3) ~ * { /* здесь стили */ }
      (Обратите внимание, чтобы не привязываться к тегам, я использую универсальный селектор . :last-child(n+3) ~ *. В этом случае, он обозначает «любой элемент любого тега, следующий за:last-child(n+3).»

      С другой стороны, преимущество:nth-last-of-type() в том, что вы можете селектать элементы с одним тегом среди множества других соседних. Например, можно посчитать количество тегов

      Несмотря на то, что они в одной куче с

      и
      .

      ...

      P:nth-last-of-type(n+6), p:nth-last-of-type(n+6) ~ p { /* здесь стили */ }

      Поддержка браузерами

      Все используемые в статье селекторы CSS2.1 и CSS3 поддерживаются в Internet Explorer 9 и выше , а так же все современные мобильные и десктопные браузеры.

      Internet Explorer 8 неплохо поддерживает большинство селектов, но задуматься о полифилле на js не помешает. В качестве альтернативы, можно расставить специальные классы для старых версий IE и приписать их к своим селекторам. В случае с навигационным меню, код будет выглядеть примерно так:

      Nav li:nth-last-child(n+6), nav li:nth-last-child(n+6) ~ li, .lt-ie9 nav li { display: inline-block; /* и т.д. */ }

      В реальном мире

      Предположим, наше навигационное меню принадлежит сайту с CMS. В зависимости от того, кто его наполняет и использует, в меню будет разное количество элементов. Кто-то старается не усложнять и ему хватает «Home» и «About», а кто-то хочет запихать в меню всё, что есть у него на сайте.

      Создавая стили, учитывающие разные сетки для разного количества элементов в меню, мы делаем вёрстку более стройной и подходящей для самых разных форматов - какой бы ни был контент, у нас всё учтено.

      Поздравляю, теперь в вашем CSS арсенале есть умение оперировать количеством элементов.

      Контент-независимый дизайн

      Респонсив дизайн решает одну важную проблему: он позволяет комфортно расположить один и тот же контент на множестве разных устройств. Было бы неприемлемо видеть разный контент только потому, что у тебя экран неправильного размера. Так же и неприемлемо диктовать дизайнеру, под сколько пунктов меню должен быть заточен сайт. «Не рисуй так, у нас вся сетка поедет, если будет столько элементов».

      Какую форму примет контент и сколько его будет в конкретный момент времени - никто не знает. И мы не можем всегда полагаться на скрипты или обрезание текста, это неправильно. Правильно - быть независимым от количества контента и создавать для этого нужные механизмы и инструменты. Количественные селекторы это просто одна из идей для этого.

      Веб дизайн это всегда изменчивость, гибкость и неопределенность. В нём скорее не знаешь, чем знаешь. Он уникален тем, что представляет с собой вид визуального дизайна, который не определяет формы, а предвидит, какие формы может что-то принять. Для кого-то это неприемлемо и непонятно, но для вас и меня это вызов и удовольствие.

      Теги: Добавить метки

      От автора: в CSS есть селекторы для поиска элементов на основе их положения в дереве документа. Их называют индексными псевдоклассами, потому что они смотрят на положение элемента, а не на его тип, атрибуты или ID. Всего их пять.

      :first-child и:last-child

      По названию вы могли догадаться, что псевдоклассы:first-child и:last-child выбирают первый и последний дочерний элемент в узле (элементе). Как и с другими псевдоклассами, :first-child и:last-child оказывают минимальное стороннее воздействие при использовании простых селекторов.

      Рассмотрим HTML и CSS ниже:

      :first-child and:last-child

      List of fruits

      • Apples
      • Bananas
      • Blueberries
      • Oranges
      • Strawberries

      < ! DOCTYPE html >

      < html lang = "en-US" >

      < head >

      < meta charset = "utf-8" >

      < title > : first - child and : last - child < / title >

      < / head >

      < body >

      < h2 > List of fruits < / h2 >

      < ul >

      < li > Apples < / li >

      < li > Bananas < / li >

      < li > Blueberries < / li >

      < li > Oranges < / li >

      < li > Strawberries < / li >

      < / ul >

      < / body >

      < / html >

      На скриншоте ниже показан результат.

      Заголовок h2 и первый li окрасились в розовый, так как:first-child не привязан к конкретным элементам. Тег h2 – первый ребенок тега body, а li – первый дочерний элемент ul. Но почему оставшиеся элементы li зеленые? Потому что:last-child тоже не привязан к конкретному элементу, а ul является последним дочерним элементом в теге body. По сути, в стилях выше мы прописали *:first-child и *:last-child.

      Если добавить к:first-child и:last-child простой селектор, они станут конкретнее. Давайте ограничим нашу выборку только элементами списка. Замените:first-child на li:first-child и:last-child на li:last-child. На скриншоте ниже показан результат.

      :nth-child() и:nth-last-child()

      Уметь выбирать первый и последний дочерние элементы в документе неплохо. А что если нужно выбрать четные или нечетные элементы? Может, нам нужно выбрать шестой элемент в дереве или применить стили к каждому третьему дочернему элементу. Здесь нам помогут псевдоклассы:nth-child() и:nth-last-child().

      Как и:not, :nth-child() и:nth-last-child() также являются функциональными псевдоклассами. Они принимают один аргумент, который должен быть:

      ключевым словом odd;

      ключевым словом even;

      целочисленным значением типа 2 или 8;

      аргументом в форме Аn+B , где А – шаг, B – смещение, а n – переменная с положительным целочисленным числом.

      Последний аргумент немного сложнее остальных. Разберем его чуть позже.

      Чем отличаются:nth-child() и:nth-last-child()? Они отличаются точкой отсчета: :nth-child() считает вперед, а:nth-last-child() – назад. CSS индексы используют натуральные числа и начинаются с 1, а не с 0.

      С помощью псевдоклассов:nth-child() и:nth-last-child() удобно создавать чередующиеся узоры. Полосатая таблица – идеальный пример использования. CSS ниже присваивает четным строкам в таблице светлый синевато-серый фон, результат можно посмотреть на скриншоте ниже:

      tr:nth-child(even) { background: rgba(96, 125, 139, 0.1); }

      tr : nth - child (even ) {

      background : rgba (96 , 125 , 139 , 0.1 ) ;

      Если переключиться с:nth-child на:nth-last-child, полосы инвертируются, так как отсчет начнется с низа. Смотрите скриншот ниже.

      А хотите что-нибудь посложнее, с более сложными аргументами? Давайте создадим документ с 20 элементами, как показано ниже.

      С помощью:nth-child() и:nth-last-child() можно выбрать один определенный элемент. Можно выбрать все дочерние элементы после заданной позиции, или можно выбрать элементы с кратностью со смещением. Давайте изменим фон шестого элемента:

      Item:nth-child(6) { background: #e91e63; }

      Еще раз, А – шаг. Это множитель для n, начинающийся с 1. То есть если А = 3, то 3n выберет третий, шестой и девятый элементы и т.д. Именно это можно наблюдать на скриншоте ниже.

      Здесь уже все немного интереснее. С помощью:nth-child() и:nth-last-child() можно выбрать все элементы после заданной точки. Давайте выберем все элементы кроме первых семи:

      Item:nth-child(n+8) { background: #e91e63; }

      Item : nth - child (n + 8 ) {

      background : #e91e63;

      Здесь шаг не задан. Как результат, n+8 выбирает все элементы n, начиная с восьмого. Смотрите скриншот ниже.

      Замечание: отрицательное смещение

      Отрицательные значения и диапазоны также валидны. Запись типа:nth-child(-n+8) инвертирует выборку и выбирает первые восемь элементов.

      С помощью смещения и шага можно выбрать каждый третий элемент, начиная с пятого:

      Item:nth-child(3n+5) { background: #e91e63; }

      Item : nth - child (3n + 5 ) {

      background : #e91e63;

      Результат.

      only-child

      Псевдокласс only-child выбирает элемент только в том случае, если он единственный дочерний элемент. Ниже представлено два маркированных списка. В первом один элемент, во втором три:

      • Apple
      • Orange
      • Banana
      • Raspberry

      < ul >

      < li > Apple < / li >

      < / ul >

      < ul >

      < li > Orange < / li >

      < li > Banana < / li >

      < li > Raspberry < / li >

      < / ul >

      Селектор li:only-child{color: #9c27b0;} выберет

    • Apple
    • , так как это единственный дочерний элемент первого списка. Элементы второго списка в выборку не попадают, так как там три смежных элемента. Результат показан ниже.

      :empty

      С помощью псевдокласса:empty можно выбрать элементы, у которых нет дочерних элементов. Псевдокласс:empty говорит сам за себя (empty от англ. «пустой»). Чтобы попасть в выборку:empty, элемент должен быть абсолютно пустым, не должно быть даже пробелов. То есть попадает в выборку, а нет.

      Иногда WYSIWYG редакторы вставляют пустые теги p в ваш контент. С помощью:empty и:not можно делать так, чтобы к этим элементам не применялись стили. Например, p:not(:empty).

      Выбор элементов определенного типа по их индексу

      Описанные в предыдущем разделе псевдоклассы выбирают элементы, если те занимают определенную позицию в дереве документа. Например, p:nth-last-child(2) выберет все теги p перед последним внутри родительского блока.

      В этом разделе мы поговорим о типизированных индексных псевдоклассах. Эти псевдоклассы также выбирают элементы по значению индекса, но выбор ограничен определенным типом. Например, нужно выбрать пятый тег p или четные h2.

      Существует пять таких псевдоклассов, имена которых полностью противоположны их нетипизированным коллегам:

      nth-last-of-type()

      Грань между ними и дочерними индексными псевдоклассами тонка. Запись p:nth-child(5) находит только пятый тег p, а запись p:nth-of-type(5) находит все теги p и вычленяет среди них пятый.

      Давайте создадим другой документ. В нем также 20 элементов, только некоторые — это теги p, а другие – div. Теги p со скругленными углами, смотрите скриншот ниже.