NV ToolkitFormat · Validate · Convert

CSS Tools

LESS to CSS Compiler

less.js itself, running in your browser — mixins expanded, guards evaluated, colour functions computed.

In short

Compile LESS to CSS online with the real less.js compiler: @variables, mixins, guards, operations and colour functions all evaluated in your browser.

By NaveenKumar T · Updated

Learn: Sass vs SCSS vs LESS vs Stylus: Choosing a CSS Preprocessor

  • Real less.js compiler
  • Mixins, guards & operations
  • Colour functions evaluated

Runs entirely in your browser — nothing you paste or open here is uploaded, logged, or stored.How we handle data →

Example

LESS to CSS: input and output

A panel built the way real LESS is written: a guarded mixin, a parametric mixin with a default, arithmetic in the padding, and two colour functions.

LESS input
@brand: #0ea5e9;
@radius: 10px;
@gap: 16px;

.rounded(@r: @radius) {
  border-radius: @r;
}

.focus-ring(@color) when (iscolor(@color)) {
  outline: 2px solid fade(@color, 40%);
  outline-offset: 2px;
}

.panel {
  .rounded();
  padding: @gap (@gap * 2);
  background: lighten(@brand, 45%);
  border: 1px solid @brand;

  .panel__title {
    margin: 0 0 (@gap / 2);
    color: darken(@brand, 20%);
  }

  &:focus-within {
    .focus-ring(@brand);
  }

  @media (max-width: 640px) {
    padding: @gap;
  }
}
CSS output
.panel {
  border-radius: 10px;
  padding: 16px 32px;
  background: #dff4fd;
  border: 1px solid #0ea5e9;
}
.panel .panel__title {
  margin: 0 0 8px;
  color: #086189;
}
.panel:focus-within {
  outline: 2px solid rgba(14, 165, 233, 0.4);
  outline-offset: 2px;
}
@media (max-width: 640px) {
  .panel {
    padding: 16px;
  }
}

Both mixins are expanded and disappear from the output, the guard accepts @brand because it is a colour, @gap (@gap * 2) becomes 16px 32px, lighten() and darken() return literal hex values, the nested .panel__title flattens to a full selector, and the in-rule @media is hoisted to the top level.

Learn more

What less.js evaluates for you

The whole LESS runtime is here, not a structural approximation of it. @variables resolve with LESS's lazy-evaluation and scoping rules (a variable can be used above the line that defines it, and the last definition in a scope wins). Mixins are expanded, including parametric mixins with default arguments, the @arguments and @rest forms, and mixin guards such as when (iscolor(@c)) or when (@width > 640px). Operations are computed, colour functions return concrete colours, :extend() rewrites selector lists, and detached rulesets are called and inlined.

Structure is handled by the compiler too: nesting flattens into full selectors, & parent references expand — including suffix forms like &-active and multi-reference selectors — and @media blocks written inside a rule bubble out to the top level exactly as lessc emits them. ~"escaped strings" pass through unevaluated by design, and @{name} interpolation is substituted in selectors, property names and URLs.

Imports, and what to do about them

The one thing a browser cannot do is read your project directory, so @import "variables.less" stops the compile. Inline the imported file above the code that needs it and compile the combined snippet — for a single component plus its token file that is a two-second copy-paste, and it is exactly how most people use this page. Anything with a real dependency graph should stay in your build, where the file manager can resolve paths and caching does its job.

@import (css) url("https://…") is not affected: it is a plain CSS import statement and is emitted unchanged, as are @font-face blocks and url() references, which are never rewritten or fetched.

When teams compile LESS by hand

LESS codebases are mature codebases — Bootstrap 3-era themes, long-lived enterprise admin panels, WordPress and Magento themes — and the compile-by-hand moment usually arrives when styles have to leave that codebase. A component is going into an email template, a CMS custom-CSS field or a documentation site; a bug needs a CodePen reproduction; a designer wants the computed colours rather than the darken() call. In each case the compiled CSS is the deliverable and spinning up the project's build is overkill.

The other common trigger is retiring the preprocessor: custom properties, native nesting and modern colour functions now cover most of what LESS was adopted for, so teams compile their sheets once and maintain plain CSS from then on. If you are moving the other way — modernising rather than retiring — CSS to LESS brings plain CSS into a .less file, the CSS preprocessor converter translates a sheet into SCSS, Sass or Stylus, and LESS formatter tidies a file without compiling it.

Help

Frequently asked questions

Everything you need to know about the LESS to CSS.

01How do I compile LESS to CSS?

Paste your LESS (or load a .less file) and press Compile. less.js runs inside this page — the same compiler lessc wraps — and the CSS appears on the right, ready to copy or download. No upload, no build step, no account.

02Are colour functions like darken() actually computed now?

Yes. This page runs less.js, so darken(@brand, 8%), lighten(), fade(), fadeout(), mix(), saturate() and the rest are evaluated to concrete colour values, exactly as lessc would. So are numeric operations, parametric mixins with default arguments, mixin guards (when (iscolor(@c))), :extend(), detached rulesets, ~"escaped" strings and @{name} interpolation. What lands in the output pane is real, browser-ready CSS.

03Which math mode does the compiler use?

math: always — the classic LESS behaviour, where @gap / 2 and @width - 2px are evaluated wherever they appear rather than only inside parentheses. Modern lessc defaults to parens-division instead, so a sheet written for that mode can differ on one point: an unparenthesised slash that you meant to survive as a literal (grid-area: 1 / 3, font: 14px/1.5) is computed here. Wrap those values in a ~"…" escape, or read them back in the output and fix the two or three lines that matter.

04Why does my @import "theme.less" fail?

There is no file system in a browser tab, so a relative @import has nothing to resolve against and the compile stops with a "File not found" error naming the line. Paste the imported file's contents above the code that uses it and compile the combined snippet. @import (css) url(…) is different — it is a plain CSS import and passes straight through to the output.

05Where do the error line numbers come from?

From less.js itself. A parse error, an undefined @variable, a mixin called with arguments no guard accepts, or a unit mismatch each report the line and column the compiler recorded, and the workbench highlights that position in the input pane. It is the same diagnostic you would get from lessc, which makes this a quick way to check a snippet before committing it.

Keep working

Related tools

Learn the format

Related guides

All guides →