You can use nesting selectors natively in CSS now
About a 5 minute read
Written by Kyle Hawk on May 3, 2024
Updated on Oct 11, 2024
#css
What a time to be alive. It’s crazy how far CSS has come since I graduated college back in 2015.
As of December 2023, modern browsers now support the & nesting selector. This means you can nest selectors natively in CSS without having to use a preprocessor like Sass or Less. That’s pretty freakin’ cool if you ask me.
When I was first learning CSS back in the day, I was drawn to Sass for four main reasons: variables, nesting, modules and mixins. Fast forward to today, two out of the four of those points are now available natively. Variables are possible using CSS custom properties and now nesting is possible using the & nesting selector.
What’s it look like?
.parent {
/* cool parent styling */
& .child {
/* awesome child styling */
}
}
Cool, right? This will be parsed by the browser as the following:
.parent {
/* cool parent styling */
}
.parent .child {
/* awesome child styling */
}
This also works with pseudo elements, but you have to be careful. Take the following:
.parent {
/* cool parent styling */
:hover {
/* hover stuffs */
}
}
Might not render how you expect! This is saying to attach :hover
to every child element using the *
selector, like as follows:
.parent {
/* cool parent styling */
}
.parent *:hover {
/* hover stuffs */
}
If your intent was to attach :hover
to the .parent
, then you need to remember to add the &
.
.parent {
/* cool parent styling */
&:hover {
/* hover stuffs */
}
}
This will render the expected:
.parent {
/* cool parent styling */
}
.parent:hover {
/* hover stuffs */
}
There’s some more wacky things you can do with this new selector that you can read about over on Mozilla’s developer site. For instance, you can append the &
and it reverses the rules, meaning the nested item becomes the parent. Crazy, right? What’s wackier, is you can stack them.
.item {
/* item styling */
.featured & {
/* featured item styling */
}
}
.item {
.featured & & & {
/* you can do this but why styling */
}
}
Want to take a gander how that renders?
.item {
/* item styling */
}
.featured .item {
/* featured item styling */
}
.featured .item .item .item {
/* you can do this but why styling */
}
Going forward
The browser support is good-ish. Meaning if you are lucky enough, you can use it. If not, then you probably need to wait just a little bit longer or continue using a preprocessor.
This is a cool and powerful feature that’s now available natively. Depending on the project, I’ll probably continue using Sass. I can use CSS custom properties within Sass, as well as it’s other benefits.
If the project uses native CSS, you better believe I’m going to be using this new feature! Well, if browser support allows it.
Thanks for reading.