Introduction
CSS nesting allows you to write child selectors inside parent rule blocks — just like Sass, but natively in the browser. This reduces repetition and groups related rules visually.
For years, nesting was the top reason for CSS preprocessors. Now it's built into CSS — organized styles without any build step.
The syntax is straightforward, but there are important differences from Sass nesting you should understand.
Key Concepts
Basic Nesting
.card {
padding: 1.5rem;
border-radius: 0.75rem;
.card__title {
font-size: 1.25rem;
font-weight: 600;
}
.card__body {
margin-top: 0.75rem;
}
}
Nesting with &
.button {
background: var(--color-primary);
&:hover { background: var(--color-primary-dark); }
&:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
&.button--large { padding: 1rem 2rem; }
}
Nesting Media Queries
.grid {
display: grid;
grid-template-columns: 1fr;
@media (min-width: 768px) { grid-template-columns: repeat(2, 1fr); }
@media (min-width: 1024px) { grid-template-columns: repeat(3, 1fr); }
}
Practical Examples
1. Navigation Component
.nav {
display: flex;
align-items: center;
gap: 2rem;
.nav__link {
text-decoration: none;
&:hover { color: var(--color-primary); }
&.active { font-weight: 600; }
}
@media (max-width: 768px) { flex-direction: column; }
}
2. Form Styles
.form-field {
display: flex;
flex-direction: column;
gap: 0.25rem;
label { font-weight: 500; }
input {
padding: 0.5rem 0.75rem;
border: 1px solid var(--border);
&:focus { border-color: var(--color-primary); outline: none; }
}
}
3. Combining with :has()
.card {
padding: 1.5rem;
&:has(img) {
padding: 0;
img { border-radius: 0.75rem 0.75rem 0 0; }
}
}
Best Practices
- Keep nesting shallow — 2-3 levels max.
- Use & for pseudo-classes, pseudo-elements, and compound selectors.
- Nest media queries to co-locate responsive behavior.
- Don't nest just because you can — flat selectors are fine for unrelated styles.
- Use nesting to group component styles for readability.
Common Pitfalls
- Deep nesting creates highly specific selectors hard to override.
- You can't concatenate strings like &__modifier (unlike Sass).
- Nested rules increase specificity same as the flattened selector.
- Element selectors may need & in some contexts in older syntax.
Browser Support
Chrome 120+, Safari 17.2+, Firefox 117+, Edge 120+. ~88% support as of 2025.
Related Guides
- CSS Cascade Layers — combine @layer with nesting
- CSS :has() Selector — powerful with nested styles
- CSS Custom Properties — use variables inside nested blocks