Nesting
Sass nesting lets you write child / pseudo / media-query rules inside their parent. Use the & reference for modifiers (&:hover, &.is-active). Modern CSS now has native nesting; Sass version is more permissive.
Nesting, parent reference, when to stop
EXAMPLE
/* 1) Basic nesting */
.card {
padding: 1rem;
background: white;
border-radius: 0.5rem;
h2 {
font-size: 1.25rem;
margin-bottom: 0.5rem;
}
p {
color: #475569;
}
}
/* Compiles to:
.card { padding: 1rem; ... }
.card h2 { font-size: 1.25rem; ... }
.card p { color: #475569; }
*/
/* 2) & — the parent selector reference */
.btn {
display: inline-block;
padding: 0.5rem 1rem;
&:hover { background: #f1f5f9; }
&:focus { outline: 2px solid #0ea5e9; }
&:active { transform: scale(0.98); }
&.is-active { background: #0ea5e9; color: white; }
&.is-disabled { opacity: 0.5; pointer-events: none; }
/* nested element */
.icon { width: 1em; height: 1em; }
/* BEM modifier — & joins the parent class */
&--primary { background: #0ea5e9; color: white; }
&--danger { background: #ef4444; color: white; }
}
/* Compiles to:
.btn { ... }
.btn:hover { ... }
.btn:focus { ... }
.btn.is-active { ... }
.btn .icon { ... }
.btn--primary { ... }
.btn--danger { ... }
*/
/* 3) & inside selectors — combine BEM + state */
.card {
&__title {
font-size: 1.25rem;
.card--featured & { color: #0ea5e9; } /* .card--featured .card__title */
}
}
/* 4) Nesting media queries — close to the rule they affect */
.container {
padding: 1rem;
@@media (min-width: 768px) {
padding: 1.5rem;
}
@@media (min-width: 1024px) {
padding: 2rem;
max-width: 1024px;
margin-inline: auto;
}
}
/* 5) Nesting @@supports */
.layout {
display: flex;
@@supports (display: grid) {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
}
/* 6) Don't nest too deep — readability + specificity blow up */
/* BAD */
.page {
.section {
.row {
.col {
.card {
.title { /* now specificity is .page .section .row .col .card .title */
color: red;
}
}
}
}
}
}
/* RULE OF THUMB: no more than 3 levels deep.
If you need 4, refactor to a BEM-style flat class. */
/* 7) Modern CSS has native nesting (no preprocessor needed) */
/* Supported in all current browsers. Slight syntax differences:
- Sass allows `.card h2 { }` (descendant); CSS requires `& h2 { }`
- Sass: `&--primary { }`; CSS: `&.primary { }` (no string-concat with &)
*/
/* 8) Useful idioms */
/* SVG icon recoloring */
.btn {
.icon { fill: currentColor; }
&--primary { color: white; }
}
/* Form group */
.field {
display: flex; flex-direction: column; gap: 0.25rem;
label { font-weight: 500; }
input, textarea, select {
padding: 0.5rem;
border: 1px solid #cbd5e1;
border-radius: 0.25rem;
&:focus { border-color: #0ea5e9; outline: none; box-shadow: 0 0 0 3px #bae6fd; }
&.is-error { border-color: #ef4444; }
}
}
/* 9) Trade-off — readability vs specificity
Nesting groups related rules; deep nesting bakes high specificity into your CSS,
making overrides painful. Best: nest pseudo + modifier states (1-2 levels), flatten the rest. */
Why it matters
Three-level rule of thumb: nest pseudo + modifier states (1-2 levels) and flatten the rest. Deep nesting feels readable when you write it; it’s a specificity nightmare when someone tries to override it.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
.card {
padding: 16px;
&__title { font-weight: bold; }
&:hover { background: #f5f5f5; }
}
Try it Yourself »
Exercise
Reference the parent selector.
.btn {
:hover { color: red; } }
One character.
Discussion
Loading…