The @extend rule shares one selector's declarations with another by combining them at compile time, rather than duplicating declarations like a mixin would. This lesson covers @extend's syntax, its interaction with placeholders, and when it's the right (or wrong) tool.
What Does @extend Do?
@extend tells the compiler: "wherever the extended selector's declarations apply, also apply them to this selector." Instead of copying declarations into the extending selector, Sass groups the two selectors together into one combined rule in the output.
@extend .class; shares another class's declarations by grouping selectors together.
@extend %placeholder; is the most common pairing, sharing a placeholder's declarations without ever outputting the placeholder alone.
!optional suppresses the compiler error that would otherwise occur if the extended selector is never matched anywhere.
A single selector can @extend multiple other selectors or placeholders in separate statements.
@extend Cheatsheet
Common @extend patterns and their trade-offs.
Pattern
Example
Notes
Extend a class
@extend .message;
Leaves .message in the output as its own selector too
Extend a placeholder
@extend %message-base;
No standalone placeholder output, most common form
Optional extend
@extend .foo !optional;
No error if .foo is never actually used
Extend, then override
Extend + add new declarations after
Extending selector's own rule wins on conflicts
@extend vs Mixin Trade-offs
@extend produces smaller output for shared, unparameterized styles by grouping selectors instead of duplicating declarations. But it can also produce long, hard-to-read combined selectors when many unrelated rules extend the same placeholder, and it cannot accept parameters like a mixin can.
Aspect
@extend
Mixin
Compiled selector list
Can grow long with many extenders
Not applicable, no shared selector
Accepts parameters
No
Yes
Output duplication
Avoided via grouping
Occurs at every @include
Debugging clarity
Can be harder to trace in DevTools
Easier, declarations are local to the rule
A Caveat: @extend Across Media Queries
You generally cannot @extend a selector defined inside a different media query than the extending selector; Dart Sass raises a compile error in that case, since the resulting rule wouldn't make logical sense in plain CSS.
Modern Sass style guides increasingly favor mixins and placeholders used sparingly over heavy @extend chains, since long combined selector lists can be harder to debug in browser DevTools than straightforward, locally duplicated declarations from a mixin.
Common Mistakes
Extending a selector across a media query boundary, which raises a compile error in Dart Sass.
Chaining many unrelated @extends onto the same placeholder, producing an extremely long, hard-to-read combined selector in the compiled CSS.
Forgetting !optional when a placeholder or selector might legitimately never be used, causing an unnecessary compile error.
Using @extend when a mixin would actually be clearer, especially once any parameterization is needed.
Key Takeaways
@extend groups selectors together at compile time instead of duplicating declarations.
It's most commonly paired with placeholder selectors to avoid unused, standalone output.
@extend cannot cross media query boundaries and cannot accept parameters.
For anything needing parameters or variation, a mixin remains the clearer, more debuggable choice.
Pro Tip
Reserve @extend for placeholder-based, parameter-free style sharing, and default to mixins for everything else; this keeps your compiled selectors from growing unpredictably long as a project scales.
You now understand the @extend rule and how it compares to mixins. Next, move into Sass architecture, starting with organizing a real project's folder structure.