Chepter 8: Sass @extend

1. What is @extend? (The Core Idea)

@extend tells Sass: “Make this selector behave as if it also matches that other selector.”

Instead of copying code (like @mixin does), @extend groups selectors in the compiled CSS so they share the exact same declarations.

Official one-liner from sass-lang.com (still true in Dart Sass 1.97+ in 2026):

@extend <selector> — one selector inherits the styles of another by making Sass output them together.

Key mental model:

  • @mixin / @include = copy-paste code (DRY source, but repeated in output CSS)
  • @extend = share the same rule (no duplication in output CSS, but creates selector relationships)

2. Basic Syntax & Example – No Placeholder First

SCSS

Compiled CSS output (beautifully DRY):

CSS

See? .message styles are not repeated — Sass just lists all extenders in the selector list. This keeps your gzipped CSS smaller.

3. The Real Power Tool: Placeholder Selectors % (Recommended in 2026)

Often you don’t want a base class like .message to actually exist in HTML (it’s just a style blueprint).

Enter placeholder (silent / abstract class) — starts with %:

SCSS

Compiled output:

CSS
  • No .alert-base or %alert-base appears in final CSS → perfect for “abstract base styles”
  • Very clean, very common in component libraries / design systems in 2026

4. @extend vs @mixin – Head-to-Head Comparison (2026 View)

Feature / Behavior @extend (with or without %) @mixin + @include When to choose?
Output CSS size Minimal (shared selectors) Larger (duplicates declarations) @extend wins for identical styles
Accepts arguments / parameters No Yes (required for dynamic styles) @mixin only
Can include logic/loops/if No Yes @mixin only
Cascade / specificity impact Can create unexpected high specificity Predictable (just pastes where used) @mixin safer in complex cases
Works across media queries? Limited (extend must be in same context) Full flexibility @mixin
Placeholder support Yes (%) – very clean Not needed (mixin doesn’t output unless included) @extend % for blueprints
Best for… “Is-a” relationships (Button is-a .btn-base) “Has-a” reusable chunks / parametric styles See rule below

Official Sass team rule of thumb (still valid 2026):

  • Use @extend when you’re expressing that one selector is a subtype of another (semantic / “is-a”) → .alert-dangeris an.alert
  • Use @mixin when you’re sharing a chunk of properties that aren’t necessarily related in meaning → flex-center utilities, clearfix, etc.

Many 2026 teams actually prefer mixins for almost everything because:

  • Easier to reason about cascade
  • Parameters + @content give more power
  • Avoids weird specificity surprises from chained extends

But @extend % still shines for pure DRY base styles without params (e.g., reset patterns, alert families, typography scale bases).

5. Chaining Extends (Advanced – Use Carefully)

SCSS

→ Works, but chaining too much can create very long selector lists (performance hit, hard to debug).

6. Common Gotchas & Limitations in Dart Sass (2026)

  • Only simple selectors can be extended: .class, #id, tag, :pseudo → Cannot @extend .parent .child or .btn[disabled] (Dart Sass enforces this strictly)
  • Cannot @extend from another module without careful setup (with @use + @extend selector-from-module.selector)
  • Inside media queries: extend stays inside unless identical extend exists outside
  • Avoid extending very specific/complex selectors → leads to specificity wars

7. Quick Challenge – Try This in Your Editor

SCSS

Compile → see how clean the output is!

You’ve now got @extend fully under your belt — use it wisely for semantic inheritance, fall back to mixins for everything else.

Next class — want to build a full small design system using variables + nesting + mixins + @extend % together? Or dive into modern Sass color manipulation / math functions?

Just say the word — we’re on fire! 🚀

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *