In the Using CSS Nesting guide on MDN, in the example section we have the following HTML structure:
<div class="wrapper">
<article class="card">
<h2>Card 1</h2>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit.</p>
</article>
<article class="card featured">
<h2>Card 2</h2>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit.</p>
</article>
...
</div>
and CSS:
.card {
padding: 0.5rem;
border: 1px solid black;
border-radius: 0.5rem;
& h2 {
/* equivalent to `.card h2` */
color: slateblue;
.featured & {
/* equivalent to `.featured .card h2` */
color: tomato;
}
}
}
My question is about this CSS line:
/* equivalent to .featured .card h2 */
How does it work? Since in the example the .card
element is not a child of the .featured
element, but styles are still applied.
My understand is that it should be like this:
.featured.card h2
I don't understand how nesting works in this particular case when we have several layers nested and &
at the end of the selector.
The code comment line you referenced from MDN is wrong.
The &
is equivalent to :is(the-containing-selector)
so the innermost nested selector expands to
.featured :is(:is(.card) h2)
Which means "an h2
element which has an ancestor which has class card
and has an ancestor which has class featured
". They can be the same ancestor.
.featured :is(:is(.card) h2) {
color: yellow;
}
<div class="wrapper">
<article class="card">
<h2>Card 1</h2>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit.</p>
</article>
<article class="card featured">
<h2>Card 2</h2>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit.</p>
</article>
<article class="card">
<h2>Card 3</h2>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit.</p>
</article>
</div>