Repeating the same @media (min-width: 768px) condition across dozens of components is fragile and hard to update. This lesson builds a reusable responsive mixin that wraps a breakpoint behind a simple, memorable name.
Why Wrap Media Queries in a Mixin?
A responsive mixin accepts a breakpoint name (or value) and, using guards, expands to the correct @media condition, letting every component reference .respond-above(tablet) instead of memorizing and repeating a raw pixel value.
This also means updating a single breakpoint value later, changing tablet from 768px to 800px, requires editing one variable instead of hunting through every component file for a matching raw number.
The second argument is a detached ruleset, a block of declarations passed in and later invoked with @rules();.
Guards branch on the named breakpoint to select the correct raw pixel value.
This pattern requires LESS's detached ruleset feature, supported since LESS 1.4.
Callers never need to know or repeat the raw breakpoint value directly.
Responsive Mixins Cheatsheet
Building blocks for a reusable breakpoint mixin system.
Piece
Example
Purpose
Breakpoint variables
@bp-tablet: 768px;
Single source of truth per breakpoint
Guarded mixin
.respond-above(@bp) when (@bp = tablet)
Maps a name to a media condition
Detached ruleset arg
{ width: 260px; }
The declarations to run inside the query
Invoking the ruleset
@rules();
Executes the passed-in declarations
Call site
.respond-above(tablet, { ... });
Readable, name-based usage
Detached Rulesets, Briefly Explained
A detached ruleset is a block of CSS wrapped in curly braces and assigned to a variable (or passed as an argument), which can later be invoked like a mixin call using parentheses. It's the mechanism that lets a responsive mixin accept an arbitrary block of styles as an argument.
A complete responsive mixin system usually needs more than just a min-width helper; max-width and range-based helpers cover the remaining common responsive scenarios.
.respond-below(@bp; @rules) when (@bp = tablet) {
@media (max-width: (@bp-tablet - 1)) { @rules(); }
}
.respond-between(@from; @to; @rules) when (@from = tablet) and (@to = desktop) {
@media (min-width: @bp-tablet) and (max-width: (@bp-desktop - 1)) { @rules(); }
}
Keeping a Growing Mixin Maintainable
As more named breakpoints are added, the guarded mixin definitions grow linearly, one guard per breakpoint name. This is a reasonable tradeoff for the readability gained at every call site.
Keep all breakpoint names and values defined in one shared variables file.
Add a short comment listing every supported breakpoint name above the mixin definitions.
Consider a map-like detached ruleset combined with each() if the number of breakpoints grows very large.
Common Mistakes
Hardcoding a raw pixel value directly at a component's call site instead of using the named responsive mixin.
Forgetting the semicolon after a detached ruleset variable assignment, which is required unlike a normal mixin definition.
Not adding a fallback or default() guard case for an unrecognized breakpoint name, silently producing no media query.
Building respond-below() without subtracting 1 from the next breakpoint's value, causing an overlapping range with respond-above().
Key Takeaways
A responsive mixin maps a memorable breakpoint name to its raw pixel value using guards.
Detached rulesets let the mixin accept an arbitrary block of declarations as an argument via @content-like invocation.
A complete system typically includes above, below, and between helpers for full responsive coverage.
Centralizing breakpoint names and values avoids repeated, hard-to-update raw pixel values across a project.
Pro Tip
Give your responsive mixins names that describe intent (respond-above, respond-below) rather than raw values (min-768), so a future change to the underlying breakpoint value never requires renaming call sites throughout your codebase.
You now know how to build reusable responsive mixins. Next, formalize your breakpoint system with a dedicated lesson on LESS breakpoints.