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. */
}
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??? */
}
}
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 */
}
}
}
@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. */
}
}
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;
}
}
}
Nesting Media Queries
For people who are familiar with Sass, the "normal" code looks like this:
.section {
@media(/* some media query */) {
/* styles... */
}
}
However, this is slightly different. In css, the styles must be enclosed in "&".
@media(/* some media query */) {
& {
/* styles... */
}
}
- Normal code
.table.xyz > th.y > p.abc {
font-size: 1rem;
color: white;
}
.table.xyz > th.y > p.abc-primary {
font-size: 1.4rem;
}
- The Power of nesting 💪 💪 💪
.table.xyz > th.y > p.abc {
font-size: 1rem;
color: white;
&-primary {
font-size: 1.4rem
}
}
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 */
}
}
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)
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.
Ah thank you! I was actually tinkering around with the classes a bit and forgot to change the name of the class
Good article.
Please fix the sample code in the section
Nesting Media Queries
, I think you forgot few close quotes.Thanks! I'll fix it right away.