An online LESS compiler for trying things out
Reading about a LESS feature is one thing; seeing what it compiles to is faster. This online LESS compiler runs less.js 4 in your browser and recompiles while you type, so you can change a variable, break a guard on purpose or rewrite a mixin and watch the CSS respond. When something is wrong, the status bar explains the problem and the editor marks the line it refers to.
Converting finished .less files for a project or a migration? LESS to CSS runs the same compiler with plain expanded output and no options. This page adds Minify output and is meant for experiments and debugging.
Four experiments to learn LESS
Paste each snippet into the editor, compare your result with the output shown, then change one thing at a time. Small edits with instant feedback are the quickest way to understand how less.js evaluates your code.
1. Operations and units
@w: 10px;
.a { width: @w + 5; height: @w * 2; margin: (@w / 2); padding: @w / 2; }
.b { width: 10px + 2em; color: #ff0000 + #001100; }
.a {
width: 15px;
height: 20px;
margin: 5px;
padding: 10px / 2;
}
.b {
width: 12px;
color: #ff1100;
}
Three lessons in one snippet. Division is only calculated inside parentheses, because LESS 4 uses the parens-division math mode. Mixed units do not raise an error: LESS keeps the unit of the first operand, so 10px + 2em quietly becomes 12px. And colors can be added channel by channel. Use calc() whenever you really mean to mix units.
2. Guards instead of if/else
LESS has no if statement. Conditions are written as guards on mixins:
.text(@size) when (@size >= 16px) { font-weight: 600; }
.text(@size) { font-size: @size; }
.small { .text(12px); }
.large { .text(20px); }
.small {
font-size: 12px;
}
.large {
font-weight: 600;
font-size: 20px;
}
Every mixin whose guard matches is applied, in source order, which is why .large received both declarations while .small only got the unguarded one. Guards accept comparisons, and, not and type checks such as iscolor(@c), so they cover most of what an if would do.
3. Loops with a recursive mixin
.loop(@i) when (@i > 0) {
.col-@{i} { width: (@i * 25%); }
.loop(@i - 1);
}
.loop(3);
.col-3 {
width: 75%;
}
.col-2 {
width: 50%;
}
.col-1 {
width: 25%;
}
The guard stops the recursion, and @{i} interpolates the counter into the selector. Try changing the call to .loop(0): nothing is output, because the guard never matches.
4. :extend versus a mixin
.a { color: red; }
.b:extend(.a) { margin: 0; }
.a,
.b {
color: red;
}
.b {
margin: 0;
}
Instead of copying declarations, :extend adds .b to the selector list of .a. Calling .a(); inside .b as a mixin would copy color: red instead; compile both versions to compare the output size.
Reading LESS error messages
| Message shown | Typical cause |
|---|---|
| Name error: variable @brand is undefined (line 2) | A typo, or a variable that lives in a file you did not paste |
| Name error: .missing is undefined (line 2) | A mixin call with no matching definition |
| Parse error: Unrecognised input. Possibly missing something | An unclosed brace or bracket; the line points to where parsing gave up |
| File error: 'vars.less' wasn't found | An @import or @plugin; the compiler cannot read files from your computer |
A mistake LESS does not report
A missing semicolon is not always an error. This input compiles without complaint:
.a {
color: red
width: 10px;
}
.a {
color: red
width: 10px;
}
LESS read everything up to the next semicolon as the value of color, so the output contains one broken declaration instead of two. If a property seems to vanish in the browser, look for this pattern, or paste the result into the CSS Validator.
Limits of the playground
Inline JavaScript in backticks is disabled, as in current LESS defaults, and imports and plugins cannot load files. Copy shared definitions into the snippet itself, above the code that uses them. To tidy the LESS source itself, use the LESS Formatter; to see the same styles as SCSS, try LESS to SCSS. Everything is compiled locally in your browser.