A Responsive Mixin Library

Build a small, ergonomic set of breakpoint mixins — min-width, max-width and between — from one map.

Every serious project ends up needing responsive helpers. Rather than scatter raw @media queries, centralise breakpoints in one map and expose a handful of @content mixins. Change a breakpoint once and the whole codebase follows.

The core mixin

@use 'sass:map';
$bp: ('md': 768px);
@mixin up($name) {
  @media (min-width: map.get($bp, $name)) { @content; }
}
.nav { display: none; @include up('md') { display: flex; } }

What a good library provides

  • up($name) — mobile-first, min-width. Your default.
  • down($name) — max-width, using the breakpoint minus 0.02px to avoid overlap.
  • between($a, $b) — a bounded range.
  • An @error guard so a typo'd breakpoint name fails the build.

Mobile-first (up) should be the habit: start with the small-screen styles unconditionally, then layer enhancements at each breakpoint.

Example

Example · css
@use 'sass:map';

$breakpoints: (
  'sm': 480px,
  'md': 768px,
  'lg': 1024px,
  'xl': 1280px,
);

@function _bp($name) {
  @if not map.has-key($breakpoints, $name) {
    @error 'No breakpoint "#{$name}". Known: #{map.keys($breakpoints)}.';
  }
  @return map.get($breakpoints, $name);
}

@mixin up($name) {
  @media (min-width: _bp($name)) { @content; }
}
@mixin down($name) {
  @media (max-width: _bp($name) - 0.02px) { @content; }
}
@mixin between($min, $max) {
  @media (min-width: _bp($min)) and (max-width: _bp($max) - 0.02px) {
    @content;
  }
}

.sidebar {
  display: none;                    // mobile-first base
  @include up('lg')   { display: block; }
}
.promo {
  @include between('md', 'lg') { flex-direction: row; }
}

When to use it

  • A team replaces ad-hoc media queries scattered across 50 component files with a small mixin library (bp.up, bp.down, bp.between) backed by one breakpoint map.
  • A developer uses a between() mixin to target only tablets (768px–1024px) for a sidebar layout without writing the verbose two-condition media query by hand.
  • A component library ships its breakpoint map as a !default variable so consumer projects can add or rename breakpoints without touching the mixin source.

More examples

Breakpoint map and up() mixin

A breakpoint map backed by !default drives an up() mixin that wraps any @content block in the correct min-width query.

Example · css
@use 'sass:map';

$bps: (xs: 0, sm: 640px, md: 768px, lg: 1024px, xl: 1280px) !default;

@mixin up($bp) {
  @media (min-width: map.get($bps, $bp)) { @content; }
}

.sidebar {
  display: none;
  @include up(md) { display: block; width: 260px; }
}

down() and between() mixins

Adds a max-width down() mixin and a min-and-max between() mixin, completing a three-function responsive API from one breakpoint map.

Example · css
@use 'sass:map';

@mixin down($bp) {
  @media (max-width: map.get($bps, $bp) - 0.02px) { @content; }
}

@mixin between($lower, $upper) {
  @media (min-width: map.get($bps, $lower))
     and (max-width: map.get($bps, $upper) - 0.02px) { @content; }
}

.ad-banner {
  @include between(sm, lg) { display: block; }
}

Configuring breakpoints downstream

Overrides the library's default breakpoint map at @use time so the entire mixin library operates on the project's custom breakpoints.

Example · css
// project/main.scss
@use 'responsive-lib' with (
  $bps: (
    sm:  600px,
    md:  900px,
    lg: 1200px,
    xl: 1600px
  )
);

.container {
  @include responsive-lib.up(lg) { max-width: 1140px; }
}

Discussion

  • Be the first to comment on this lesson.