Where you still run into Less
Less was the stylesheet language of Bootstrap 3, and it remains the theming layer of Ant Design, Semantic UI, many Magento 2 storefronts and a long tail of internal admin panels. It looks like CSS with @variables, nested selectors, parametric mixins called like functions (.rounded(4px);), guards written as when (...), the :extend() pseudo-class, ~"escaped" strings and @{name} interpolation in selectors and property names. Because so much of it lives in older codebases, the files you inherit are often a mix of hand-written and machine-minified rules, which is exactly the case a formatter fixes.
Formatting a stylesheet step by step
- Paste the Less source or drop the file in. Variable declarations like
@brand: #2563eb;, mixin calls ending in();andwhenguards tell the detector this is Less rather than SCSS or plain CSS. - Read the output pane. It updates as you edit; Ctrl/Cmd+Enter forces a run if live formatting is turned off in Settings.
- Pick an Indent of 2 spaces, 4 spaces or tabs from the toolbar to match your repository.
- Press Ctrl/Cmd+Shift+C to copy, or use Download to save the file.
Under the hood this is Prettier’s Less support, built on the PostCSS parser and loaded into the page as JavaScript. The stylesheet is processed in the browser tab itself, so an unreleased theme or a client’s brand palette stays on your computer.
What Prettier rewrites
The formatter changes layout, not logic. Declarations are split onto their own lines with a single space after the colon and a closing semicolon. Blocks open on the selector line and close on a line of their own. Arithmetic gets spaces around the operator, so @gutter/2 is printed as @gutter / 2, and a value like .5em gains a leading zero. A property with several comma-separated layers, such as transition: opacity .3s, transform .3s, is printed one layer per line, and lines are otherwise kept within roughly 80 columns. Comments of both styles are retained, and stacked blank lines are reduced to one.
There are no Less-only switches. Indentation is the only shared layout setting that applies here.
Less syntax that is left exactly as written
Several Less constructs are passed through verbatim because changing them could change what the compiler produces:
- Mixin definitions with defaults, such as
.rounded(@r:@radius), keep their original spacing inside the parentheses. - Guard conditions like
when (lightness(@a)>=50%)are not re-spaced. - Escaped values
~"calc(100% - @{gutter})", backtick JavaScript evaluation and@pluginlines are copied as is. @import (reference),(inline)and other import options stay on the import line.- Detached rulesets assigned to a variable keep their trailing semicolon, and calls such as
@detached();stay where they are. - An empty rule produced by
:extend()is kept rather than deleted.
Nothing is compiled. Variables are not resolved and imports are not loaded, so you can format a single partial out of a larger theme.
Less or SCSS?
The two are easy to confuse when you only see a snippet. Less uses @ for variables and calls mixins as class-like selectors, while SCSS uses $ and @include. If a file is full of $ variables, the SCSS formatter is the right tool; for compiled output, use the CSS formatter.
Examples
Minified theme with guarded mixins
Both guarded mixins and the escaped calc() survive unchanged while the card rule is expanded and the division gains spaces.
@import (reference) "mixins.less";@gutter:16px;.mixin(@a) when (lightness(@a)>=50%){background:black}.mixin(@a) when (lightness(@a)<50%){background:white}.card{.mixin(#ddd);padding:@gutter/2;margin:~"calc(100% - @{gutter})";&-title{font-size:1.25em}}@import (reference) "mixins.less";
@gutter: 16px;
.mixin(@a) when (lightness(@a)>=50%) {
background: black;
}
.mixin(@a) when (lightness(@a)<50%) {
background: white;
}
.card {
.mixin(#ddd);
padding: @gutter / 2;
margin: ~"calc(100% - @{gutter})";
&-title {
font-size: 1.25em;
}
}
Detached ruleset and parametric mixin
The detached ruleset keeps its closing semicolon and the !important mixin call is spaced but not altered.
@detached:{background:red;};.box{@detached();.bordered(2px)!important;width:(@w * 2)}
.bordered(@width:1px){border:@width solid #ccc}@detached: {
background: red;
};
.box {
@detached();
.bordered(2px) !important;
width: (@w * 2);
}
.bordered(@width:1px) {
border: @width solid #ccc;
}
Selector interpolation and media variables
Variables used as a media query and inside a selector are kept intact, with four spaces per level.
@phone:~"(max-width: 600px)";@media @phone{.nav{display:none}}@selector:~".nav";@{selector}-item{color:#334155;padding:.5em 1em}@phone: ~"(max-width: 600px)";
@media @phone {
.nav {
display: none;
}
}
@selector: ~".nav";
@{selector}-item {
color: #334155;
padding: 0.5em 1em;
}
Common errors and how to fix them
| Error | Cause | Fix |
|---|---|---|
CssSyntaxError: Unclosed blockExplained | A rule or mixin body has an opening brace without a matching closing one. | Go to the reported line, find the block it starts and add the missing } where that block should end. |
CssSyntaxError: Unexpected } | An extra closing brace follows a complete rule, typically after a mixin was deleted. | Delete the surplus } shown at the reported position. |
CssSyntaxError: Unknown word color | A property is missing its colon, so the parser reads the line as the start of a selector. | Insert the colon between the property name and its value. |
CssSyntaxError: Unclosed string | An escaped string such as ~“calc(…)” or a font name has no closing quote. | Add the closing quote before the semicolon. |
Frequently asked questions
Does the Less formatter compile Less to CSS?
No. It only reformats the source. Run lessc or your build tool to get CSS; the output here is still Less.
Why are my mixin parameters not spaced like the declarations?
Prettier leaves the inside of mixin definitions and guard conditions as written, because Less is sensitive to spacing in some of those positions. Only declarations and selectors are normalised.
Can it handle Bootstrap 3 or Ant Design variable files?
Yes. Long lists of @variable declarations, color functions such as darken() and fade(), and imports are all formatted, and nothing is evaluated.
Is there a way to minify Less here?
Not directly. Compile it to CSS first, then use the CSS minifier on the result, which is what browsers receive anyway.