Skip to content

Sass Placeholder Selectors — Silent Extend-Only Classes

DodaTech Updated 2026-06-28 5 min read

In this tutorial, you will learn about Sass Placeholder Selectors. We cover key concepts, practical examples, and best practices to help you master this topic.

Sass placeholder selectors use % prefix to create classes that exist only for @extend, producing no CSS output unless explicitly extended by another selector.

What You'll Learn

You will learn how to define and use placeholder selectors, understand their output benefits, combine them with mixins, and build extendable pattern libraries.

Why It Matters

Placeholders avoid unused CSS. DodaTech's component library uses placeholders for all base patterns so the compiled CSS only includes what is actually used.

Real-World Use

Durga Antivirus Pro's design system defines button, card, and form base patterns as placeholders. Components that @extend them produce only the needed output.

flowchart LR
    A[@extend] --> B[Placeholders]
    B --> C[% Selectors]
    B --> D[No Output]
    B --> E[Library Use]
    B --> F[Patterns]
    style B fill:#c69,stroke:#c69,color:#fff
    style C fill:#22c55e,stroke:#16a34a,color:#fff

Placeholder Basics

// Define a placeholder (no CSS output)
%button-base {
  display: inline-block;
  padding: 0.5rem 1rem;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 1rem;
}

// Extend the placeholder
.btn-primary {
  @extend %button-base;
  background: #7c3aed;
  color: white;
}

.btn-danger {
  @extend %button-base;
  background: #ef4444;
  color: white;
}

Compiles to:

.btn-primary, .btn-danger {
  display: inline-block;
  padding: 0.5rem 1rem;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 1rem;
}

.btn-primary { background: #7c3aed; color: white; }
.btn-danger { background: #ef4444; color: white; }

Expected output: No .button-base class in the compiled CSS. Only the extending classes exist.

Placeholders vs Regular Classes

// Regular class — always outputs
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

// Placeholder — only outputs if extended
%sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

// If nothing extends %sr-only, it produces zero CSS

Expected output: The regular class always appears. The placeholder only appears if extended.

Placeholder Library Pattern

// _placeholders.scss
%clearfix {
  &::after {
    content: "";
    display: table;
    clear: both;
  }
}

%text-truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

%flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}

%visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  border: 0;
}
// main.scss
@import "placeholders";

.card-header {
  @extend %clearfix;
}

.ellipsis-text {
  @extend %text-truncate;
}

.icon-wrapper {
  @extend %flex-center;
}

Expected output: Only the three required patterns appear in the compiled CSS, not the entire placeholder library.

Placeholder with Mixins

// Mixin that extends a placeholder
@mixin button-variant($bg, $color) {
  @extend %button-base;
  background: $bg;
  color: $color;
}

%button-base {
  display: inline-block;
  padding: 0.5rem 1rem;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.btn-primary { @include button-variant(#7c3aed, white); }
.btn-success { @include button-variant(#10b981, white); }

Expected output: Both buttons share the base styles from the placeholder, with unique backgrounds from the mixin.

Placeholder for Responsive Patterns

%container {
  width: 100%;
  margin: 0 auto;
  padding: 0 1rem;

  @media (min-width: 768px) { max-width: 720px; }
  @media (min-width: 992px) { max-width: 960px; }
  @media (min-width: 1200px) { max-width: 1140px; }
}

.main-content {
  @extend %container;
}

.sidebar {
  @extend %container;
}

Expected output: Both .main-content and .sidebar share the responsive container pattern.

Placeholder Nesting

%card {
  background: white;
  border-radius: 8px;
  overflow: hidden;

  %card-body {
    padding: 1rem;
  }

  %card-header {
    padding: 1rem;
    background: #f8fafc;
    border-bottom: 1px solid #e2e8f0;
  }
}

.user-card {
  @extend %card;

  .body { @extend %card-body; }
  .head { @extend %card-header; }
}

Expected output: Nested placeholders are scoped to the parent placeholder context.

Common Mistakes

1. Extending Placeholders From Different Files

Placeholders defined in one file must be @imported or @used before @extend. Order matters.

2. Using Placeholder Names That Conflict

Placeholder names use the same namespace as classes. A %button and .button cannot coexist in the same scope.

3. Forgetting That Placeholders Are Global

Placeholders are globally accessible regardless of where they are defined. Use namespaced names.

4. Extending Placeholders Inside Media Queries

Defining a placeholder inside a media query and extending it outside causes errors.

5. Overusing Placeholders for Everything

Use placeholders only for patterns that are extended multiple times. Single-use patterns do not benefit.

Practice Questions

  1. What prefix identifies a placeholder selector? The % prefix, like %button-base { ... }.

  2. Does a placeholder appear in compiled CSS if not extended? No. Placeholders produce no CSS output unless extended.

  3. Why are placeholders useful for libraries? Libraries can define many patterns as placeholders. Only the patterns actually used produce CSS output.

  4. Can placeholders be nested? Yes. Placeholders can be nested inside other placeholders.

  5. Can a mixin extend a placeholder? Yes. Mixins can include @extend directives for placeholders.

Challenge

Build a utility placeholder library with 10 common patterns (clearfix, truncate, flex-center, visually-hidden, container, card-base, button-base, input-base, list-reset, transition). Write a test page that uses 6 of them and verify unused placeholders do not appear in CSS.

FAQ

Are placeholders specific to Sass?

Yes. Placeholders (the % prefix) are a Sass-specific feature not available in native CSS.

Can I use placeholders with @use modular system?

Yes. Placeholders work with @use. Use @forward to re-export placeholders from a module.

Do placeholders increase compile time?

Marginally. The @extend mechanism does require extra processing, but it is negligible for reasonable numbers.

Can I extend a placeholder from a third-party library?

Yes, if the library exports placeholders. Check the library documentation for available placeholders.

Should I use placeholders or CSS custom properties?

Placeholders are for compile-time patterns. CSS custom properties are for runtime values. They serve different purposes.

Mini Project

Create a utility-first "functional CSS" library using placeholders. Define placeholders for common patterns (text alignment, display values, spacing, colors). Consumers @extend what they need. Verify the compiled CSS only includes used utilities.

What's Next

Learn Sass Control Directives for conditional logic with @if, @else if, @else. Then explore Sass Loops for iteration.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro