Первое, что нужно объяснить, это то, что мое решение не использует ссылки на атрибуты (например, id, класс, имя и т. Д. c.) Только tagName
и :nth-of-type
псевдоклассы и дочерние комбинаторы >
. Причина в том, из-за характера вопроса. Если бы структура и классы были назначены минимальным образом, вероятно, вообще не было бы вопроса. Вот почему я избегаю использования <div>
для каждого элемента уровня блока. Я использую чередующиеся теги для каждого уровня:
<body> root
<main> 1st
<section> 2nd
<article> 3rd
<aside> 4th </aside>
</article>
</section>
</main>
</body>
Поддерживая структуру, подобную описанной выше, и используя псевдокласс CSS :nth-of-type
, мы можем точно ссылаться на уровни. :nth-of-type
ссылается на родителя в дочерних иерархиях, таких как его двоюродный брат nth-child
, но он превосходит nth-child
в том, что он также ссылается на тип тега. Хотя использование nth-of-type
в одних и тех же тегах может показаться излишним, мы все же можем получить точные результаты, если будем ссылаться на <body>
, поскольку он уникален, является предком почти каждого тега и не имеет родственных тегов.
body > div > div:first-of-type > div:first-of-type > p {
color: green
}
body
привязывает первое упоминание, которое не может быть выведено из чего-либо, кроме того, что оно есть. Пока каждый сегмент селектора устанавливает ссылку solid от своего родителя, меньше шансов, что любая неясность все испортит. Единственный дочерний элемент body
имеет div.parent
, поэтому достаточно > div
.
>
прямой потомок (или дочерний комбинатор) сужает возможности до двух div.child
.
:first-of-type
псевдокласс ограничивает возможность только до первого div.child
. Более того, если использовать first-child
, тогда вместо него будет выбран <p>
.
Другой > div:first-of-type
приведет нас к первому div.grandchild
> p
сужается до <p>Aaron</p>
.
Обратите внимание, что дочерний комбинатор >
играет очень важную роль. Если бы мы пренебрегли этим на последнем этапе, div:first-of-type p
схватил бы всех потомков <p>
- что означало бы <p>Victoria</p>
, а <p>Devin</p>
также было бы зеленым.
Еще одна вещь, которую нужно помнить, - это то, что даже самые лаконичные селекторы (такие как тот, что я предоставил) могут все еще перетекать через свои стили своим потомкам. Если ваше CSS демонстрирует именно это поведение, скорее всего, это связано с наследованием. К сожалению, это может быть решено только в каждом конкретном случае.
Демо
body > div > div:first-of-type > div:first-of-type > p {
color: green
}
<div class="parent">
<!-- red -->
<p>Jane</p>
<div class="child">
<!-- blue -->
<p>Jim</p>
<div class="grandchild">
<!-- green -->
<p>Aaron</p>
<!--------------------Style ONLY this one----->
<div class="greatgrandchild">
<!-- pink -->
<p>Victoria</p>
</div>
<div class="greatgrandchild greatgrandchild2">
<!-- purple -->
<p>Devin</p>
</div>
<!-- grandchild2 -->
</div>
<!-- grandchild -->
</div>
<!-- child -->
<div class="child child2">
<!-- coral -->
<p>Susan</p>
<div class="grandchild">
<!-- aqua -->
<p>George</p>
<div class="greatgrandchild">
<!-- rosybrown -->
<p>Julie</p>
</div>
</div>
<div class="grandchild grandchild2">
<!-- sienna -->
<p>Nancy</p>
<div class="greatgrandchild">
<!-- tomato -->
<p>Bob</p>
</div>
</div>
<!-- grandchild -->
</div>
</div>
<!-- parent -->