The basics
What is a Less file?
A Less file holds the source of a stylesheet in Less, a language that extends CSS with variables, nesting, mixins, guards (conditions), operations and functions. Browsers don't read it directly. The Less compiler, lessc, turns it into a normal .css file, and that's what a web page links to.
Less appeared in 2009. It looks very much like CSS and can even be compiled in the browser with JavaScript, which made it easy to adopt. Bootstrap was written in Less up to version 3 and moved to Sass for version 4, and many themes and admin templates from that period still ship .less files, as do projects built on component libraries that used Less for theming, such as Ant Design before version 5.
- Not CSS. A
.lessfile linked as an ordinary stylesheet does nothing. Only the compiled.cssfile styles a page. - Not Sass. Less and Sass solve the same problem with different syntax:
@variablesinstead of$variables, classes as mixins instead of@mixin, guards instead of@if. The files aren't interchangeable. - Not abandoned. It's less fashionable than Sass, but less.js is maintained: 4.9.1 came out in September 2026 and Less 5 is in alpha.
Anatomy
What's inside a Less file
Less is a superset of CSS: a .css file is already valid Less. On top of that come variables, nesting, mixins, operations and functions. Here is a small stylesheet, part by part. It assumes a variables.less file next to it that defines @brand and @radius.
// buttons.less: button styles
@import "variables";
@padding: 0.5rem 1rem;
.focus-ring(@c: @brand) {
outline: 3px solid @c;
}
/* Buttons */
.button {
padding: @padding;
background: @brand;
border-radius: (@radius / 2);
&:hover {
background: darken(@brand, 10%);
}
&--large {
font-size: 1.25rem;
}
&:focus-visible {
.focus-ring();
}
}- 1
// buttons.less: button stylesA line comment
Comments starting with
//are for people editing the file. They're dropped from the compiled CSS. - 2
@import "variables";Importing another file
Pulls in
variables.lessat compile time, so its variables and mixins are available here. The.lessextension is optional. Unlike a CSS@import, the browser never sees it: everything ends up in one CSS file. - 3
@padding: 0.5rem 1rem;A variable
Less variables start with
@, like CSS at-rules. They are evaluated lazily: a variable can be used before the line that defines it, and the last definition in a scope wins. - 4
.focus-ring(@c: @brand) { … }A parametric mixin
A reusable block with a parameter and a default value. The brackets after the name keep the mixin itself out of the CSS; a plain class such as
.focus-ring { … }would be output as well as being usable as a mixin. - 5
/* Buttons */A block comment
A normal CSS comment, copied into the output.
- 6
(@radius / 2)An operation
Maths with units:
12px / 2gives6px. Since Less 4.0, division only happens inside parentheses by default; without them@radius / 2is left as written. - 7
&:hover { … }Nesting and the parent selector
A rule inside a rule.
&stands for the outer selector, so this compiles to.button:hover. - 8
darken(@brand, 10%)A colour function
Runs while compiling and outputs a plain colour:
#0058d0. Less has functions for colours, maths, strings, lists and types. - 9
&--large { … }Building a class name
&--largebecomes.button--large. Native CSS nesting can't do this: there,&can't be glued to the rest of a class name. - 10
.focus-ring();Calling the mixin
Copies the mixin's declarations here. Write the brackets: calling a mixin without them is deprecated in Less 4, and current versions print a warning.
How it's used
How a Less file becomes CSS
The compiler comes with the less package on npm, which works the same on Windows, macOS and Linux once Node.js is installed. The small stylesheet above compiles to this:
/* Buttons */
.button {
padding: 0.5rem 1rem;
background: #046eff;
border-radius: 6px;
}
.button:hover {
background: #0058d0;
}
.button--large {
font-size: 1.25rem;
}
.button:focus-visible {
outline: 3px solid #046eff;
}- One-off compile:
npx -y less styles.less styles.css. The package is calledlessand the command it installs islessc. Don't typenpx lesscunless Less is already installed: npx would then download an unrelated package that happens to be calledlessc. - Install it:
npm install -g lessgives youlessceverywhere;npm install --save-dev lessadds it to one project. - Source maps:
lessc --source-map styles.less styles.csswritesstyles.css.map, so developer tools can show the Less line behind each rule. - Maths mode:
--math=parens-divisionis the Less 4 default; see the next section. - In a build: Vite compiles
.lessimports oncelessis installed; webpack usesless-loader. Neither needs a separate command. - Minify: run the output through a CSS minifier such as esbuild, Lightning CSS or cssnano.
Versions
Less 3, Less 4 and the maths change
Less 4.0, released in December 2020, made two breaking changes. Division now needs parentheses by default, and calling a mixin without brackets (.mixin;) is deprecated. Older stylesheets written for Less 3 can compile without errors and still produce different CSS:
| Written as | Default (`parens-division`) | `--math=always` (Less 3 behaviour) | `--math=parens` |
|---|---|---|---|
(@base / 2) | 12px | 12px | 12px |
@base / 2 | 24px / 2 (unchanged) | 12px | 24px / 2 |
@base * 2 | 48px | 48px | 24px * 2 |
grid-area: 1 / 2 / 3 / 4 | Unchanged | 0.04166667 | Unchanged |
aspect-ratio: 16 / 9 | Unchanged | 1.77777778 | Unchanged |
The last two rows show why the default changed: in CSS the slash is often a separator, and dividing it silently breaks layouts. If an old theme's sizes come out as 24px / 2, add parentheses around those divisions rather than switching back to --math=always, which less.js 4.9.1 reports as deprecated and due for removal in Less 5.
| Release | Date | Notes |
|---|---|---|
| First version | 2009 | Written in Ruby, later rewritten in JavaScript |
| 3.5 | July 2018 | Rulesets usable as maps: @config[key] |
| 4.0 | December 2020 | Parentheses for division; mixin calls need brackets |
| 4.9.1 | September 2026 | Latest stable release on npm as of October 2026 |
| 5.0 | Alpha since August 2026 | Current 4.x releases warn about features due to go, such as inline JavaScript and --math=always |
Client-side
Compiling in the browser, and why not to do it in production
Less can also run in the page. Link the .less file with rel="stylesheet/less" and load less.js after it; the script downloads the file, compiles it and injects the CSS:
<!-- Development only: compiles styles.less in the browser on every load -->
<link rel="stylesheet/less" type="text/css" href="styles.less">
<script src="less.js"></script>
<!-- Production: compile once with lessc, then link the CSS -->
<link rel="stylesheet" href="styles.css">That's convenient for a quick experiment, and the Less documentation recommends compiling ahead of time with Node.js when performance and reliability matter. The reasons:
- Every visitor compiles the stylesheet, on every page load, after downloading the compiler itself.
- Nothing is styled until the script runs. Visitors with JavaScript blocked or failing see an unstyled page.
- It fetches the
.lessfile with JavaScript, so opening the page from your disk (file://) usually fails, and files on another domain need CORS headers. - Errors happen in front of users rather than on your machine at build time.
Comparison
Less vs Sass (SCSS) vs plain CSS
| Less | [SCSS](/file-types/scss) (Sass) | Plain [CSS](/file-types/css) | |
|---|---|---|---|
| Needs compiling | Yes (or less.js in the browser) | Yes | No |
| Variables | @name, fixed when compiled, lazily evaluated | $name, fixed when compiled | Custom properties --name, live in the browser (all major browsers since 2017) |
| Nesting | Yes, including &-suffix | Yes, including &-suffix | Yes, in all major browsers since 2023, but & can't build class names |
| Mixins | Any class or .name() rule | @mixin / @include | No |
| Conditions and loops | Guards (when), recursive mixins, each() | @if, @each, @for, @while | Only @media, @supports and @container |
| Splitting into files | @import, merged into one CSS file | @use / @forward, merged into one CSS file | @import makes the browser fetch each file |
| Comments | // and /* */ | // and /* */ | /* */ only |
| Compiler | less.js (lessc), JavaScript | Dart Sass | The browser |
For a new project, plain CSS with custom properties and native nesting covers much of what people once used Less for. Sass has the larger ecosystem today. Less remains a sensible choice for maintaining a codebase that already uses it, and converting a large Less codebase to Sass is real work: the mixin and guard syntax has no one-to-one equivalent.
File conventions
Imports, file names and encoding
- Imports:
@import "mixins";loadsmixins.less. Imports of.cssfiles are left as CSS@importrules unless you add the(less)or(inline)option.@import (reference) "lib";makes a library's mixins and variables available without outputting its rules, and(optional)skips a file that doesn't exist. - No partial convention: Less has no
_namerule like Sass. Projects usually have one entry file, such asstyles.less, that importsvariables.less,mixins.lessand component files, and only the entry file is compiled. - Encoding: save files as UTF-8. less.js reads a UTF-8 byte order mark and CRLF line endings without trouble and writes LF line endings without a BOM; non-ASCII text in strings comes through unchanged.
sample-windows.lesstests exactly that. - Escapes:
~"…"outputs text exactly as written, after filling in@{variables}. It was the usual way to protectcalc()and other CSS that Less might otherwise try to evaluate.
Troubleshooting
Why won't my Less compile?
| Message or symptom | Usual cause | Fix |
|---|---|---|
ParseError: Unrecognised input | A missing brace, semicolon or quote; the line shown is often just after the real mistake | Check the lines above the one reported |
NameError: variable @x is undefined | A typo, or the file that defines it wasn't imported | Import the variables file in the entry file, before it's needed |
NameError: .mixin is undefined | The mixin's file isn't imported, or the name or number of arguments doesn't match | Check the import and the mixin's parameters |
FileError: 'x.less' wasn't found | Wrong path, or a package path that needs a load path | Paths are relative to the importing file; add --include-path=node_modules for packages |
Inline JavaScript is not enabled | Backtick JavaScript in an old stylesheet | Replace it with Less functions; turning on javascriptEnabled is deprecated and unsafe for files you don't control |
Sizes come out as 24px / 2 | Less 4's parens-division default | Put the division in parentheses |
DEPRECATED WARNING: Calling a mixin without parentheses | .mixin; instead of .mixin(); | Add the brackets |
How to
How to open, edit and convert a Less file
- Open or edit it: any plain-text editor. VS Code highlights and checks Less without extensions, and so do JetBrains IDEs.
- Turn it into CSS: compile it with
lessc, as above. That's also the only reliable way to see what it does: mixins, guards and lazy variables can be hard to follow by eye. - Turn CSS into Less: rename the file to
.less. Any CSS is valid Less. - Convert Less to Sass: there's no official converter. Variables and nesting translate directly; mixins, guards and escaping need rewriting by hand.
- Format and lint it: Prettier formats
.lessfiles, and Stylelint with thepostcss-lesssyntax checks them.
Security
Is a Less file safe?
Opening a Less file in an editor is harmless. Compiling one is closer to running code than it looks:
- Inline JavaScript. Old stylesheets could run JavaScript in backticks while compiling. Current less.js turns this off by default and warns that the option will be removed in Less 5; leave it off, especially for stylesheets from others.
- Plugins.
@plugin "name";loads a JavaScript plugin when the file is compiled. Treat a.lessfile from an unknown source like a script: read it before compiling. - Source maps and comments. Public source maps and
/* */comments can reveal internal paths and notes. Ship only the compiled CSS where that matters.
Free downloads
Sample Less files to download
Free sample Less files for testing compilers, build pipelines, editors and syntax highlighters. Every file compiles without errors or warnings in less.js 4.9.1, and the compiled CSS passes the CSSTree validator.
Loading…What's inside sample-styles.less
The file is commented: open it in a text editor and each numbered comment marks one of these parts. sample-styles.css is what lessc makes of it.
Comments 1 and 2: variables and operations
@brand,@radius,@spaceand@prefix, and@gutter: (@space / 2), which needs its parentheses in Less 4.Comments 3 and 4: mixins and guards
.rounded()with a default parameter, and two versions of.text-on()withwhenguards that pick dark or light text from the background's lightness.Comment 5: interpolation and nesting
.@{prefix}-cardbecomes.ui-card, with nestedh2,&:hover,&--featuredand a media query that bubbles up.Comments 6 and 7: functions and :extend
darken()andfade()compute colours.&:extend(.focus-ring)adds.ui-button:focus-visibleto the.focus-ringrule instead of copying its declarations.Comments 8 and 9: a map and each()
@tones[warning]looks up one value;each(@tones, …)writes a badge class per entry, with the guard mixin choosing the text colour.Comment 10: a counted loop
A recursive mixin with a guard writes
.mt-1to.mt-4, the classic Less loop.Comments 11 and 12: escaping and custom properties
~"calc(100% - @{gutter})"outputs text as written, and--brand: @brand;writes a Less value into a CSS variable.
All sample Less files
Commented Less stylesheet
sample-styles.less · 2.8 KB (2,865 bytes)
A self-contained stylesheet with variables, operations, mixins, guards, interpolation, nesting, colour functions,
:extend, a map,each()and a recursive loop, with 12 numbered comments.- Testing Less compilers and build pipelines
- Teaching the parts of a Less file
Compiled CSS of the featured sample
sample-styles.css · 1.1 KB (1,083 bytes)
The output of
npx -y less sample-styles.less sample-styles.csswith less.js 4.9.1.- Comparing your compiler's output
- Seeing what each Less feature turns into
Less 4 maths modes
sample-math.less · 994 bytes
Division and multiplication with and without parentheses, plus CSS slashes in
grid-areaandaspect-ratio. Compile it with different--mathoptions to see the results in the table above.- Checking which maths mode a build uses
- Testing a Less 3 to Less 4 upgrade
UTF-8 with BOM and CRLF line endings
sample-windows.less · 708 bytes
Saved with a UTF-8 byte order mark and Windows line endings, with text in eight scripts, emoji, a
.caféclass and a\20ACescape.- Checking tools that choke on a BOM or CRLF
- Spotting encoding bugs in the CSS output
100 KB Less file
sample-100kb.less · 100 KB (102,400 bytes)
1,122 generated colour swatches, each with a variable, a mixin call and an operation, padded with a comment to exactly 102,400 bytes. It compiles to about 104 KB of CSS.
- Upload and size-limit tests
- Compiler performance
Ways to test with them
- Compiler output: compile
sample-styles.lessand compare withsample-styles.css. Differences point to another Less version or different options. - Maths mode: compile
sample-math.less. Ifbcomes out as12pxandgrid-areaas a number, the build is using--math=always. - Encoding: compile
sample-windows.less. The CSS should show every script unchanged; anyÃorâ€means a step misread UTF-8. - Upload limits:
sample-100kb.lessis exactly 102,400 bytes, for testing a limit at the boundary.
Free to use for testing, teaching and demos, commercially or not, with no attribution needed. A link back to this page is always appreciated.
Put it online
Have a Less file? Give it a link.
Drop a Less file on 99helpers and it gets its own address, handy for sharing a theme or a snippet for review. Opened in a browser, the link shows the source as plain text: browsers can't apply Less, so to style a page, compile it and host the .css file.
Questions
Less files, frequently asked
What is a .less file?
A stylesheet written in Less, a language that adds variables, nesting, mixins and functions to CSS. It's compiled into an ordinary .css file before a browser uses it.
How do I open a Less file?
With any text editor, such as VS Code, Notepad or TextEdit in plain-text mode. To see its effect, compile it to CSS and open a page that uses that CSS.
How do I compile Less to CSS?
With Node.js installed, run npx -y less input.less output.css, or install it with npm install -g less and use lessc. Build tools such as Vite compile .less imports automatically.
Is Less still maintained?
Yes. less.js 4.9.1 was released in September 2026 and Less 5 is in alpha. Sass is more widely used for new projects.
What's the difference between Less and Sass?
Both are CSS preprocessors. Less uses @ for variables, classes as mixins and guards for conditions, and its compiler is JavaScript. Sass (SCSS) uses $, @mixin, @if and loops, and its main compiler is Dart Sass.
Why does my division not work in Less?
Since Less 4.0, division only happens inside parentheses by default: write (@width / 2). Without them, @width / 2 is left as written, because CSS uses the slash as a separator.
Can I use Less directly in the browser?
Yes, with less.js and rel="stylesheet/less", but only for experiments. In production, compile ahead of time: in-browser compiling slows every page load and leaves the page unstyled if the script fails.
Related formats
Other file types explained
Keep going
Related
Sources
- Less: overview and features
- Less: command line and browser usage
- Less: about and history
- less on npm
- Bootstrap 4 alpha: moved from Less to Sass
Last reviewed 27 October 2026.