The mixin guards lesson introduced the when syntax. This lesson focuses on applying guards to real problems: building responsive helper mixins, switching between themes, and defensively validating mixin arguments.
Guards as LESS's Conditional Logic
Since LESS has no @if/@else statement, guards are the only mechanism for conditional logic. Understanding how to structure a family of guarded mixin definitions is essential for writing anything beyond the simplest static styles.
A well-designed guarded mixin family reads almost like a switch statement: each guarded definition handles one case, and an optional unguarded definition acts as a shared or fallback behavior.
This pattern is expanded fully in the Responsive Mixins lesson later in this course.
Structuring a Guarded Mixin Family
.mixin(@case) when (@case = A) { /* case A */ }
.mixin(@case) when (@case = B) { /* case B */ }
.mixin(@case) when (default()) { /* fallback */ }
List the most specific guarded cases first for readability, though evaluation order doesn't affect which guards match.
Use default() (covered in its own upcoming lesson) to define an explicit fallback case.
Combine iscolor(), isnumber(), and similar type checks with value comparisons for defensive mixins.
Keep each guarded case focused on exactly one condition for readability.
Practical Guard Patterns Cheatsheet
Common real-world guard patterns used across production LESS codebases.
Use Case
Pattern
Notes
Theme switch
when (@theme = dark)
Branches styles by a theme variable
Breakpoint switch
when (@bp = mobile)
Branches by a named breakpoint
Type validation
when (iscolor(@c))
Only applies if argument is a color
Range validation
when (@n > 0) and (@n =< 12)
Restricts a numeric argument's valid range
Fallback case
when (default())
Runs only if no other guard matched
Defensive Argument Validation with Guards
Guards can validate that a mixin received a sensible argument before applying styles, preventing a mixin from silently producing broken CSS when called with an unexpected value.
.grid-column(@n) when (@n > 0) and (@n =< 12) {
width: percentage(@n / 12);
}
.grid-column(@n) when (@n =< 0), (@n > 12) {
width: 0; // explicit fallback for an out-of-range argument
}
Theme Switching with Guards
A single mixin, gated by guards on a shared theme variable, can produce the correct styles for multiple themes from one call site, which is expanded on further in the Theme System lesson.
As a guarded mixin family grows, readability becomes important. Grouping all definitions of the same mixin name together, in the same file and in a logical order, keeps the overall conditional logic easy to follow.
Keep all guarded definitions of the same mixin name adjacent in the source file.
Add a short comment above the group explaining the overall branching logic.
Prefer 2-4 well-named guard cases over a dozen narrow, overlapping conditions.
Common Mistakes
Scattering guarded definitions of the same mixin name across multiple files, making the overall logic hard to trace.
Writing guard conditions so narrow and overlapping that debugging which one actually applied becomes difficult.
Forgetting a fallback case for arguments outside the guarded ranges, silently producing no styles at all.
Overusing guards for logic that would be clearer as separate, distinctly named mixins instead of one branching mixin.
Key Takeaways
Guards are LESS's only conditional mechanism, used in place of @if/@else.
A guarded mixin family reads like a switch statement: each case handles one condition.
Guards can defensively validate mixin arguments, preventing broken output from unexpected values.
Keep guarded definitions of the same mixin grouped together in source for readability.
Pro Tip
When a guarded mixin family grows past 3-4 cases, add a one-line comment above the group summarizing the branching logic; it saves the next developer from having to trace every guard condition manually.
You now understand practical guard patterns. Next, look closely at guard comparison operators and how they behave with different value types.