Skip to content

Sass - Mixin Directives

Mixins are one of Sass’s most powerful features for creating reusable blocks of styles. They allow you to define a set of CSS declarations that can be included elsewhere in your stylesheet, optionally accepting arguments for customization.

You define a mixin using the @mixin directive, followed by the mixin name and an optional argument list. The styles to be included go inside the curly braces {}.

Syntax:

// Simple mixin
@mixin mixin-name {
property1: value1;
property2: value2;
}
// Mixin with arguments
@mixin mixin-name-with-args($arg1, $arg2: default-value) {
property1: $arg1;
property2: $arg2;
// ... use arguments in declarations
}

Example: A mixin for common button styling.

@mixin button-base {
display: inline-block;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
text-align: center;
text-decoration: none;
}

Example: A mixin for creating themeable buttons with arguments.

@mixin themed-button($bg-color, $text-color: white) {
@include button-base; // Include the base styles
background-color: $bg-color;
color: $text-color;
&:hover {
background-color: darken($bg-color, 10%);
}
}

To use a mixin within a CSS rule or another mixin, you use the @include directive followed by the mixin name and any required arguments.

Syntax:

.selector {
@include mixin-name;
}
.another-selector {
// Passing arguments by order
@include mixin-name-with-args(value1, value2);
// Passing arguments by name (keyword arguments)
@include mixin-name-with-args($arg2: value2, $arg1: value1);
}

Example: Using the themed-button mixin.

.button-primary {
@include themed-button(blue);
}
.button-secondary {
@include themed-button(gray, black);
}
.button-danger {
@include themed-button($bg-color: red, $text-color: white);
}

Compiled CSS Output:

.button-primary {
display: inline-block;
padding: 10px 20px;
/* ... other base styles */
background-color: blue;
color: white;
}
.button-primary:hover {
background-color: #0000cc; /* darkened blue */
}
.button-secondary {
display: inline-block;
padding: 10px 20px;
/* ... other base styles */
background-color: gray;
color: black;
}
.button-secondary:hover {
background-color: #6b6b6b; /* darkened gray */
}
/* ... rules for .button-danger */

Mixins can accept arguments just like functions, allowing for customization:

  • Required Arguments: Must be provided when including the mixin.
  • Optional Arguments (Default Values): Have a default value specified with : (e.g., $arg: default). They don’t need to be passed when including.
  • Keyword Arguments: Arguments can be passed by name (e.g., $name: value), which allows passing them in any order and makes the include more readable.
  • Variable Arguments (...): A mixin can accept an arbitrary number of arguments using ... at the end of the argument list. These arguments are available inside the mixin as a list.

Example: Mixin with variable arguments for box-shadow.

@mixin box-shadow($shadows...) {
// $shadows is a list of all passed arguments
box-shadow: $shadows;
}
.element {
@include box-shadow(0 2px 4px rgba(0,0,0,0.1), 0 0 1px rgba(0,0,0,0.05));
}

Mixins can accept entire blocks of styles using the @content directive. When you include a mixin with a content block, the styles within that block are injected where @content appears inside the mixin definition. This is particularly useful for creating wrappers or handling media queries.

Example: A mixin for responsive styles.

@mixin respond-to($breakpoint) {
@media (min-width: $breakpoint) {
@content; // Content block styles go here
}
}
.element {
width: 100%;
@include respond-to(768px) {
// This block is passed as content
width: 50%;
float: left;
}
}

Compiled CSS Output:

.element {
width: 100%;
}
@media (min-width: 768px) {
.element {
width: 50%;
float: left;
}
}

Mixins are ideal for:

  • Reducing repetition of common style patterns.
  • Creating configurable style components via arguments.
  • Encapsulating complex CSS like vendor prefixes (though Autoprefixer is now preferred for prefixes), specific hacks, or intricate selectors.
  • Handling responsive design patterns using @content blocks.

Avoid using mixins for simple property sharing where @extend with placeholder selectors might be more appropriate (if the relationship is truly semantic inheritance), but mixins are generally safer and more flexible.