@extend / Inheritance
@@extend shares a selector’s declarations across other selectors. It generates grouped selectors instead of duplicating CSS — smaller output, but with surprising selector specificity if abused.
@@extend vs @@mixin
EXAMPLE
// 1. @extend — adds the host to a placeholder selector
%card-base {
padding: 1rem;
border-radius: 8px;
background: white;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
.card { @extend %card-base; }
.user-card { @extend %card-base; border-left: 4px solid $brand; }
.invoice { @extend %card-base; padding-bottom: 1.5rem; }
// Compiles to:
// .card, .user-card, .invoice { padding: 1rem; … }
// .user-card { border-left: 4px solid #04AA6D; }
// .invoice { padding-bottom: 1.5rem; }
// 2. Compare to @mixin (duplicates declarations)
@mixin card-base {
padding: 1rem;
border-radius: 8px;
background: white;
}
.card { @include card-base; } // duplicates the rules per selector
.invoice { @include card-base; padding-bottom: 1.5rem; }
// Rule of thumb:
// • Use @extend with PLACEHOLDERS (%name) — never with real selectors
// • Use @mixin when you take arguments or content blocks
// • Never @extend across files / scopes — fragile + surprising
// Avoid this anti-pattern:
.alert { color: red; }
.error-alert { @extend .alert; } // pulls every .alert selector everywhere
Why it matters
Almost every real-world Sass codebase ends up using @@mixin by default. @@extend shines for small placeholder selectors; everywhere else it tends to confuse more than it saves.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
%button-base {
padding: 8px 16px;
border-radius: 4px;
}
.btn-primary { @extend %button-base; background: #04AA6D; }
Try it Yourself »
Exercise
Inherit another selector's rules.
.error {
.alert; }
Starts with @ex.
Discussion
Loading…