CSS: nested syntax
What is CSS Nesting syntax
- CSS Nesting syntax is introduced in 2019, and widely supported in browsers since 2024.
- CSS nesting is convenient syntax to allow you nest CSS code.
- It does not do anything extra compared to non-nested syntax, but is just a syntax convenience.
CSS Nesting syntax (ai generated)
CSS Nesting Tutorial1. Basic Syntax
Instead of repeating parent selectors, you nest child rules inside the parent block using & (the nesting selector) or by directly writing the child selector.
With native CSS nesting:/* Traditional flat CSS */ .card { background-color: pink; border: solid 1px grey; } .card h2 { color: red; } .card p { color: blue; } .card:hover { box-shadow: 3px 3px 4px 2px grey; }
/* nested syntax */ .card { background-color: pink; border: solid 1px grey; h2 { color: red; } p { color: blue; } &:hover { box-shadow: 3px 3px 4px 2px grey; } }
2. The ampersand & (Nesting Selector)
The & always refers to the parent selector. It's required when you need to:
- Combine with pseudo-class (
:hover,:focus, etc.) - Combine with sibling or child combinators
- Create compound selectors
.button { padding: 12px 24px; border: none; border-radius: 6px; font-weight: 600; &:hover { background: #0056b3; } &:active { transform: scale(0.98); } &.primary { background: #007bff; color: white; } &.large { padding: 16px 32px; font-size: 1.1rem; } > span { /* direct child */ margin-left: 8px; } + .button { /* adjacent sibling */ margin-left: 12px; } }
3. Advanced Examples
Nesting Media Queries
.card { padding: 1rem; @media (min-width: 768px) { padding: 2rem; } @media (hover: hover) { &:hover { transform: translateY(-4px); } } }
Nesting with :is(), :where(), :has()
.article { color: #222; :is(h1, h2, h3) { margin: 1.5em 0 0.5em; } :has(> figure) { display: grid; gap: 1rem; } }
Complex Nesting (realistic component)
.nav { display: flex; gap: 2rem; &__item { /* BEM-style with nesting */ color: #666; text-decoration: none; &:hover, &.active { color: #007bff; border-bottom: 3px solid #007bff; } } &--vertical { flex-direction: column; gap: 1rem; } }
4. Rules and Limitations
- At-rules like
@media,@supports,@containercan be nested. - Nesting depth: Browsers support deep nesting, but for readability keep it under 4–5 levels.
- Specificity: Nested rules increase specificity naturally (parent + child). [see CSS: Specificity]
- Invalid nesting: You cannot start a nested rule with a combinator (
>,+,~) without using&.
Valid:.card { > .content { } /* ❌ */ }
.card { & > .content { } /* or just > .content in many cases */ }
5. Nesting with Custom Properties (Variables)
.theme { --accent: #007bff; .card { border-color: var(--accent); &:hover { --accent: #0056b3; /* local override */ } } }
6. Browser Support & Fallbacks
As of 2026, support is excellent:
- Chrome/Edge: 112+
- Firefox: 117+
- Safari: 17.2+
/* Base styles (always work) */ .card { background: #f8f9fa; } /* Nested styles for supporting browsers */ @supports (selector(&)) { .card { h2 { color: #333; } &:hover { box-shadow: ...; } } }
7. Best Practices
- Keep it readable — Avoid nesting deeper than 3–4 levels.
- Use
&explicitly when combining with pseudo-classes or compound selectors. - Combine with modern CSS (
:has(), container queries, cascade layers, etc.). - Maintainability — Nesting makes component styles self-contained and easier to move around.
- Tooling — PostCSS, Lightning CSS, and modern build tools can polyfill or transform nesting for older browsers if needed.
8. Real-World Example: A Complete Card Component
.card { background: white; border-radius: 12px; overflow: hidden; box-shadow: 0 2px 8px rgba(0,0,0,0.08); transition: all 0.2s ease; &:hover { box-shadow: 0 10px 25px rgba(0,0,0,0.12); transform: translateY(-4px); } &__image { width: 100%; height: 200px; object-fit: cover; } &__content { padding: 1.5rem; h3 { margin: 0 0 0.75rem; font-size: 1.25rem; } p { color: #555; line-height: 1.6; } } &__footer { padding: 1rem 1.5rem; border-top: 1px solid #eee; display: flex; justify-content: space-between; align-items: center; } }
CSS Nesting brings the power of preprocessors directly into vanilla CSS, reducing repetition and improving organization while keeping everything in one file.
Try it live: Most modern CodePen, JSFiddle, or browser dev tools already support it perfectly. Just start writing nested rules!