Sass Mixins & Functions
Mixins and functions are Sass's two tools for avoiding repetition, and they solve related but distinct problems: a mixin produces a reusable block of CSS declarations, while a function computes and returns a single value that you then use somewhere else in a declaration.
@mixin and @include
@mixin and a name, optionally with parameters, and then pulled into a selector with @include. Everything inside the mixin body is copied into wherever it's included.// A mixin with parameters and a default value
@mixin flex-center($direction: row) {
display: flex;
align-items: center;
justify-content: center;
flex-direction: $direction;
}
.hero {
@include flex-center;
min-height: 60vh;
}
.button-group {
@include flex-center(column);
gap: 0.5rem;
}compiles to:
.hero {
display: flex;
align-items: center;
justify-content: center;
flex-direction: row;
min-height: 60vh;
}
.button-group {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
gap: 0.5rem;
}Notice that every selector that includes the mixin gets its own full copy of those declarations in the compiled CSS — a mixin duplicates output, it doesn't share a single rule the way a plain class does.
Mixins with a content block
@content, which is especially handy for wrapping a media query:@mixin respond-above($breakpoint) {
@media (min-width: $breakpoint) {
@content;
}
}
.sidebar {
width: 100%;
@include respond-above(768px) {
width: 260px;
}
}@function
@function, always ends with @return, and computes a single value rather than a block of declarations. It's called like any built-in Sass function, wherever a value is expected.@function rem($px, $base: 16px) {
@return ($px / $base) * 1rem;
}
.title {
font-size: rem(24px); // => 1.5rem
margin-bottom: rem(32px); // => 2rem
}compiles to:
.title {
font-size: 1.5rem;
margin-bottom: 2rem;
}Mixins vs. functions
@mixin | @function | |
|---|---|---|
Produces | A block of CSS declarations (or nested rules). | A single Sass value (number, color, string, list). |
Invoked with |
| Called directly as a value, e.g. |
Typical use | Reusable patterns — flex centering, media query wrapping, resets. | Computed values — unit conversion, color math, spacing scales. |
Can output nested selectors / at-rules | Yes | No — must return a single value |
A worked flex-centering example
@mixin flex-center($gap: 0) {
display: flex;
align-items: center;
justify-content: center;
@if $gap != 0 {
gap: $gap;
}
}
@function contrast-text($bg) {
@return if(lightness($bg) > 60%, #111111, #ffffff);
}
.badge {
@include flex-center(0.25rem);
background: #0066cc;
color: contrast-text(#0066cc);
padding: 0.25rem 0.75rem;
border-radius: 999px;
}sass:math), color manipulation (sass:color), strings, lists, and maps — reach for those before writing your own function for common operations like darkening a color or rounding a number.A mixin is for reusable declarations — think of it as a copy-paste macro for CSS.
A function is for reusable computations — think of it as a helper that returns one value.
@contentlets a mixin accept a caller-supplied block, most commonly for wrapping media queries.