While the do's and don'ts lesson was a fast-reference list, this lesson digs deeper into why each common LESS mistake happens and how to recognize and fix it when you encounter it in real code.
Why These Mistakes Keep Happening
Most recurring LESS mistakes come from one of three sources: syntax that looks similar to another language (Sass, JavaScript, or plain CSS) but behaves differently, LESS's specific evaluation model (lazy evaluation, guard matching), or simply forgetting a small but important detail like a parenthesis or separator.
Recognizing the pattern behind a mistake, rather than just memorizing the fix, makes it much easier to debug a new, unfamiliar case later.
// Looks like it should work, but doesn't:
.mixin(@a) when (@a <= 10) { ... } // <= is invalid in LESS guards
// The correct LESS syntax:
.mixin(@a) when (@a =< 10) { ... }
This exact mistake is common among developers coming from Sass, JavaScript, or plain CSS media queries, all of which use <=.
Categories of Common Mistakes
1. Syntax confusion (borrowed habits from other languages)
2. Evaluation model surprises (lazy evaluation, guard matching)
3. Small omissions (missing parens, semicolons, curly braces)
Syntax confusion mistakes are usually caught immediately by a compile error.
Evaluation model surprises often compile successfully but produce unexpected output.
Small omissions can sometimes compile successfully while silently changing behavior.
Reading the compiled CSS output, not just the LESS source, is the fastest way to catch evaluation model surprises.
Common Mistakes Deep-Dive Cheatsheet
Each mistake, its symptom, and its root cause.
Mistake
Symptom
Root Cause
Using <= in a guard
Compile error
LESS requires =< instead
Mixin without ()
Unexpected standalone CSS in output
No-parens mixins also compile as regular classes
Wrong variable value used
Output doesn't match expectations
Lazy evaluation, last declaration in scope wins
Media query parse error with a variable
Compile error on parentheses
Missing ~"..." escape around the condition
Unused CSS bloat from an import
Larger-than-expected output file
Missing (reference) import option
Guard family produces no output
Element silently unstyled
No default() or unguarded fallback defined
Debugging a Lazy Evaluation Surprise
When a variable's compiled value doesn't match what you expect from reading the file top to bottom, search the entire scope for every declaration of that variable name, the last one, not the first, determines the result.
.box {
width: @size; // check EVERY @size declaration in this scope, not just the nearest one above
}
@size: 10px;
@size: 20px; // this wins, even though it's declared after the usage
Debugging a Guard Family That Silently Matches Nothing
If a mixin call compiles without error but produces no visible styles, check whether the argument you passed actually satisfies any guarded definition's condition, and whether a default() or unguarded fallback exists.
.variant(@type) when (@type = primary) { background: blue; }
.variant(@type) when (@type = success) { background: green; }
.btn { .variant(warning); } // matches NEITHER guard, produces no background at all
Adding a default() fallback definition would have caught this case with an explicit, intentional style.
Reading Compiled Output as a Debugging Tool
When a mistake's cause isn't obvious from the LESS source alone, compiling the file and reading the actual output CSS is often the fastest way to understand what LESS actually did, versus what you expected it to do.
Compile the specific file in isolation to get a smaller, easier-to-read output.
Search the output for the property or selector in question to see its actual final value.
Compare the output against your mental model to pinpoint exactly where the divergence happened.
Common Mistakes
Assuming a mistake must be in the nearest visible code instead of checking the entire scope for competing declarations.
Debugging purely by re-reading LESS source repeatedly instead of compiling and inspecting the actual output CSS.
Fixing a guard-matching mistake by adding another narrow guard instead of a general default() fallback.
Not recognizing when a mistake stems from habits carried over from Sass, JavaScript, or plain CSS syntax.
Key Takeaways
Most recurring LESS mistakes fall into three categories: syntax confusion, evaluation model surprises, and small omissions.
Lazy evaluation surprises require checking every declaration of a variable within its scope, not just the nearest one.
A guard family that silently produces no output usually needs a default() or unguarded fallback case.
Compiling and reading the actual output CSS is often the fastest way to debug an unexpected LESS result.
Pro Tip
When a LESS mistake doesn't make sense from reading the source alone, compile just that one file and read the output CSS directly, it removes any ambiguity about what LESS actually decided to do.
You now understand the root causes behind common LESS mistakes. Next, use the complete LESS cheat sheet as a fast, all-in-one reference.