DEV Community

Akash Shyam
Akash Shyam

Posted on • Edited on

Selector Nesting Has Come to CSS 🤯🤯🤯 !!!

First we had variables and now nesting in css! It seems that the functionality we get with pre-processors like Sass and Less are slowly being introduced in CSS. It's similar to what's happening between javascript and typescript. If you have noticed, a few years ago, some of the current javascript features did not exist in javascript but were implemented in typescript.

I'm not saying this is a bad thing, it's actually great! This decreases the need for pre-proccessors which need to be compiled into CSS/Javascript

That being said, selector nesting is still in the future. No browsers support it yet, but I expect this to improve. For more information, checkout the draft.

What Really Is nesting???

To explain this effectlively, I'm going to compare two code samples.

Without Nesting
button.btn {
  color: blue;
  background: white;
  transition: .2s all ease-in;
  /* More styles for the button */
}

button.btn:hover {
  color: white;
  background: blue;
}

button.btn:focus {
   /* Add more styles */
}

button.btn-group {
  /* Some styles */ 
}

button.btn-primary {
  /* I promise, this is the last. */ 
}
Enter fullscreen mode Exit fullscreen mode

Now let me show the same code with nesting.

.btn {
  color: blue;
  background: white;
  transition: .2s all ease-in;

  &:hover {
    color: white;
    background: blue;
  }

  &:focus {
   /* Add more styles */
  }

  &-group {
    /* Some styles */ 
  }

  &-primary {
    /* You get the point right??? */ 
  }
}

Enter fullscreen mode Exit fullscreen mode

Just like in Sass, The & is used to refer to the parent selector(in this case, .btn). That's not all, we can also nest multiple levels deep.

.btn {
  color: white;
  background: cyan;

  &-container {
    margin: 10px 20px;

    &:hover {
      /* Some fancy animation */ 
    }

    & .overlay {
       /* There should always be an "&" in a nested selectors */
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

@nest

This is a new at-rule that helps us overcome some of the limitations of nesting using the &. Look at the following code:

.section {
    /* etc ... */
}

.section {
    /* etc ... */

    .blog {
        /* We want to reference the blog container which is inside the .section. */
    }
}
Enter fullscreen mode Exit fullscreen mode

For this, we can use the @nest rule. This rule shifts the reference of the & to another selector we specify.

.main {
    /* etc ... */

    .blog {
        @nest .section & {
                        /* The "&" refers to ".section" */
            background: red;
        }
    }
}

Enter fullscreen mode Exit fullscreen mode

Nesting Media Queries

For people who are familiar with Sass, the "normal" code looks like this:

.section {
  @media(/* some media query */) {
    /* styles... */
  }

}
Enter fullscreen mode Exit fullscreen mode

However, this is slightly different. In css, the styles must be enclosed in "&".

  @media(/* some media query */) {
    & {
      /* styles... */
    }
  }
Enter fullscreen mode Exit fullscreen mode
  • Normal code
.table.xyz > th.y > p.abc {
  font-size: 1rem;
  color: white;
}

.table.xyz > th.y > p.abc-primary {
  font-size: 1.4rem;
}
Enter fullscreen mode Exit fullscreen mode
  • The Power of nesting 💪 💪 💪
.table.xyz > th.y > p.abc {
  font-size: 1rem;
  color: white;

  &-primary {
    font-size: 1.4rem
  }
}
Enter fullscreen mode Exit fullscreen mode

Makes code more readable

As soon as you look the code, you can go "Aha, anything between those outer curly braces is related to buttons or .btn! Not my business!"

A gotcha

One thing to keep in mind is that any css which is after nested selectors is flat out ignored. However, any nesting that is followed is completely valid.

.x {
  &-y {
    /* styles... */
  }

  a {
    /* invalid */
  }

  &-z {
    /* valid */
  }
}
Enter fullscreen mode Exit fullscreen mode

That's it guys! Thank you for reading this post. Please give it a like and follow me on dev.to for more content based on HTML & CSS, Javascript, React and NodeJS. To my dear regular readers, I'm sorry about not writing any articles in the past few weeks, I was quite busy. Bye guys 🤟

Top comments (4)

Collapse
 
qwby profile image
Dominik Halfkann

Either there is a mistake in the @nest example code or I’m just not understanding it right. Shouldn’t .blog be inside .section? In the example code, .blog is just inside .main.

Collapse
 
akashshyam profile image
Akash Shyam

Ah thank you! I was actually tinkering around with the classes a bit and forgot to change the name of the class

Collapse
 
ogranada profile image
Andres Granada

Good article.

Please fix the sample code in the section Nesting Media Queries, I think you forgot few close quotes.

Collapse
 
akashshyam profile image
Akash Shyam

Thanks! I'll fix it right away.