CSSLess Overview

Less Overview

Less ("Leaner CSS") was one of the first CSS preprocessors, predating Sass's SCSS syntax by giving developers variables, nesting, and mixins on top of plain CSS. It compiles to standard CSS either at build time (via the lessc compiler or a bundler plugin) or, historically, in the browser at runtime via less.js. Native CSS has since absorbed variables and nesting, which is why Less has faded from new projects — but it is still very much alive in codebases and libraries built years ago, most notably Ant Design.

Variables with @

Where Sass uses $, Less uses @ for variables — visually easy to confuse with native CSS at-rules, but they are pure Less-time substitutions removed entirely by the compiler.

SCSS
@primary-color: #2563eb;
@spacing-unit: 8px;

.button {
  background: @primary-color;
  padding: @spacing-unit @spacing-unit * 2;
}
Note
Compare to native CSS custom properties (see Custom Properties), which are resolved at *runtime* in the browser and can be read/changed via JavaScript — Less @variables are gone by the time the browser ever sees the CSS.
Nesting

SCSS
.card {
  padding: 1rem;
  border-radius: 8px;

  .title {
    font-weight: 600;
  }

  &:hover {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  }

  &.is-featured {
    border: 2px solid @primary-color;
  }
}

The & parent-reference works exactly like Sass's — it stands in for the compiled parent selector, letting you write compound classes (&.is-featured) and pseudo-classes (&:hover) without repeating the selector.

Mixins

A Less mixin is just a class or ID ruleset called by name inside another ruleset — no special @mixin keyword needed, though a trailing () marks it "not meant to be output on its own."

SCSS
.rounded(@radius: 4px) {
  border-radius: @radius;
  overflow: hidden;
}

.avatar {
  .rounded(50%);
  width: 48px;
  height: 48px;
}

.card {
  .rounded(); // uses the default 4px
}
Guards — conditional mixins

Less has no @if/@else block syntax; instead, mixins take guards, a when clause that decides whether that mixin definition applies.

SCSS
.button-size(@size) when (@size = large) {
  padding: 16px 32px;
  font-size: 18px;
}

.button-size(@size) when (@size = small) {
  padding: 6px 12px;
  font-size: 13px;
}

.btn-lg { .button-size(large); }
.btn-sm { .button-size(small); }

Guards can also test numeric comparisons (when (@size > 10)), types (when (iscolor(@c))), and combine conditions with and/, (or) / not.

Operations and functions

SCSS
@base: 10px;

.box {
  width: @base * 4;           // 40px — arithmetic on values with units
  margin: @base / 2;
  color: darken(#2563eb, 10%); // built-in color functions
  background: fade(#000, 50%);
}
  • Less performs unit-aware arithmetic directly on dimensioned values (10px * 4), similar to Sass.

  • Built-in color functions (darken(), lighten(), fade(), mix()) mirror Sass's color module almost one-to-one.

  • Less also supports simple loops via recursive mixins (a mixin calling itself with a decrementing guard), standing in for Sass's native @for/@each.

Less vs Sass — the practical differences

Less

Sass (SCSS)

Variable syntax

@variable

$variable

Conditionals

Guards (when) on mixins

Native @if / @else

Loops

Recursive mixins

Native @for, @each, @while

Compiler

lessc (JavaScript), or in-browser less.js

dart-sass (the only actively maintained implementation)

Modules

@import only

@use / @forward (namespaced, one-time evaluation)

Ecosystem momentum

Mostly legacy, still used by Ant Design/Bootstrap 3

Active — the dominant preprocessor for new projects that still want one

Where Less still shows up today
  • Ant Design — the popular React component library ships its theme system in Less variables; customizing an Ant Design theme usually means overriding @primary-color and friends via a Less-aware build step (less-loader, ConfigProvider with CSS variables in v5+).

  • Bootstrap 3 (pre-Bootstrap 4, which moved to Sass) — older Bootstrap-based codebases and their custom themes are frequently still Less.

  • Legacy internal design systems at companies that adopted a preprocessor before Sass's SCSS syntax won broad favor.

Compiling Less

HTML
npm install -D less

npx lessc styles.less styles.css
# or watch mode via a bundler plugin:
# Vite:   npm i -D vite-plugin-less (or built-in .less import support)
# Webpack: less-loader + css-loader + MiniCssExtractPlugin
Note
Modern bundlers (Vite, webpack, Next.js) can import .less files directly once less is installed as a dependency — no separate CLI step needed in most app setups.