Episode 11 of 12
The @Content Keyword
Pass custom style blocks into mixins with @content — powerful pattern for media queries and wrappers.
The @Content Keyword
@content lets you pass a block of styles into a mixin. The mixin defines the wrapper, and @content is replaced by whatever you pass inside the @include block.
How @content Works
// Define a mixin with @content placeholder
@mixin wrapper {
.wrapper {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
@content; // ← Custom styles go here
}
}
// Use it — pass styles in the { } block:
@include wrapper {
background: #f5f7fa;
min-height: 100vh;
}
// Compiled CSS:
.wrapper {
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
background: #f5f7fa;
min-height: 100vh;
}
Media Query Mixin (Most Common Use)
@mixin mobile {
@media (max-width: 576px) {
@content;
}
}
@mixin tablet {
@media (max-width: 768px) {
@content;
}
}
@mixin desktop {
@media (min-width: 1024px) {
@content;
}
}
// Usage — clean and readable!
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
@include tablet {
grid-template-columns: repeat(2, 1fr);
}
@include mobile {
grid-template-columns: 1fr;
gap: 12px;
}
}
Flexible Breakpoint Mixin
$breakpoints: (
xs: 480px,
sm: 576px,
md: 768px,
lg: 1024px,
xl: 1200px,
);
@mixin respond-to($breakpoint) {
$value: map-get($breakpoints, $breakpoint);
@if $value {
@media (max-width: $value) {
@content;
}
} @else {
@warn "Unknown breakpoint: #{$breakpoint}";
}
}
// Usage:
.sidebar {
width: 300px;
@include respond-to(md) {
width: 200px;
}
@include respond-to(sm) {
width: 100%;
}
}
Dark Mode Mixin
@mixin dark-mode {
@media (prefers-color-scheme: dark) {
@content;
}
}
.card {
background: white;
color: #333;
border: 1px solid #eee;
@include dark-mode {
background: #1a1a2e;
color: #eee;
border-color: #2a2a3e;
}
}
Hover-Capable Mixin
@mixin hover {
@media (hover: hover) {
&:hover {
@content;
}
}
}
.card {
transition: transform 0.2s;
@include hover {
transform: translateY(-4px);
box-shadow: 0 8px 24px rgba(0,0,0,0.12);
}
}
Keyframe Wrapper
@mixin keyframes($name) {
@keyframes #{$name} {
@content;
}
}
@include keyframes(fadeIn) {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.element {
animation: fadeIn 0.3s ease;
}
Key Takeaways
@contentis a placeholder inside a mixin that gets replaced by the passed block- Perfect for media queries — write
@include mobile { ... }instead of full media queries @contentmixins are wrappers — they provide context, you provide the styles- Combine with maps and arguments for flexible breakpoint systems
- Also great for dark mode, hover detection, keyframes, and container queries