Разница между :nth-child и :nth-of-type


Рассмотрим следующий код HTML: 1 <section> 2 <p>Маленькая</p> 3 <p>свинка</p> <!-- Нам нужен вот этот элемент --> 4 </section> Следующие правила CSS будут модифицировать нужный элемент: 1 p:nth-child(2) { color: red; } 1 p:nth-of-type(2) { color: red; } Но между двумя селекторами конечно же существует разница. Наш селектор :nth-child выбирает элемент если: Это параграф. Второй элемент-наследник в родительском элементе. Наш селектор :nth-of-type выбирает элемент, если: Это второй элемент-наследник типа параграф в родительском элементе. Селектор :nth-of-type накладывает меньше условий. Допустим, что разметка изменилась: 1 <section> 2 <h1>Персонаж</h1> 3 <p>Маленькая </p> 4 <p>свинка</p> <!-- Нам нужен вот этот элемент --> 5 </section> Первый селектор выдаст неправильный результат: 1 p:nth-child(2) { color: red; } /* Изменит слово "Маленькая" */ А второй селектор будет работать по-прежнему правильно: 1 p:nth-of-type(2) { color: red; } /* Делает то, что нужно */ Селектор :nth-child теперь выбирает слово "Маленькая" вместо "свинка", так как именно этот элемент удовлетворяет обеим условиям: 1) это второй элемент-наследник, и 2) он является параграфом. А во втором случае выбирается именно второй параграф-наследник в родительском элементе. Если мы добавим тег <h2> после тега <h1>, селектор :nth-child не выберет вообще ничего. Потому что второй элемент наследник является теперь заголовком, а не параграф. А селектор :nth-of-type по-прежнему будет выдавать правильный результат. Складывается ощущение, что селектор :nth-of-type менее уязвим к ошибкам и в общем случае более удобен к использованию, хотя селектор :nth-child используется значительно чаще. Как часто вы думаете "Я хочу выбирать второй элемент-наследник, если он будет параграфом."? Вероятно, что весьма редко. Более распространена ситуация "Надо выбрать второй параграф!" или "Выбираем каждую третью строку таблицы!", которая полностью соответствует использованию селектора :nth-of-type. Очень часто в работе возникают вопросы "Что за ерунда? Почему этот селектор :nth-child не работает?!" именно потому, что при верстке в родительский элемент вклинивается какой-нибудь тег, и селектор начинает указывать в небо. Поэтому лучше указывать родительский тег и оставлять :nth-child без указания тега: 1 dl :nth-child(2) { } /* Лучше, чем */ 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. Но вопрос решается использованием специального плагина jQuery. Стоит также помнить о таких селекторах, как :first-of-type, :last-of-type, :nth-last-of-type и :only-of-type.