HuntExams Academy logo
HTML/CSSAdvanced#css#sass

What is the difference between a Sass mixin and a placeholder/extend?

Answer

@mixin with @include duplicates the CSS rules into every place it's used, giving flexibility with arguments. @extend with a %placeholder groups all selectors sharing the styles under one rule in the output, reducing file size but coupling unrelated selectors together.

Example

%button-base { padding: 10px; border-radius: 4px; }
.btn-primary { @extend %button-base; background: blue; }
.btn-secondary { @extend %button-base; background: gray; }

@mixin shadow($x, $y) { box-shadow: $x $y 4px rgba(0,0,0,0.2); }
.card { @include shadow(2px, 2px); }

Detailed explanation

A Sass mixin and a placeholder used with @extend both reuse styling, but they do so at different levels. A mixin reuses declarations or other Sass-generated output at the inclusion site; @extend changes selectors so that existing rules also match the extending selector. Both are compile-time features: the browser receives ordinary CSS, not mixins, placeholders, or extension instructions. The important distinction is declaration reuse versus selector sharing.

Define a mixin with @mixin and invoke it with @include. For example, @mixin shadow($x, $y) { box-shadow: $x $y 4px rgba(0,0,0,0.2); } lets .card include shadow(2px, 2px). Sass emits the resulting declaration inside .card. Each inclusion emits its own output, even when arguments are identical. Mixins support arguments, defaults, control flow, and content blocks, making them suitable for configurable styles. Their output appears where they are included, which makes cascade reasoning relatively local and predictable.

A placeholder such as %button-base { padding: 10px; border-radius: 4px; } is not emitted on its own. When .btn-primary and .btn-secondary extend it, the simple output is .btn-primary, .btn-secondary { padding: 10px; border-radius: 4px; }, followed by their separate background rules. Under the hood, @extend performs selector unification rather than copying declarations. It can affect multiple rules containing the extended selector, including compound or contextual selectors. Placeholders are not mandatory for @extend, but they provide dedicated, non-emitted extension targets rather than tying reuse to a concrete class.

Choose mixins for parameterised styling and independent components; consider placeholders when selectors intentionally share a stable styling relationship. Extension can avoid repeated declarations, but it does not guarantee smaller output: complex selector relationships can generate large selector lists, and compression changes the size trade-off. Shared declarations remain at the original rule's position, not the @extend location, so source order matters. Extension also has scope restrictions, including restrictions across media-query contexts. Interviewers usually expect you to explain the compiled CSS and these maintenance trade-offs, rather than simply claim that one approach is always better.

Key points to remember

  • @include emits a mixin's generated output at each inclusion site.
  • Mixins accept arguments and content blocks; placeholders cannot be parameterised directly.
  • @extend rewrites selector lists instead of copying declarations into the extending rule.
  • An unused %placeholder produces no CSS; an extended placeholder supplies shared rules.
  • Extension can reduce declaration repetition but introduces selector coupling and source-order considerations.

Common mistakes candidates make

  • Saying @extend always produces smaller CSS, ignoring selector expansion and compression.
  • Assuming extended declarations appear where @extend is written rather than at the original rule's location.
  • Extending unrelated components just because they currently share a few declarations.

Likely follow-up questions

Can @extend target a normal class instead of a placeholder?

Yes, a simple class selector can be extended. Unlike a placeholder, that class can appear in the generated CSS even without an extension, so a placeholder is useful for a dedicated reuse target.

Can you extend a placeholder defined outside a media query from inside that media query?

No, Sass does not allow that cross-context extension because it cannot apply the extension only under the media condition while preserving the outside rule. Include a mixin inside the media query instead, or define and extend the placeholder within the same media context.

Does @extend copy the target selector's specificity?

No, specificity is calculated by the browser for each generated selector; it is not transferred from an extension target. Inspect the compiled CSS, especially when contextual selectors are involved, because both generated selector structure and source order determine the cascade.

Interview tip: Show the compiled CSS for the button example, contrast it with repeated mixin output, and finish with when you would choose each approach.

Related Interview Questions

1
HTML/CSSBeginner#css#tailwind

What is Tailwind CSS and how does it differ from writing custom CSS?

Open
2
HTML/CSSIntermediate#css#tailwind

How do you customize and extend Tailwind's default theme?

Open
3
HTML/CSSBeginner#css#tailwind

What are Tailwind's responsive and state variant prefixes?

Open