Breakpoint Mixins
Hand-written `@media` queries scatter the same magic numbers everywhere. The SCSS pattern: store breakpoints in a map, write a `respond-to` mixin that resolves names to widths, and let designers rename a breakpoint in one place. Bonus: the mixin can error on typos, which a raw `@media` never will.
A breakpoint map plus a respond-to mixin
EXAMPLE
// _breakpoints.scss
$breakpoints: (
'xs': 0,
'sm': 480px,
'md': 768px,
'lg': 1024px,
'xl': 1280px,
'2xl': 1536px,
);
// Mobile-first: 'respond-to(md)' means '≥ 768px'
@mixin respond-to($name) {
@if not map-has-key($breakpoints, $name) {
@error 'Unknown breakpoint "#{$name}". Known: #{map-keys($breakpoints)}.';
}
$min: map-get($breakpoints, $name);
@if $min == 0 {
@content; // 'xs' is just the base styles
} @else {
@media (min-width: #{$min}) { @content; }
}
}
// Range query: 'respond-between(sm, lg)'
@mixin respond-between($from, $to) {
$min: map-get($breakpoints, $from);
$max: map-get($breakpoints, $to) - 1px;
@media (min-width: #{$min}) and (max-width: #{$max}) { @content; }
}
// Down query: 'respond-below(md)' = '< 768px'
@mixin respond-below($name) {
$max: map-get($breakpoints, $name) - 1px;
@media (max-width: #{$max}) { @content; }
}
// ---- usage ----
.card {
padding: 1rem;
display: grid;
grid-template-columns: 1fr;
@include respond-to('md') {
padding: 1.5rem;
grid-template-columns: 200px 1fr;
}
@include respond-to('xl') {
padding: 2rem;
grid-template-columns: 240px 1fr 320px;
}
}
.hide-on-mobile { @include respond-below('md') { display: none; } }
.only-tablet { @include respond-between('md', 'lg') { outline: 2px solid orange; } }
// Loop variant: generate utility classes
@each $name, $min in $breakpoints {
@include respond-to($name) {
.#{$name}\:hidden { display: none; }
.#{$name}\:flex { display: flex; }
}
}
Why it matters
Stay mobile-first (min-width queries only) inside a component to avoid stacking-context surprises and specificity wars. Reach for respond-below or respond-between only when a visual concept genuinely only exists at small or mid widths — most layout problems do not need them.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
@mixin md { @media (min-width: 768px) { @content; } }
.card { padding: 8px; @include md { padding: 24px; } }
Try it Yourself »
Discussion
Loading…