Skip to content

LESS default() Function

The default() function is a special, guard-only tool that returns true only when no other guarded definition of the same mixin name matches. It's the closest thing LESS has to an explicit else branch.

What Does default() Do?

default() is available only inside a guard condition. It evaluates to true if no other definition of the current mixin call matches, and false otherwise, letting you write an explicit fallback case for a guarded mixin family.

Used outside a guard, default() is instead treated as a literal CSS value (like a function named default being passed through), so it only has this special behavior in the specific context of a mixin guard.

.badge(@status) when (@status = success) { background: green; }
.badge(@status) when (@status = danger)  { background: red; }
.badge(@status) when (default())          { background: gray; }

.tag { .badge(unknown-status); } // background: gray;

Since "unknown-status" matches neither success nor danger, the default() guard becomes the only matching definition.

default() Syntax

.mixin(@arg) when (default()) {
  // fallback, only runs if no other .mixin() definition matched
}
  • default() takes no arguments and is only meaningful inside a guard condition.
  • It can be combined with other guard logic, like when (default()) and (isnumber(@a)).
  • Multiple default() calls across different guarded definitions of the same mixin are allowed, as long as LESS can resolve them without ambiguity.
  • LESS throws a compile error if it detects a genuine circular dependency between multiple default() calls.

default() Function Cheatsheet

Common patterns using default() for guard fallback logic.

Pattern Example Notes
Simple fallback when (default()) Runs only if nothing else matched
Negated fallback when not (default()) Runs only if at least one other guard matched
Combined with type check when (iscolor(@a)) and (default()) Fallback restricted to a specific type
Multiple defaults (safe) when (default()), not (default()) Allowed when not ambiguous

Using default() as an else Branch

The clearest mental model for default() is a catch-all else at the end of an if/else-if chain, except expressed as a separate guarded mixin definition rather than a nested block.

.button-variant(@type) when (@type = primary) { background: #2563eb; }
.button-variant(@type) when (@type = secondary) { background: #64748b; }
.button-variant(@type) when (default()) { background: #e5e7eb; color: #111; }

Combining default() with Type Checks

default() can be combined with a type-check function to create a fallback that only applies to arguments of a specific type, useful when a mixin accepts multiple unrelated argument types with different fallback behavior for each.

.m(@x) when (iscolor(@x)) and (default()) { fallback-color: @x; }
.m(@x) when (isstring(@x)) and (default()) { fallback-string: @x; }

Avoiding default() Ambiguity Errors

LESS will throw a compile error if it cannot determine which default() call should return true because two guarded definitions depend on each other circularly. Keep default() usage straightforward: one clear catch-all case per mixin name is usually enough.

  • Avoid defining two default() guards whose conditions directly negate each other in a circular way.
  • Prefer a single, unambiguous default() fallback per mixin name.
  • If a compile error mentions default() ambiguity, simplify the guarded definitions rather than trying to force a workaround.

Common Mistakes

  • Using default() outside of a guard condition and being confused when it's treated as a literal value instead of special logic.
  • Defining multiple overlapping default() fallbacks that create a circular ambiguity, triggering a compile error.
  • Forgetting that default() depends on every other guarded definition of the exact same mixin name and argument count.
  • Not adding any fallback case at all, leaving certain argument values silently producing no styles.

Key Takeaways

  • default() returns true only when no other guarded definition of the current mixin call matches.
  • It's only meaningful inside a guard condition; elsewhere it's treated as a literal value.
  • default() can be combined with not() and type-check functions for more specific fallback logic.
  • Keep default() usage simple, one clear catch-all case per mixin name, to avoid ambiguity errors.

Pro Tip

Add a when (default()) fallback to every guarded mixin family you write, even if you think every case is covered; it guarantees a defined, intentional result for any argument value you didn't anticipate.