Skip to content

The @include Rule

The @include rule is how you apply a mixin wherever you need its declarations. This lesson covers every form @include can take: no arguments, positional arguments, named arguments, and passing a content block.

What Does @include Do?

@include inserts a mixin's declarations at the point where it's called. If the mixin accepts parameters, you pass matching arguments; if the mixin uses @content, you can also pass a block of additional styles for it to wrap.

@mixin button-variant($bg, $color: white) {
  background: $bg;
  color: $color;
}

.btn-primary {
  @include button-variant(#2563eb);
}

.btn-warning {
  @include button-variant($bg: #f59e0b, $color: #1f2937);
}

.btn-primary uses a positional argument and the default $color; .btn-warning uses named arguments to set both explicitly.

@include Syntax Forms

@include name;
@include name(arg1, arg2);
@include name($param: value);
@include name {
  // content block
}
  • @include name; applies a parameterless mixin.
  • @include name(arg1, arg2); passes positional arguments in order.
  • @include name($param: value); passes named arguments, order doesn't matter.
  • @include name { ... } passes a content block that fills in the mixin's @content.

@include Rule Cheatsheet

The different ways to call a mixin, from simplest to most flexible.

Form Example When to Use
No arguments @include clearfix; Mixin needs no configuration
Positional args @include button-variant(#2563eb); Short, common calls
Named args @include button-variant($color: white); Clarity, or skipping earlier optional params
Mixed args @include button-variant(#2563eb, $color: #fff); Combine positional and named
Content block @include respond-to(768px) { ... } Mixin wraps caller-provided styles
Module-qualified @include mixins.button-variant(...); Mixin loaded from a namespaced module

Positional vs Named Arguments

Positional arguments must be passed in the exact order the mixin defines its parameters. Named arguments (using $param: value syntax at the call site) can be passed in any order and make the call site self-documenting, especially useful when a mixin has several optional parameters.

@mixin card($padding: 1rem, $radius: 8px, $shadow: true) {
  padding: $padding;
  border-radius: $radius;

  @if $shadow {
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
  }
}

.card {
  @include card($radius: 16px, $shadow: false);
}

Named arguments let you skip $padding entirely and jump straight to overriding $radius and $shadow.

Including Mixins From Modules

When a mixin comes from a file loaded with @use, you call it with the module's namespace prefix, exactly like accessing a namespaced variable or function.

@use 'mixins';

.card {
  @include mixins.card($radius: 12px);
}

Passing a Content Block

When a mixin definition contains @content, the @include call can attach a block of styles in curly braces, those styles get inserted exactly where @content appears inside the mixin.

@mixin dark-mode {
  @media (prefers-color-scheme: dark) {
    @content;
  }
}

body {
  @include dark-mode {
    background: #0f172a;
    color: #f1f5f9;
  }
}

Common Mistakes

  • Mixing positional and named arguments incorrectly, positional arguments must always come before named ones in the same call.
  • Forgetting the namespace prefix when including a mixin loaded from a module with @use.
  • Trying to pass a content block to a mixin that never uses @content in its definition; the block is simply ignored, a common source of confusion.
  • Passing too many positional arguments to a mixin with a fixed parameter list, causing a compile error.

Key Takeaways

  • @include applies a mixin's declarations, optionally passing positional or named arguments.
  • Named arguments improve readability and let you skip earlier optional parameters.
  • Mixins loaded via @use are called with their module namespace prefix.
  • A content block passed to @include fills in the mixin's @content placeholder.

Pro Tip

Once a mixin has more than two parameters, prefer named arguments at the call site even if positional would technically work, it makes the intent of each value immediately clear to anyone reading the code later.