Могу ли я объединить:nth-child () или:nth-of-type () с произвольным селектором?
есть ли способ выбрать каждый N-й ребенок что соответствует (или не соответствует) произвольному селектору? Например, я хочу выбрать каждую нечетную строку таблицы, но в пределах подмножества строк:
table.myClass tr.row:nth-child(odd) {
...
}
<table class="myClass">
<tr>
<td>Row
<tr class="row"> <!-- I want this -->
<td>Row
<tr class="row">
<td>Row
<tr class="row"> <!-- And this -->
<td>Row
</table>
но :nth-child()
просто, кажется, считать все tr
элементы независимо от того, являются ли они классом" row", поэтому я получаю один даже элемент "row" вместо двух, которые я ищу. То же самое происходит и с :nth-of-type()
.
может кто-нибудь объяснить, почему?
4 ответа:
это очень распространенная проблема, которая возникает из-за непонимания, как
:nth-child()
и:nth-of-type()
работа. К сожалению, в настоящее время нет решения на основе селектора, потому что селекторы не обеспечивают способ сопоставления n-го дочернего элемента, который соответствует произвольному селектору на основе шаблона, такого как нечетный, четный или любойan+b
здесьa != 1
иb != 0
. Это выходит за рамки только селекторов классов, чтобы приписать селекторы, отрицания и более сложные комбинации простых селекторы.The
:nth-child()
псевдо-класс подсчет элементов между все их братьев и сестер под одним родителем. Не считать только братьев и сестер, которые соответствуют остальной части селектора. Точно так же,:nth-of-type()
псевдо-класс подсчитывает братьев и сестер, имеющих один и тот же тип элемента, который ссылается на имя тега в HTML, а не на остальную часть селектора.это также означает, что если все дети одного родителя имеют тот же тип элемента, например, в случае тела таблицы, единственными дочерними элементами которого являются
tr
элементы или элемент списка, единственными дочерними элементами которого являютсяli
элементы, затем:nth-child()
и:nth-of-type()
будет вести себя одинаково, т. е. для каждого значенияan+b
,:nth-child(an+b)
и:nth-of-type(an+b)
будет соответствовать тот же набор элементов.фактически, все простые селекторы в данном составном селекторе, включая псевдоклассы, такие как
:nth-child()
и:not()
, работает самостоятельно одного другом, а не смотреть на!--37-->подмножество элементов, которым соответствует остальная часть селектора.это также означает, что нет понятия порядка среди простых селекторов внутри каждого отдельного составного селектора1, что означает, например, что следующие два селектора эквивалентны:
table.myClass tr.row:nth-child(odd) table.myClass tr:nth-child(odd).row
в переводе на английский, они оба означают:
выберите
tr
элемент, который соответствует всем следующим независимым условиям:
- это нечетный ребенок своего родителя;
- он имеет класс "row"; и
- является потомком элемента
table
элемент, который имеет класс "myClass".(вы заметили, что я использую неупорядоченный список здесь, просто доказать)
поскольку в настоящее время нет чистого решения CSS, вам придется использовать скрипт для фильтрации элементов и применения стилей или дополнительных имен классов соответственно. Например, ниже приведен общий обходной путь с использованием jQuery (предполагая, что есть только одна группа строк, заполненная
tr
элементы в таблицу):$('table.myClass').each(function() { // Note that, confusingly, jQuery's filter pseudos are 0-indexed // while CSS :nth-child() is 1-indexed $('tr.row:even').addClass('odd'); });
С соответствующим CSS:
table.myClass tr.row.odd { ... }
если вы используете автоматизированные инструменты тестирования, такие как Selenium или обработка HTML с помощью таких инструментов, как lxml, многие из этих инструментов позволяют XPath как альтернатива:
//table[contains(concat(' ', @class, ' '), ' myClass ')]//tr[contains(concat(' ', @class, ' '), ' row ')][position() mod 2)=1]
другие решения, использующие различные технологии, оставлены в качестве упражнения для читателя; это всего лишь краткий, надуманный пример для иллюстрации.
для чего это стоит, есть предложение для расширение
:nth-child()
обозначение для добавления к селекторам уровня 4 с конкретной целью выбора каждого n-го дочернего элемента, соответствующего данному селектору.2селектор для фильтрации совпадения предоставляются в качестве аргумента для
:nth-child()
опять же из-за того, как селекторы работают независимо друг от друга в последовательности, продиктованной существующей синтаксис селектора. Так что в вашем случае это будет выглядеть так:table.myClass tr:nth-child(odd of .row)
(проницательный читатель сразу заметит, что это должно быть
:nth-child(odd of tr.row)
вместо этого, так как простые селекторыtr
и:nth-child()
работают независимо друг от друга, а также. Это одна из проблем с функциональными псевдоклассами, которые принимают селекторы, банку червей я бы предпочел не открывать в середине этого ответа. Вместо этого я собираюсь пойти с предположением, что большинство сайтов не будет иметь никаких других элементов, чемtr
элементы как братья и сестры друг друга в теле таблицы, что сделает любой вариант функционально эквивалентным.)конечно, будучи совершенно новым предложением в совершенно новой спецификации, это, вероятно, не увидит реализации до нескольких лет вниз по дороге. В то же время, вам придется придерживаться используя скрипт, как указано выше.
1если вы укажете тип или универсальный селектор, он должен быть первым. Однако это не меняет фундаментальной работы селекторов; это не более чем синтаксическая причуда.
2это было первоначально предложено как
:nth-match()
, однако, поскольку он по-прежнему считает элемент только относительно своих братьев и сестер, а не для каждого другого элемента, который соответствует данному селектору, он имеет так как по состоянию на 2014 год был перепрофилирован в качестве расширения к существующему:nth-child()
вместо.
не совсем так..
The
:nth-child
псевдо-класс соответствует элемент, который имеет+b-1 братья и сестры перед этим в дереве документов, для a заданное положительное или нулевое значение для n, и имеет родительский элемент.это селектор сам по себе и не сочетается с классами. В вашем правиле он просто должен удовлетворять оба селектора одновременно, поэтому он покажет
:nth-child(even)
строк таблицы если у них также есть.row
класса.
nth-of-type
работает в соответствии с индексом того же типа элемента, ноnth-child
работает только в соответствии с индексом независимо от того, какой тип элементов братьев и сестер.<div class="one">...</div> <div class="two">...</div> <div class="three">...</div> <div class="four">...</div> <div class="five">...</div> <div class="rest">...</div> <div class="rest">...</div> <div class="rest">...</div> <div class="rest">...</div> <div class="rest">...</div>
предположим, что в приведенном выше html мы хотим скрыть все элементы, имеющие класс rest.
в этом случае
nth-child
иnth-of-type
будет работать точно так же, как все элементы имеют тот же тип, что и<div>
так что css должен будь.rest:nth-child(6), .rest:nth-child(7), .rest:nth-child(8), .rest:nth-child(9), .rest:nth-child(10){ display:none; }
или
.rest:nth-of-type(6), .rest:nth-of-type(7), .rest:nth-of-type(8), .rest:nth-of-type(9), .rest:nth-of-type(10){ display:none; }
теперь вам должно быть интересно, в чем разница между
nth-child
иnth-of-type
так вот в чем разницапредположим, что html-это
<div class="one">...</div> <div class="two">...</div> <div class="three">...</div> <div class="four">...</div> <div class="five">...</div> <p class="rest">...</p> <p class="rest">...</p> <p class="rest">...</p> <p class="rest">...</p> <p class="rest">...</p>
в приведенном выше html тип
.rest
элемент отличается от других.rest
являются абзацы и другие div так что в этом случае, если вы используетеnth-child
нужно писать.rest:nth-child(6), .rest:nth-child(7), .rest:nth-child(8), .rest:nth-child(9), .rest:nth-child(10){ display:none; }
но если вы используете nth-of-type css может быть это
.rest:nth-of-type(1), .rest:nth-of-type(2), .rest:nth-of-type(3), .rest:nth-of-type(4), .rest:nth-of-type(5){ display:none; }
как типа
.rest
элемент<p>
здесьnth-of-type
обнаружение типа.rest
и тогда он обратился в КСС на 1й, 2й, 3й, 4й, 5й элемент<p>
.