Search code examples
csscss-selectors

Native CSS nesting confusion


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.


Solution

  • 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>