Различия между :nth-child и :nth-of-type

Original author: Chris Coyier
  • Translation
Допустим, есть такой HTML:
<section>
   <p>Little</p>
   <p>Piggy</p>    <!-- Нужен этот элемент -->
</section>

Следующий CSS будет делать одно и тоже:
p:nth-child(2) { color: red; }

p:nth-of-type(2) { color: red; }


Хотя, конечно, в этих селекторах, есть разница.

Псевдокласс :nth-child, означачает выбрать элемент, если:
  1. Этот элемент — параграф;
  2. Это второй элемент одного родителя.

Псевдокласс :nth-of-type, означает:
  1. Выбрать второй параграф одного родителя.

Предположим, что наша разметка изменена следующим образом:
<section>
   <h1>Words</h1>
   <p>Little</p>
   <p>Piggy</p>    <!-- Нужен этот элемент -->
</section>

Теперь первый вариант не работает:
p:nth-child(2) { color: red; } /* Не работает */

Второй продолжает работать:
p:nth-of-type(2) { color: red; } /* Продолжает работать */

Под «Не работает» я имею ввиду, что cелектор :nth-child выбирает слово «Little» вместо «Piggy». Потому что элемент выполняет оба условия: 1) Это второй элемент родительского элемента и 2) Это параграф. Под «Продолжает работать», я имею ввиду, что селектор продолжает выбираться «Piggy», потому что это второй параграф родительского элемента.

Если добавить <h2> после <h1>, то селектор с :nth-child не выберет ничего, потому что параграф больше не является вторым элементом. Селектор с :nth-of-type продолжит работать.

Мне кажется :nth-of-type менее хрупкий и более полезный в целом, несмотря на это :nth-child продолжает быть основным в работе. Как часто вы думаете «Я хочу выбрать второй элемент в родительском блоке, если это параграф». Возможно иногда, но чаще вы думаете «Выбрать второй параграф» или «выбрать каждую третью строку таблицы», для этих задач больше подходит :nth-of-type (опять же, на мой взгляд).

Большинство ситуаций, когда я говорю «Почему мой селектор с :nth-child не работает?» случаются из за того, что я забываю про выборку тегов и нужный тег не оказывается по счету тем, который нужен. Поэтому, при использовании :nth-child лучше указывать его от родителя и не использовать привязку к тегу.
dl :nth-child(2) {  } /* Этот вариант лучше чем */
dd:nth-child(2) {  } /* этот */

Но, конечно, все зависит от конкретной ситуации.

Поддержка браузерами :nth-of-type довольно приличная… Firefox 3.5+, Opera 9.5+, Chrome 2+, Safari 3.1+, IE 9+. Я бы сказал, если вам нужна более глубокая поддержка, то используйте jQuery (используйте селектор и применяйте класс, там где нужно), но jQuery прекратил поддержку :nth-of-type. Слышал, что из за редкого использования, но мне это кажется странным. Если вы хотите пойти этим путем, то вот плагин возвращающий поддержку назад.
Share post

Similar posts

AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 16

    0
    > «но jQuery прекратил поддержку :nth-of-type. Слышал, что из за редкого использования, но мне это кажется странным»

    У Jquery есть более универсальные средства, которые в частности реализуют и данный функционал.

      0
      чтоб быть более точным, jQuery использует движок Sizzle, а тот в свою очередь не поддерживает nth-of-type.
      в jQuery это можно реализовать как $('p:odd') для четных и $('p:even') для нечетных.
        +1
        Jquery очень гибок.
        Например:
        $('p').eq(2) // выбрать второй параграф.
          +12
          кстати третий.
          $('p').eq(1) Вот это второй
          0
          А если через три надо выбрать? Или начиная со второго, например?
            0
            если начиная с индекса N то p:gt(N-1)
              0
              Я вообще имел в виду через три начиная со второго, но так тоже можно :)
              0
              а если каждый третий то уже надо ухищряться, например так
              $('p').each(function(i){
              if(i%3==0) return;
              ///делаем что хотим
              )}
          –1
          спасибо, то что нужно!
            0
            А вообще, что селектор :nth-of-type подразумевает под type? Имя тега? Получается, что селектор .class:nth-of-type(2) бессмысленный, потому что не задает какой именно нужно тип выбрать? Или же в данном случае типом будет считаться .class?
              0
              Судя по описанию w3c, под type понимается элемент, тоесть тег.
              www.w3.org/TR/css3-selectors/#nth-of-type-pseudo
              Но проверил, в случае описаном вами firefox, safari и chrome выберут второй элемент, если у него есть класс .class
                +1
                Селекторы всегда относятся к тому элементу, который задан до них. В случае p:nth-of-type(x) это будет тег P, в случае table .info:nth-of-type(x) будет любой тег с классом .info внутри таблиц.
                  –1
                  К сожалению ни nth-child, ни nth-of-type с классами и атрибутами не работают — только элементы.
                  Т.е. если у вас часть строк таблицы скрыты, то нельзя правильно сделать зебру средствами CSS для оставшихся видимых строк с определённым назначенным классом.
                0
                Спасибо за перевод!

                (А Между тем у меня были ситуации, когда «:nth-child» не работал «по странным обстоятельствам» :-).
                  –14
                  битрикс
                    0

                    Only users with full accounts can post comments. Log in, please.