File types · Explainer

The Less file (.less)

A Less file is a stylesheet written in Less, a language that adds variables, nesting, mixins and functions to CSS and is compiled into a plain CSS file. This guide explains what's inside one, how to compile it, the Less 4 changes that catch people out, and has free sample Less files to download for testing.

At a glance

Full name
Less, short for Leaner Style Sheets
Extensions
.less
MIME type
None registered. Servers usually send text/plain; text/x-less is an unofficial name some tools use
Kind
Plain text (stylesheet source code, compiled to CSS)
Owner
The Less core team; the compiler, less.js, is open source under the Apache 2.0 licence
First released
2009, by Alexis Sellier; first written in Ruby, later ported to JavaScript
Current version
less.js 4.9.1 (September 2026), with Less 5 in alpha
Opens with
Any text editor; compile with lessc (npx -y less in.less out.css)
Comments
// (left out of the CSS) and /* */ (kept)
Magic number
None

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 .less file linked as an ordinary stylesheet does nothing. Only the compiled .css file styles a page.
  • Not Sass. Less and Sass solve the same problem with different syntax: @variables instead 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
// 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. 1// buttons.less: button styles

    A line comment

    Comments starting with // are for people editing the file. They're dropped from the compiled CSS.

  2. 2@import "variables";

    Importing another file

    Pulls in variables.less at compile time, so its variables and mixins are available here. The .less extension is optional. Unlike a CSS @import, the browser never sees it: everything ends up in one CSS file.

  3. 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. 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. 5/* Buttons */

    A block comment

    A normal CSS comment, copied into the output.

  6. 6(@radius / 2)

    An operation

    Maths with units: 12px / 2 gives 6px. Since Less 4.0, division only happens inside parentheses by default; without them @radius / 2 is left as written.

  7. 7&:hover { … }

    Nesting and the parent selector

    A rule inside a rule. & stands for the outer selector, so this compiles to .button:hover.

  8. 8darken(@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. 9&--large { … }

    Building a class name

    &--large becomes .button--large. Native CSS nesting can't do this: there, & can't be glued to the rest of a class name.

  10. 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.css
/* 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 called less and the command it installs is lessc. Don't type npx lessc unless Less is already installed: npx would then download an unrelated package that happens to be called lessc.
  • Install it: npm install -g less gives you lessc everywhere; npm install --save-dev less adds it to one project.
  • Source maps: lessc --source-map styles.less styles.css writes styles.css.map, so developer tools can show the Less line behind each rule.
  • Maths mode: --math=parens-division is the Less 4 default; see the next section.
  • In a build: Vite compiles .less imports once less is installed; webpack uses less-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:

What `sample-math.less` compiles to with less.js 4.9.1
Written asDefault (`parens-division`)`--math=always` (Less 3 behaviour)`--math=parens`
(@base / 2)12px12px12px
@base / 224px / 2 (unchanged)12px24px / 2
@base * 248px48px24px * 2
grid-area: 1 / 2 / 3 / 4Unchanged0.04166667Unchanged
aspect-ratio: 16 / 9Unchanged1.77777778Unchanged

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.

ReleaseDateNotes
First version2009Written in Ruby, later rewritten in JavaScript
3.5July 2018Rulesets usable as maps: @config[key]
4.0December 2020Parentheses for division; mixin calls need brackets
4.9.1September 2026Latest stable release on npm as of October 2026
5.0Alpha since August 2026Current 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:

index.html
<!-- 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 .less file 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 compilingYes (or less.js in the browser)YesNo
Variables@name, fixed when compiled, lazily evaluated$name, fixed when compiledCustom properties --name, live in the browser (all major browsers since 2017)
NestingYes, including &-suffixYes, including &-suffixYes, in all major browsers since 2023, but & can't build class names
MixinsAny class or .name() rule@mixin / @includeNo
Conditions and loopsGuards (when), recursive mixins, each()@if, @each, @for, @whileOnly @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
Compilerless.js (lessc), JavaScriptDart SassThe 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"; loads mixins.less. Imports of .css files are left as CSS @import rules 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 _name rule like Sass. Projects usually have one entry file, such as styles.less, that imports variables.less, mixins.less and 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.less tests exactly that.
  • Escapes: ~"…" outputs text exactly as written, after filling in @{variables}. It was the usual way to protect calc() and other CSS that Less might otherwise try to evaluate.

Troubleshooting

Why won't my Less compile?

Message or symptomUsual causeFix
ParseError: Unrecognised inputA missing brace, semicolon or quote; the line shown is often just after the real mistakeCheck the lines above the one reported
NameError: variable @x is undefinedA typo, or the file that defines it wasn't importedImport the variables file in the entry file, before it's needed
NameError: .mixin is undefinedThe mixin's file isn't imported, or the name or number of arguments doesn't matchCheck the import and the mixin's parameters
FileError: 'x.less' wasn't foundWrong path, or a package path that needs a load pathPaths are relative to the importing file; add --include-path=node_modules for packages
Inline JavaScript is not enabledBacktick JavaScript in an old stylesheetReplace it with Less functions; turning on javascriptEnabled is deprecated and unsafe for files you don't control
Sizes come out as 24px / 2Less 4's parens-division defaultPut 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 .less files, and Stylelint with the postcss-less syntax 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 .less file 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.

sample-styles.less · 2.8 KBDownloadOpen
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.

  1. Comments 1 and 2: variables and operations

    @brand, @radius, @space and @prefix, and @gutter: (@space / 2), which needs its parentheses in Less 4.

  2. Comments 3 and 4: mixins and guards

    .rounded() with a default parameter, and two versions of .text-on() with when guards that pick dark or light text from the background's lightness.

  3. Comment 5: interpolation and nesting

    .@{prefix}-card becomes .ui-card, with nested h2, &:hover, &--featured and a media query that bubbles up.

  4. Comments 6 and 7: functions and :extend

    darken() and fade() compute colours. &:extend(.focus-ring) adds .ui-button:focus-visible to the .focus-ring rule instead of copying its declarations.

  5. 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.

  6. Comment 10: a counted loop

    A recursive mixin with a guard writes .mt-1 to .mt-4, the classic Less loop.

  7. 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.css with 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-area and aspect-ratio. Compile it with different --math options 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 \20AC escape.

    • 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.less and compare with sample-styles.css. Differences point to another Less version or different options.
  • Maths mode: compile sample-math.less. If b comes out as 12px and grid-area as 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.less is 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

Last reviewed 27 October 2026.