iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

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…