Chepter 5: Sass Nested
Sass: Nesting (also called Nested Rules or Selector Nesting).
I’m going to explain this like we’re pair-programming a small component together — very detailed, with real-world examples, comparisons to plain CSS and native CSS nesting (2026 reality), best practices, the famous & parent selector, common pitfalls, and when to stop nesting.
1. What is Nesting in Sass? (Super Simple First)
In plain CSS, selectors are flat and repetitive:
|
0 1 2 3 4 5 6 7 8 9 10 |
nav { ... } nav ul { ... } nav ul li { ... } nav ul li a { ... } nav ul li a:hover { ... } |
In Sass (SCSS), you can nest rules the way your HTML is nested:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
nav { ul { li { a { &:hover { ... } } } } } |
Sass compiler automatically combines the selectors:
- Outer selector + space + inner selector
- Result → same CSS as above, but you wrote it cleaner and more visually like your HTML tree.
Biggest benefit:
- Less repetition
- Easier to read/maintain
- Matches HTML structure → easier mental mapping
2. How Nesting Works – Basic Rules (2026 Sass Behavior)
Sass combines selectors with a space (descendant combinator) by default.
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// SCSS .parent { color: blue; .child { color: red; } p { font-size: 1.1rem; } } |
Compiles to:
|
0 1 2 3 4 5 6 7 8 |
.parent { color: blue; } .parent .child { color: red; } .parent p { font-size: 1.1rem; } |
3. The Star of the Show: & – The Parent Selector
& = reference to the parent selector (invented by Sass, genius!)
Without &, nesting always adds a descendant space. With &, you can:
- Add pseudo-classes (:hover, :focus)
- Add modifier classes (BEM style)
- Put selector before parent
- Concatenate directly
Classic examples:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
.btn { padding: 0.8rem 1.6rem; background: #6c5ce7; color: white; border: none; border-radius: 6px; cursor: pointer; &:hover { background: darken(#6c5ce7, 12%); } &:active { transform: scale(0.98); } &--large { padding: 1.2rem 2.4rem; font-size: 1.2rem; } &--outline { background: transparent; border: 2px solid #6c5ce7; color: #6c5ce7; &:hover { background: #6c5ce7; color: white; } } } |
Compiles to:
|
0 1 2 3 4 5 6 7 8 9 10 11 |
.btn { ... } .btn:hover { ... } .btn:active { ... } .btn--large { ... } .btn--outline { ... } .btn--outline:hover { ... } |
Magic! No repetition of .btn.
4. Real-World Example – Card Component with BEM-ish Nesting
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
.card { background: white; border-radius: 12px; box-shadow: 0 4px 20px rgba(black, 0.08); overflow: hidden; transition: transform 0.25s ease, box-shadow 0.25s ease; &:hover, &:focus-within { transform: translateY(-8px); box-shadow: 0 12px 40px rgba(black, 0.12); } &__header { padding: 1.5rem 1.5rem 0; background: linear-gradient(135deg, #667eea, #764ba2); h2 { margin: 0; color: white; font-size: 1.4rem; } } &__body { padding: 1.5rem; p { margin: 0 0 1rem; color: #4a5568; } } &__footer { padding: 1rem 1.5rem; background: #f7fafc; border-top: 1px solid #e2e8f0; .btn { margin-right: 0.75rem; } } &--featured { border: 2px solid #6c5ce7; .card__header { background: #6c5ce7; } } } |
This is very common in 2026 component libraries — clean, scoped, easy to find related styles.
5. Nesting Combinators (> + ~ etc.)
You can place combinators anywhere:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
nav { ul > li { // direct child display: inline-block; } li + li { // adjacent sibling margin-left: 1.5rem; } a { > img { // img direct child of a vertical-align: middle; } } &:hover > ul { // hover on nav shows direct ul display: block; } } |
6. 2026 Reality: Sass Nesting vs Native CSS Nesting
Native CSS nesting landed ~2023–2024 and is fully supported in 2026.
But they are NOT the same — Sass team decided not to fully match native for compatibility reasons.
Key differences:
| Feature / Behavior | Sass Nesting (2026) | Native CSS Nesting | Winner for you? |
|---|---|---|---|
| Multiple parents | .foo, .bar { .baz { } } → .foo .baz, .bar .baz | :is(.foo, .bar) .baz (lower specificity) | Sass (predictable specificity) |
| & at beginning | &–modifier { } works perfectly | Requires @nest or separate rule in some cases | Sass |
| Overly deep nesting | Allowed (but warns you) | Allowed | Tie |
| Mixing declarations after nested rules | Deprecated / breaking changes in recent Dart Sass | Wrapped in implicit @nest | Native more forgiving now |
| No build step | Requires Sass compiler | Works directly in browser | Native |
Verdict in 2026:
- Small projects / quick prototypes → native CSS nesting is fine (no build tool)
- Medium/large projects, component libraries, design systems → Sass nesting still preferred because:
- Better specificity control
- Full & flexibility (suffixes, prepending selectors)
- Richer ecosystem (mixins, maps) works seamlessly with it
- Predictable output
7. Best Practices & Warnings (Don’t Over-Nest!)
- Rule of thumb: Max 3–4 levels deep → .card .body .text p is already pushing it
- Over-nesting creates:
- High specificity → hard to override
- Heavy selectors → slower (rarely, but possible)
- Hard-to-read code
- Use BEM / utility classes + shallow nesting instead
- Use nesting for:
- Pseudo-classes (&:hover)
- Modifiers (&–active)
- Child elements in components (__title, __footer)
8. Quick Challenge – Try This!
Create style.scss:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
.menu { background: #2d3748; padding: 1rem; &__item { display: inline-block; margin-right: 1.5rem; a { color: white; text-decoration: none; &:hover, &:focus { color: #a0aec0; text-decoration: underline; } } } &--vertical { display: block; .menu__item { display: block; margin: 0.5rem 0; } } } |
Compile → play with HTML <nav class=”menu menu–vertical”> → see how clean it feels!
You’ve now got nesting down solid — one of Sass’s killer features since day one.
Next — want to combine nesting with mixins for reusable button families? Or dive into @use + nesting in modular files? Or compare with native @nest more deeply?
Just tell me — class is always in session 😊
