Native CSS Nesting is Here!
Learn how to use CSS nesting to write cleaner, more maintainable stylesheets.
Search all CSS Showcase pages by name
No more preprocessors needed! CSS now supports nesting natively. Write cleaner, more organised stylesheets with less repetition.
For years, we've relied on preprocessors like SASS and LESS for nesting. Now CSS has caught up! Native nesting means faster builds, simpler tooling, and one less dependency in your project.
/* So much repetition! */
.card {
background: white;
padding: 2rem;
}
.card h2 {
margin-bottom: 1rem;
}
.card p {
line-height: 1.6;
}
.card:hover {
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}
.card:hover h2 {
color: #2563eb;
}/* Clean and organised! */
.card {
background: white;
padding: 2rem;
h2 {
margin-bottom: 1rem;
}
p {
line-height: 1.6;
}
&:hover {
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
h2 {
color: #2563eb;
}
}
}See how native CSS nesting simplifies real-world component styles — from navigation bars to complex blog cards.
Resize your browser to see me change!
Learn how to use CSS nesting to write cleaner, more maintainable stylesheets.
Hover over me for a surprise!
Moving from SASS to native CSS nesting is straightforward, but there are a few key differences to keep in mind.
// SASS with variables and mixins
$primary: #2563eb;
$radius: 0.5rem;
@mixin button-style {
padding: 0.75rem 1.5rem;
border-radius: $radius;
transition: all 0.2s;
}
.form {
padding: 2rem;
&__group {
margin-bottom: 1.5rem;
label {
display: block;
margin-bottom: 0.5rem;
color: darken($primary, 20%);
}
input {
@include button-style;
border: 2px solid $primary;
&:focus {
outline: none;
border-color: lighten($primary, 10%);
}
}
}
}/* CSS with custom properties */
:root {
--primary: #2563eb;
--primary-dark: #1d4ed8;
--primary-light: #60a5fa;
--radius: 0.5rem;
}
.form {
padding: 2rem;
&__group {
margin-bottom: 1.5rem;
label {
display: block;
margin-bottom: 0.5rem;
color: var(--primary-dark);
}
input {
/* Direct styles instead of mixin */
padding: 0.75rem 1.5rem;
border-radius: var(--radius);
transition: all 0.2s;
border: 2px solid var(--primary);
&:focus {
outline: none;
border-color: var(--primary-light);
}
}
}
}Understanding these three core rules will help you avoid common pitfalls when working with native CSS nesting.
/* CSS automatically adds & */
.parent {
.child { } /* = .parent .child */
& .child { } /* = .parent .child */
div { } /* = .parent div */
& div { } /* = .parent div */
}/* Be careful with specificity */
.card {
/* This becomes .card.active */
&.active { }
/* This becomes .card .active */
.active { }
/* Multiple selectors */
h2, h3 {
margin: 0;
}
}/* Media queries and supports */
.element {
width: 100%;
@media (min-width: 768px) {
width: 50%;
}
@supports (display: grid) {
display: grid;
}
}Keep these guidelines in mind when using native CSS nesting in production.
Avoid nesting more than 3 levels deep. It makes CSS harder to read and increases specificity.
Combine BEM naming with nesting for the best of both worlds — clarity and convenience.
Modern DevTools show nested CSS properly, making debugging much easier than before.