Sass @extend Rule

Beginner
11 min read
Updated: Nov 2026
5 examples
Compiled CSS

Definition and Usage

The Sass @extend rule is written @extend <selector>;. It tells Sass that one selector should inherit the styles of another.

Unlike mixins, which copy styles into the current rule, @extend updates style rules that contain the extended selector so they also include the extending selector. Write class="error--serious" in HTML and Sass styles it as though it also had class="error". Prefer mixins when you need arguments or non-semantic style chunks.

Official pattern.

Per the Sass docs: use @extend for semantic relationships (a modifier is a block). Sass merges selectors and extends everywhere the target is used, including :hover.

Resolved late.

Extends run after the rest of the stylesheet — including parent-selector nesting. @extend .error does not rewrite nested &__icon rules.

Only simple selectors.

Do not extend compounds like .message.info or descendants like .main .info. Write @extend .message, .info instead.

Syntax

SCSS
.error {
  border: 1px #f00;
  background-color: #fdd;

  &--serious {
    @extend .error;
    border-width: 3px;
  }
}

Compiled CSS shares the base rule between .error and .error--serious, then adds the modifier-only declaration separately.

Placeholders & Options

Core @extend shapes:

FormMeaning
@extend .error;Inherit styles of a class (mandatory target)
@extend .message, .info;Extend several simple selectors
%btn { … } then @extend %btn;Silent base — placeholder never ships alone
@extend %theme !optional;Do nothing if the target is missing

SCSS Examples

Each example uses @extend at compile time. Open View Compiled CSS for verified output.

Example 1 — Basic Extend

A BEM-style modifier inherits its block styles.

SCSS
.error {
  border: 1px #f00;
  background-color: #fdd;

  &--serious {
    @extend .error;
    border-width: 3px;
  }
}

How It Works

  1. Modifier extends the block with @extend .error.
  2. Sass merges selectors on the shared declarations.
  3. Extra styles stay on .error--serious alone.
  4. HTML can use class="error--serious" without also adding error.

Example 2 — Extend Everywhere

Sass also extends compound uses of the selector, like :hover.

SCSS
.error:hover {
  background-color: #fee;
}

.error--serious {
  @extend .error;
  border-width: 3px;
}

How It Works

  1. Extending .error updates every rule that uses it.
  2. .error:hover becomes a selector list with the modifier.
  3. No second hover rule is required on the modifier.
  4. Elements styled as if they also matched .error.

Example 3 — Placeholder Selectors

Share a silent base that never appears as its own class in CSS.

SCSS
%message-shared {
  border: 1px solid #ccc;
  padding: 10px;
  color: #333;
}

.message {
  @extend %message-shared;
}

.success {
  @extend %message-shared;
  border-color: green;
}

.warning {
  @extend %message-shared;
  border-color: yellow;
}

How It Works

  1. % placeholders are silent until extended.
  2. Extenders replace the placeholder in the output.
  3. Shared styles appear once as a selector list.
  4. Each class adds its own border color afterward.

Example 4 — Intelligent Unification

Sass skips incompatible selectors and interleaves complex ones carefully.

SCSS
.content nav.sidebar {
  @extend .info;
}

// Not extended: `p` is incompatible with `nav`.
p.info {
  background-color: #dee9fc;
}

.guide .info {
  border: 1px solid rgba(#000, 0.8);
  border-radius: 2px;
}

main.content .info {
  font-size: 0.8em;
}

How It Works

  1. p.info stays alone — p cannot match nav.
  2. Complex nests interleave when order in HTML is unknown.
  3. main.content avoids redundant combinations.
  4. Impossible selectors (like #main#footer) are never generated.

Example 5 — Placeholders + !optional

Extend a silent button base; ignore a missing placeholder safely.

SCSS
%btn {
  display: inline-block;
  padding: 0.5rem 1rem;
  border-radius: 4px;
}

.primary {
  @extend %btn;
  background: #036;
  color: #fff;
}

.ghost {
  @extend %btn !optional;
  border: 1px solid #036;
}

.missing-extender {
  @extend %does-not-exist !optional;
  opacity: 0.8;
}

How It Works

  1. Both buttons share %btn in one selector list.
  2. Mandatory extends error if the target is missing.
  3. !optional skips a missing %does-not-exist.
  4. Only opacity remains on the last rule.

Edge Cases & Pitfalls

Most @extend bugs are wrong targets, media boundaries, or choosing extend when a mixin fits better.

simple

Only simple selectors

@extend .message.info and @extend .main .info are disallowed. Extend each simple selector separately.

media

Stay inside the same @media

You may extend inside @media, but not across a selector defined outside that at-rule.

cascade

Order follows the extended rule

Cascade precedence comes from where the extended styles appear, not where you wrote @extend.

mixin

Need arguments? Use a mixin

Official tip: extends shine for semantic class relationships. Configurable chunks belong in @mixin.

Sass Support

@extend is a core Dart Sass at-rule. Prefer Dart Sass for modern rules (simple-selector-only extends, @use scope).

ImplementationStatus
Dart SassSupported (recommended)
LibSass / node-sassSupported (deprecated; compound extends legacy)
Ruby SassSupported (end-of-life)
BrowsersN/A — only see merged CSS selectors

Prefer Dart Sass for new projects. SCSS and indented syntax both support @extend.

Key Takeaways

  • Merge: @extend shares styles by rewriting selector lists.
  • Placeholders (%) are silent bases meant only to be extended.
  • Semantic relationships fit extend; configurable chunks fit mixins.
  • Simple selectors only; use !optional when a miss is OK.

One line: @extend says “this selector is also that one” and rewrites the CSS accordingly.

Compile Notes

@extend never reaches the browser. Conceptual flow:

flow.txt
1. Compile nesting and the rest of the stylesheet
2. Collect @extend relationships
3. Unify selectors (skip impossibles, interleave safely)
4. Rewrite rules that contain the extended selector
5. Emit CSS — placeholders without extenders are dropped

Frequently Asked Questions

It tells Sass that one selector should inherit the styles of another. Sass updates style rules that contain the extended selector so they also include the extending selector.
Mixins copy styles into the current rule. @extend merges selectors so shared styles appear once with a selector list. Use extends for semantic relationships; use mixins for configurable style chunks.
A selector that starts with % (like %message-shared). Rules that only use placeholders are omitted from CSS until something @extends them.
Normally @extend errors if the target selector is missing. Add !optional to silently do nothing when the extended selector does not exist.
No in modern Dart Sass. Only simple selectors can be extended. Write @extend .message, .info instead of @extend .message.info.
Yes, but you can only extend selectors defined inside the same at-rule. Extending a selector that appears outside the @media is an error.

Next: Sass @error Rule

Stop compilation with a clear message when API arguments are wrong.

Sass @error Rule →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

8 people found this page helpful