Sass Mixin Content — Passing Style Blocks with @content
In this tutorial, you will learn about Sass Mixin Content. We cover key concepts, practical examples, and best practices to help you master this topic.
Sass @content directive allows mixins to accept and output style blocks passed during @include, enabling powerful wrapper patterns for media queries, themes, and state variations.
What You'll Learn
You will learn how to use @content to pass style blocks into mixins, create media query wrappers, build theme variants, and chain content blocks.
Why It Matters
@content enables clean responsive patterns. DodaTech uses @content for all breakpoint mixins, theme variants, and state-based style wrappers.
Real-World Use
Durga Antivirus Pro uses a on-theme mixin with @content to wrap styles that should only apply in dark or light mode, keeping theme-related code organized.
flowchart LR
A[Mixin Arguments] --> B[Content Blocks]
B --> C[@content Directive]
B --> D[Media Queries]
B --> E[Theme Wrappers]
B --> F[Chaining]
style B fill:#c69,stroke:#c69,color:#fff
style D fill:#22c55e,stroke:#16a34a,color:#fff
Basic @content
@mixin respond-to($breakpoint) {
@if $breakpoint == "mobile" {
@media (max-width: 767px) {
@content;
}
} @else if $breakpoint == "tablet" {
@media (min-width: 768px) {
@content;
}
} @else if $breakpoint == "desktop" {
@media (min-width: 1024px) {
@content;
}
}
}
.sidebar {
width: 300px;
@include respond-to("mobile") {
width: 100%;
display: none;
}
}
Expected output: The sidebar is 300px on tablet/desktop, full width and hidden on mobile.
Media Query Wrapper
@mixin mobile-only {
@media (max-width: 767px) {
@content;
}
}
@mixin tablet-up {
@media (min-width: 768px) {
@content;
}
}
@mixin desktop-up {
@media (min-width: 1024px) {
@content;
}
}
.nav {
display: flex;
@include mobile-only {
flex-direction: column;
}
@include desktop-up {
gap: 2rem;
}
}
Expected output: A navigation that is column on mobile and spaced on desktop.
Theme Wrapper
$theme: "dark";
@mixin when-dark {
@if $theme == "dark" {
@content;
}
}
@mixin when-light {
@if $theme != "dark" {
@content;
}
}
.card {
background: white;
color: #333;
@include when-dark {
background: #1e293b;
color: #e2e8f0;
}
}
Expected output: When $theme is dark, the card uses dark colors. Otherwise it uses light colors.
State Wrappers
@mixin if-supported {
@supports (display: grid) {
@content;
}
}
@mixin if-not-supported {
@supports not (display: grid) {
@content;
}
}
.gallery {
display: flex;
flex-wrap: wrap;
@include if-supported {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
}
Expected output: Galleries use Flexbox fallback and grid where supported.
Chaining Content Blocks
@mixin tablet-up {
@media (min-width: 768px) {
@content;
}
}
@mixin landscape {
@media (orientation: landscape) {
@content;
}
}
.sidebar {
@include tablet-up {
width: 250px;
@include landscape {
width: 300px;
}
}
}
Expected output: The sidebar is 250px on tablet, 300px on tablet in landscape orientation.
Multiple @content Calls
@mixin hover-active {
&:hover {
@content;
}
&:active {
@content;
}
}
.button {
background: #7c3aed;
@include hover-active {
background: #6d28d9;
}
}
Expected output: The @content blocks are output for both hover and active states.
Passing Arguments to Content
@mixin with-context($property, $value) {
@media ($property: $value) {
@content;
}
}
.card {
@include with-context(min-width, 768px) {
display: grid;
grid-template-columns: 1fr 1fr;
}
}
Expected output: A media query wrapping the passed style block, using mixin arguments and @content together.
Common Mistakes
1. Multiple @content in One Mixin
Each @content use outputs the same block. For different blocks per state, use separate mixins or parameters.
2. @content Without Include Block
If no block is passed during @include, @content outputs nothing. That is fine.
3. Nested @content Confusion
When chaining mixins with @content, understand which @content refers to which block.
4. Performance of @content
@content itself has no performance cost. The compiled CSS is the same as writing the block directly.
5. Over-Abstracting @content
If a mixin only contains @content, use the block directly instead of the mixin wrapper.
Practice Questions
What does @content do inside a mixin? It outputs the style block passed during @include.
How do you pass a style block to a mixin? Include the block with curly braces after @include:
@include mixin { /* styles */ }.Can a mixin use @content multiple times? Yes. Each @content reference outputs the passed block at that location.
Can @content access variables from the calling scope? Yes. The passed block has access to variables in the scope where @include is called.
What is a common use case for @content? Media query wrappers, theme conditionals, and @supports feature detection.
Challenge
Create a responsive mixin that accepts a breakpoint name (sm, md, lg) and uses @content to output the passed styles inside the appropriate media query. Use it to make a card component responsive.
FAQ
Mini Project
Build a responsive grid system using @content mixins. Create mixins for sm, md, lg, and xl breakpoints. Write a page layout with a header, sidebar, main content, and footer that uses these mixins to adjust the layout at each breakpoint.
What's Next
Learn Sass Functions for computed values. Then explore Built-in Functions for Sass's standard library.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro