Recent from talks
Nothing was collected or created yet.
Less (style sheet language)
View on Wikipedia| Less | |
|---|---|
| Designed by | Alexis Sellier |
| Developer | Alexis Sellier, Dmitry Fadeyev |
| First appeared | 2009 |
| Stable release | 4.4.2[1] |
| Typing discipline | Dynamic |
| Implementation language | JavaScript |
| OS | Cross-platform |
| License | Apache License 2.0 |
| Filename extensions | .less |
| Website | lesscss |
| Influenced by | |
| CSS, Sass | |
| Influenced | |
| Sass, Less Framework, Bootstrap (v3) | |
Less (Leaner Style Sheets; sometimes stylized as LESS) is a dynamic preprocessor style sheet language that can be compiled into Cascading Style Sheets (CSS) and run on the client side or server side.[2] Designed by Alexis Sellier, Less is influenced by Sass and has influenced the newer "SCSS" syntax of Sass, which adapted its CSS-like block formatting syntax.[3] Less is an open source project. Its first version was written in Ruby; however, in the later versions, use of Ruby has been deprecated and replaced by JavaScript. The indented syntax of Less is a nested metalanguage, as valid CSS is valid Less code with the same semantics. Less provides the following mechanisms: variables, nesting, mixins, operators and functions; the main difference between Less and other CSS precompilers is that Less allows real-time compilation via less.js by the browser.[2][4]
Features
[edit]Variables
[edit]Less allows variables to be defined. Variables in Less are defined with an at sign (@). Variable assignment is done with a colon (:).
During translation, the values of the variables are inserted into the output CSS document.[2]
@pale-green-color: #4D926F;
#header {
color: @pale-green-color;
}
h2 {
color: @pale-green-color;
}
The code above in Less would compile to the following CSS code.
#header {
color: #4D926F;
}
h2 {
color: #4D926F;
}
Mixins
[edit]Mixins allows embedding all the properties of a class into another class by including the class name as one of its property, thus behaving as a sort of constant or variable. They can also behave like functions, and take arguments. CSS does not support Mixins: Any repeated code must be repeated in each location. Mixins allows for more efficient and clean code repetitions, as well as easier alteration of code.[2]
.rounded-corners (@radius: 5px 10px 8px 2px) {
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}
#header {
.rounded-corners;
}
#footer {
.rounded-corners(10px 25px 35px 0px);
}
The above code in Less would compile to the following CSS code:
#header {
-webkit-border-radius: 5px 10px 8px 2px;
-moz-border-radius: 5px 10px 8px 2px;
border-radius: 5px 10px 8px 2px;
}
#footer {
-webkit-border-radius: 10px 25px 35px 0px;
-moz-border-radius: 10px 25px 35px 0px;
border-radius: 10px 25px 35px 0px;
}
Less has a special type of ruleset called parametric mixins which can be mixed in like classes, but accepts parameters.
#header {
h1 {
font-size: 26px;
font-weight: bold;
}
p {
font-size: 16px;
a {
text-decoration: none;
color: red;
&:hover {
border-width: 1px;
color: #fff;
}
}
}
}
The above code in Less would compile to the following CSS code:
#header h1 {
font-size: 26px;
font-weight: bold;
}
#header p {
font-size: 16px;
}
#header p a {
text-decoration: none;
color: red;
}
#header p a:hover {
border-width: 1px;
color: #fff;
}
Functions and operations
[edit]Less allows operations and functions. Operations allow addition, subtraction, division and multiplication of property values and colors, which can be used to create complex relationships between properties. Functions map one-to-one with JavaScript code, allowing manipulation of values.
@the-border: 1px;
@base-color: #111;
@red: #842210;
#header {
color: @base-color * 3;
border-left: @the-border;
border-right: @the-border * 3;
}
#footer {
color: @base-color + #003300;
border-color: desaturate(@red, 10%);
}
The above code in Less would compile to the following CSS code:
#header {
color: #333;
border-left: 1px;
border-right: 3px;
}
#footer {
color: #114411;
border-color: #7d2717;
}
Comparison
[edit]Sass
[edit]Both Sass and Less are CSS preprocessors, which allow writing clean CSS in a programming construct instead of static rules.[5]
Less is inspired by Sass.[6][3] Sass was designed to both simplify and extend CSS, so things like curly braces were removed from the syntax. Less was designed to be as close to CSS as possible, and as a result existing CSS can be used as valid Less code.[7]
The newer versions of Sass also introduced a CSS-like syntax called SCSS (Sassy CSS).
Use on sites
[edit]Less can be applied to sites in a number of ways. One option is to include the less.js JavaScript file to convert the code on-the-fly. The browser then renders the output CSS. Another option is to render the Less code into pure CSS and upload the CSS to a site. With this option no .less files are uploaded and the site does not need the less.js JavaScript converter.
Less software
[edit]| Name | Description | Software License | Platform | Functionality |
|---|---|---|---|---|
| WinLess - Windows GUI for less.js | GUI Less Compiler | Apache 2.0[8] | Windows | Compiler |
| Crunch | Less editor and compiler (requires Adobe AIR) | GPL[9] | Windows, Mac OS X | Compiler Editor |
| less.js-windows | Simple command-line utility for Windows that will compile *.less files to CSS using less.js. | MIT License[10] | Windows | Compiler |
| less.app | Less Compiler | Proprietary | Mac OS X | Compiler |
| CodeKit | Less Compiler | Proprietary | Mac OS X | Compiler |
| LessEngine | Less Compiler | Free | OpenCart Plugin | Compiler |
| SimpLESS | Less Compiler | free but no explicit license[11] | Windows Mac OS X Linux |
Compiler |
| Chirpy | Less Compiler | Ms-PL[12] | Visual Studio Plugin | Compiler |
| Mindscape Web Workbench | Syntax highlighting and IntelliSense for Less and Sass | Proprietary | Visual Studio Plugin | Compiler Syntax Highlighting |
| Eclipse Plugin for Less | Eclipse Plugin | EPL 1.0[13] | Eclipse Plugin | Syntax highlighting Content assist Compiler |
| mod_less | Apache2 module to compile Less on the fly | Open Source | Linux | Compiler |
| grunt-contrib-less | Node.js Grunt task to convert Less to CSS | MIT[14] | Node.js | Compiler |
| Web Essentials | Visual Studio extension with support for Less and Sass | Apache 2.0 [15] | Windows | Syntax highlighting, Content assist, Compiler |
| clessc | Pure C++ compiler | MIT[16] | at least Windows, Linux, MacOS | Compiler |
| Less WebCompiler | Web-based compiler | MIT[17] | at least Windows, Linux, MacOS | Compiler, Syntax highlighting, Minifier |
See also
[edit]References
[edit]- ^ "Release 4.4.2". 6 October 2025. Retrieved 20 October 2025.
- ^ a b c d The Core Less Team. "Getting started | Less.js". Less.js. Retrieved 2021-03-19.
- ^ a b Weizenbaum, Nathan (2009-06-17). "Sass and Less : Nex3". Archived from the original on 2009-06-21. Retrieved 2021-03-19.
- ^ Meng, Jiew (2010-12-14). Mortensen, Peter (ed.). "css - Is there a SASS.js? Something like LESS.js?". Stack Overflow. Retrieved 2021-03-19.
- ^ Atwood, Jeff (2010-04-30). "What's Wrong With CSS". Coding Horror. Retrieved 2022-12-03.
- ^ The Core Less Team. "About | Less.js". Less.js. Retrieved 2021-03-19.
- ^ Eppstein, Chris (2010-11-10). "sass_and_less_compared.markdown". GitHub Gist. Retrieved 2021-03-19.
- ^ Lagendijk, Mark (2013-01-29). "License Information · Issue #55 · marklagendijk/WinLess". GitHub. Retrieved 2021-03-19.
- ^ Dean, Matthew (2011-12-02). "Crunch/LICENSE.txt at master · matthew-dean/Crunch". GitHub. Retrieved 2021-03-19.
- ^ Smart, Duncan (2013-07-25). "less.js-windows/LICENSE at master · duncansmart/less.js-windows". GitHub. Retrieved 2021-03-19.
- ^ Engel, Christian (2012-07-29). "SimpLESS/LICENSE.txt at master · Paratron/SimpLESS". GitHub. Retrieved 2021-03-19.
- ^ Evan Nagle. "Chirpy - VS Add In For Handling Js, Css, DotLess, and T4 Files - CodePlex Archive". CodePlex. Archived from the original on 2021-02-20. Retrieved 2021-03-19.
- ^ Vincent Simonet. "Eclipse plugin for LESS". normalesup.org. Retrieved 2021-03-19.
- ^ Kellen, Tyler (2012-09-04). "grunt-contrib-less/LICENSE-MIT at master · gruntjs/grunt-contrib-less". GitHub. Retrieved 2021-03-19.
- ^ Kristensen, Mads (2014-06-18). "WebEssentials2013/LICENSE.txt at master · madskristensen/WebEssentials2013". GitHub. Retrieved 2021-03-19.
- ^ Bram van der Kroef (2017-07-11). "clessc/LICENSE at master · BramvdKroef/clessc". GitHub. Retrieved 2021-03-19.
- ^ SamBrishes (2018-12-15). "snout.less/LICENSE.md at master · pytesNET/snout.less". GitHub. Retrieved 2021-03-19.
External links
[edit]Less (style sheet language)
View on Grokipedia@primary-color: #blue;), mixins for defining reusable blocks of properties that can be included in other rules, and functions for tasks like color manipulation (e.g., lighten(@color, 10%)).[2] It supports nesting for hierarchical selectors, imports for modular file organization, and namespaces to group related mixins or variables, all while preserving CSS compatibility to avoid vendor prefixes or non-standard code.[2] Less also handles advanced operations like mathematical calculations on units and escaping for custom strings in media queries.[5]
As of October 2025, the latest stable release is version 4.4.2, actively maintained through GitHub contributions, with ongoing support for modern web standards and tools integration.[6] While native CSS has evolved to include some similar features like custom properties (variables) and nesting, Less remains a popular choice for complex projects requiring preprocessing, particularly in legacy systems or environments needing enhanced productivity without full CSS refactoring.[7]
Introduction and History
Overview
Less is a dynamic stylesheet language that extends CSS with features enabling dynamic behavior, such as variables, mixins, operations, and functions, while compiling down to standard, browser-compatible CSS.[2] As an open-source project licensed under the Apache License 2.0, it uses the filename extension .less and is implemented primarily in JavaScript via the Less.js compiler, making it cross-platform and suitable for both client-side and server-side processing.[4][3] Created in 2009 by Alexis Sellier (known as @cloudhead), Less originated as a Ruby-based project before being ported to JavaScript to facilitate broader adoption and integration with web development workflows.[4] The latest stable release, version 4.4.2, was published on October 6, 2025.[6] Less syntax is designed to be fully backward-compatible with CSS, allowing existing CSS code to be included verbatim in .less files without modification during compilation. For example, a simple rule like:body {
color: #333;
}
body {
color: #333;
}
Development History
Less was initially developed in 2009 by Alexis Sellier, known online as @cloudhead, as a Ruby-based prototype aimed at overcoming the limitations of standard CSS in supporting dynamic and parametric styling.[4] The project sought to introduce features like variables and mixins to make stylesheet authoring more efficient and maintainable, drawing inspiration from existing preprocessors while maintaining a syntax closely aligned with CSS.[4] In 2010, Sellier transitioned the implementation to JavaScript, releasing less.js to enable direct execution in web browsers and improve integration with client-side environments.[4] This shift facilitated real-time compilation during development and positioned Less for broader adoption in web projects. The project was hosted on GitHub starting that year, fostering open-source collaboration.[9] The first stable release, version 1.0, arrived in early 2011, marking the initial public version suitable for production use. By 2011, Less integrated with the Node.js ecosystem, allowing server-side compilation through tools like the lessc command-line compiler, which expanded its utility in build processes.[10] Major version milestones followed, with v2.0 released in 2014, introducing improved error handling and stricter parsing to enhance reliability during compilation. Version 3.0 in 2018 added support for plugins, enabling extensibility through third-party modules for custom functions and transformations.[11] In the mid-2010s, as native CSS3 features like custom properties began reducing the immediate need for some preprocessor capabilities, Less responded by refining its core to complement emerging standards rather than compete directly.[2] Version 4.0, launched in 2019, featured a modern JavaScript rewrite for better performance and maintainability, including enhancements for ES6 compatibility in its runtime environment.[12] Development has remained community-driven, with over 240 contributors to the GitHub repository by 2025. The latest release, v4.4.2 in October 2025, focused on bug fixes and performance optimizations, such as refined deprecation warnings and updated build configurations. In May 2012, Sellier handed control to a core team of active contributors, ensuring sustained evolution through collective input via issues and pull requests.[4]Core Features
Variables
Variables in Less allow developers to store reusable values, promoting maintainability and consistency in stylesheet code. They are declared using the syntax@variable-name: value;, where the value can represent colors, numbers, strings, or units. For instance, a primary color can be defined as @primary-color: #4D926F;. This declaration enables the value to be referenced throughout the stylesheet, reducing repetition and facilitating global updates.[13]
Less supports various data types for variables, including colors like #428bca, numbers such as 42, strings enclosed in quotes like "example", and units like 100px or 9%. These variables can be used in CSS properties, selectors, URLs, and imports. A basic usage example demonstrates substitution during compilation:
@primary-color: #4D926F;
body {
color: @primary-color;
}
@primary-color: #4D926F;
body {
color: @primary-color;
}
body { color: #4D926F; }, showing how the variable replaces the property value seamlessly.[13]
Variable scope in Less follows a lexical model similar to CSS, where variables are first sought in the local scope and, if not found, inherited from parent scopes, effectively making them global unless overridden locally, such as within mixins. The last definition of a variable in the applicable scope takes precedence, allowing overrides without strict block isolation in earlier versions. For example:
@var: 0;
.class {
@var: 1;
width: @var; // Uses 1
}
@var: 0;
.class {
@var: 1;
width: @var; // Uses 1
}
.lazy-eval {
width: @var;
}
@var: 100px;
.lazy-eval {
width: @var;
}
@var: 100px;
Mixins
In Less, mixins serve as reusable blocks of styles that can be embedded into other rulesets, enabling efficient code reuse and modular design similar to class selectors in CSS. They are defined using class or ID selectors and invoked by referencing the mixin name followed by parentheses, which copies the mixin's properties into the calling rule. For instance, a simple non-parametric mixin might be written as:.bordered {
border: 1px [solid](/page/Solid) black;
}
.bordered {
border: 1px [solid](/page/Solid) black;
}
div {
.bordered();
}
div {
.bordered();
}
div selector inherits the border property: div { [border](/page/Border): 1px [solid](/page/SOLID) black; }.[2]
Parametric mixins extend this functionality by accepting arguments, allowing dynamic customization of styles with optional default values. A common example is a mixin for rounded corners:
.rounded(@radius: 5px) {
border-radius: @radius;
}
.rounded(@radius: 5px) {
border-radius: @radius;
}
#header { .rounded(); }, yielding #header { border-radius: 5px; }, or with a specific value like .rounded(10px); for greater curvature. Arguments are passed positionally by default, such as .box(10px, red); for a mixin defined as .box(@width, @color: blue) { width: @width; background: @color; }, but named arguments like .box(@color: green, @width: 20px); provide flexibility and clarity, especially with multiple parameters. Mixins can also incorporate variables as arguments for further reusability, as detailed in the variables section.[2]
Multiple mixins can be included in a single rule by separating calls with semicolons, facilitating the combination of several style blocks. For example, .primary(); .secondary(); would apply properties from both mixins to the target selector. This supports complex style compositions without duplication.[2]
Guards enable conditional logic for mixin selection, applying a mixin only when specified criteria are met, which was introduced in version 1.5.0 to enhance decision-making in stylesheets. An example using a color function checks lightness:
.light-text(@color) when (lightness(@color) > 50%) {
color: darken(@color, 20%);
}
.dark-text(@color) when (lightness(@color) <= 50%) {
color: lighten(@color, 20%);
}
.button {
.light-text(#ffffff);
// Or .dark-text(#000000); for darker backgrounds
}
.light-text(@color) when (lightness(@color) > 50%) {
color: darken(@color, 20%);
}
.dark-text(@color) when (lightness(@color) <= 50%) {
color: lighten(@color, 20%);
}
.button {
.light-text(#ffffff);
// Or .dark-text(#000000); for darker backgrounds
}
and or or.[2]
To control output priority, the !important flag can be appended to a mixin call, applying the !important declaration to all generated properties in the resulting CSS. For example:
.strong-background {
background: #f5f5f5;
}
.urgent {
.strong-background() !important;
}
.strong-background {
background: #f5f5f5;
}
.urgent {
.strong-background() !important;
}
.urgent { background: #f5f5f5 !important; }, overriding standard specificity where needed.[2]
Functions and Operations
Less supports a variety of arithmetic operations on numeric values, including addition (+), subtraction (-), multiplication (*), and division (/), which can operate on numbers with or without units and preserve compatible units during computation.[15] For instance, if a variable@base is defined as 100px, the expression width: @base * 2; compiles to width: 200px;.[5] These operations enable dynamic calculations for properties like dimensions or spacing, ensuring unit consistency where possible, such as treating 2 * 3cm as 6cm.[15]
In addition to basic arithmetic, Less provides built-in mathematical functions for more precise manipulations, available since version 1.0.0.[5] Key functions include round(number, [decimalPlaces]) for rounding to the nearest integer or specified decimals (e.g., round(1.67, 1) yields 1.7), ceil(number) for ceiling (e.g., ceil(2.4) yields 3), floor(number) for flooring (e.g., floor(2.6) yields 2), and percentage(number) for converting decimals to percentages (e.g., percentage(0.5) yields 50%).[5] Other utilities like abs(number) return the absolute value (e.g., abs(-18.6%) yields 18.6%), while min() and max() select the lowest or highest value from a set (e.g., min(5, 10) yields 5).[5] These functions support unit-aware computations, such as sqrt(25cm) producing 5cm.[5]
String operations in Less facilitate text manipulation. Strings can be concatenated using variable interpolation within quoted strings. For example:
@first: "Hello";
@second: "World";
.greeting {
content: "@{first} @{second}";
}
@first: "Hello";
@second: "World";
.greeting {
content: "@{first} @{second}";
}
content: "Hello World";. Additional string functions, introduced in version 1.0.0 unless noted, include e(string) to remove surrounding quotes (e.g., e('quoted') yields unquoted), escape(string) for URL-encoding special characters (e.g., escape('a=1') yields a%3D1), and replace(string, pattern, replacement, [flags]), added in version 1.7.0, allows pattern-based substitutions (e.g., replace('Hello, Mars?', 'Mars\\?', 'Earth!') yields 'Hello, Earth!').[5]
Logical operations enable conditional logic through functions like if(condition, valueIfTrue, valueIfFalse), introduced in version 3.0.0 and updated in 3.6.0, which evaluates a boolean expression and returns one of two values (e.g., if(2 > 1, 0, 3px) yields 0).[5] Similarly, boolean(condition) converts an expression to a reusable boolean value (e.g., @isLight: boolean(50% > 40%) sets @isLight to true), also from version 3.0.0 with updates in 3.6.0.[5] Comparisons such as >, <, =, and others can be used within these functions to test numeric or value-based conditions.[15]
Color operations provide basic adjustments to color values, such as lighten(color, amount) to increase brightness by a percentage (e.g., lighten(#ff0000, 20%) yields a lighter red), integrated into the arithmetic framework since early versions.[5] These blend with numeric operations for dynamic theming.
Custom functions can be defined using mixins that return computed values, a feature introduced in version 3.5.0, allowing developers to encapsulate reusable logic like parametric calculations within mixins for broader application.[16] For example, a mixin can compute and return a derived value based on inputs, enhancing modularity without relying solely on built-ins.[16]
Nested Rules and Selectors
Nested rules and selectors in Less enable developers to organize styles hierarchically, mirroring the structure of HTML elements and minimizing repetition of parent selectors in the compiled CSS. By nesting child selectors inside a parent rule, Less automatically prepends the parent selector to the nested ones during compilation, resulting in more concise and readable code compared to flat CSS structures. This approach promotes the DRY (Don't Repeat Yourself) principle, making stylesheets easier to maintain as changes to parent selectors propagate automatically.[2] A basic example of selector nesting is as follows:.parent {
.child {
color: red;
}
}
.parent {
.child {
color: red;
}
}
.parent .child {
color: red;
}
.parent .child {
color: red;
}
margin: {
top: 10px;
bottom: 10px;
}
margin: {
top: 10px;
bottom: 10px;
}
margin-top: 10px;
margin-bottom: 10px;
margin-top: 10px;
margin-bottom: 10px;
& refers to the enclosing selector and allows self-referencing for pseudo-classes, states, or modifications. Other combinators include > for direct children, + for adjacent siblings, and ~ for general siblings. An example combining these is:
.menu {
li {
a:hover {
color: [blue](/page/Blue);
}
> ul {
display: none;
}
+ li {
margin-top: 10px;
}
}
}
.menu {
li {
a:hover {
color: [blue](/page/Blue);
}
> ul {
display: none;
}
+ li {
margin-top: 10px;
}
}
}
.menu li a:hover {
color: blue;
}
.menu li > ul {
display: none;
}
.menu li + li {
margin-top: 10px;
}
.menu li a:hover {
color: blue;
}
.menu li > ul {
display: none;
}
.menu li + li {
margin-top: 10px;
}
& combinator enables flexible constructions, such as .menu-item & { ... } to target siblings or extensions of the parent.[2]
Less permits nesting to arbitrary depths, facilitating complex hierarchies without verbosity. The & selector remains available at each level for referencing the immediate parent. For example, multi-level nesting with self-referencing:
.grandparent {
.parent {
.child {
color: black;
&:hover {
color: gray;
}
}
}
}
.grandparent {
.parent {
.child {
color: black;
&:hover {
color: gray;
}
}
}
}
.grandparent .parent .child {
color: black;
}
.grandparent .parent .child:hover {
color: gray;
}
.grandparent .parent .child {
color: black;
}
.grandparent .parent .child:hover {
color: gray;
}
@media directive, allowing at-rules to be nested similarly to selectors with bubbling behavior for responsive designs. However, nested media queries must remain within the same scope, and certain features like extends may not cross media boundaries.[2]
The primary benefit of nested rules and selectors is the significant reduction in selector duplication relative to traditional flat CSS, leading to shorter, more intuitive codebases that better reflect document structure. Nesting can also integrate with mixins for reusable hierarchical patterns.[2]
Advanced Features
Imports and Directives
In Less, the @import directive enables the inclusion of external stylesheets, promoting modular code organization by inlining the content of imported files during compilation. The standard syntax is@import "filename.less";, where the imported .less file is processed and its rules merged into the current stylesheet as if written directly.[2]
Less supports importing files in multiple formats, including .less for full processing and .css for direct inclusion without compilation, using relative or absolute paths. For example, @import "styles.css"; embeds the CSS verbatim into the output, while variable interpolation allows dynamic paths like @import "@{theme}/colors.less";, enabling reuse of variables defined in imported files across modules.[2]
Several options modify import behavior to suit different use cases: (reference) imports content without outputting it unless explicitly referenced (e.g., via mixins or extends), ideal for utility libraries; (inline) includes the file's content as a string without processing; (css) treats the file as plain CSS regardless of extension; (optional) skips the import if the file is missing, avoiding errors (introduced in v2.3.0); (once) ensures the file is imported only once (default); and (multiple) permits repeated imports. An example is @import (reference) "library.less";, which loads mixins for selective use without bloating the CSS output.[2]
Less also recognizes standard CSS directives such as @charset, which specifies the character encoding of the stylesheet, for instance @charset "UTF-8"; at the top of a file to ensure proper handling of international characters.[1]
Less implements lazy evaluation for variables. Since version 1.4.0, variables in imported files are evaluated only when referenced, reducing dependency on declaration order and supporting flexible modular structures.[2]
Best practices for imports include using (reference) for large libraries to import only needed components and (optional) for conditional or environment-specific files to prevent compilation failures; this approach aids in modularizing large stylesheets while minimizing output size. Additionally, developers should structure imports to avoid circular dependencies, where files import each other recursively, as this can cause infinite loops and compilation errors.[2][17]
Guards and Loops
Guards in Less provide conditional logic for mixins and rules, allowing developers to apply styles only when specific criteria are met. A guard is specified using thewhen keyword followed by a condition in parentheses, appended to a mixin definition or selector. For instance, a mixin can be defined as .theme(@color) when (lightness(@color) > 50%) { background-color: darken(@color, 10%); }, which applies only if the lightness of the provided color exceeds 50%.[2]
Conditions in guards support comparisons such as greater than (>), greater than or equal to (>=), equal (=), less than or equal to (=<), and less than (<), applied to variables or expressions. Logical operators enable complex conditions: and for conjunction, comma (,) for disjunction (equivalent to or), and not for negation. Type-checking functions like iscolor(@value), isnumber(@value), isstring(@value), iskeyword(@value), and isurl(@value) further refine conditions, ensuring the argument type matches before execution. For example, .border(@size) when (isnumber(@size)) { border-width: @size; } restricts the mixin to numeric inputs.[2]
Multiple guards can chain mixins to simulate if-else structures. A primary mixin with a when condition can be followed by alternatives using not or additional when clauses, with an optional default without a guard. This pattern allows fallback behaviors, such as .size(@width) when (@width > 100px) { width: @width; } .size(@width) { width: 100px; }, where the default applies if the condition fails. Guards for mixins and CSS selectors were introduced in version 1.5.0.[2][18]
Less lacks native loop constructs but simulates iteration through recursive mixins combined with guards for termination. A recursive mixin calls itself with a modified parameter until a base case guard prevents further calls. For example:
.loop(@n) when (@n > 0) {
.element-@{n} {
width: (@n * 10px);
}
.loop(@n - 1);
}
.loop(@n) when (@n > 0) {
.element-@{n} {
width: (@n * 10px);
}
.loop(@n - 1);
}
.loop(3); generates classes .element-3 { width: 30px; }, .element-2 { width: 20px; }, and .element-1 { width: 10px; }, stopping when @n <= 0. Pattern matching on argument counts or types can enhance recursion, such as distinguishing base cases by parameter arity. Recursive mixins have been supported since early versions, with enhancements like the each() function introduced in version 3.7.0 for iterating over lists or maps. The each function takes a list and an anonymous mixin, applying the mixin to each item; for example:
.each(@list, @callback) { ... } // built-in
// Usage:
@colors: red, green, blue;
.each(@colors, {
.color-@{value} { color: @value; }
});
.each(@list, @callback) { ... } // built-in
// Usage:
@colors: red, green, blue;
.each(@colors, {
.color-@{value} { color: @value; }
});
-webkit- only for certain browsers via type or value checks, and creating responsive breakpoints by iterating over a list of media query sizes. For instance, a recursive mixin or each() can produce multiple @media rules for widths from 320px to 1200px, streamlining mobile-first designs. These mechanisms integrate with Less functions for evaluating conditions, such as using arithmetic in guards.[2][20]
Color Functions
Less provides a suite of built-in color functions that enable developers to manipulate and generate colors dynamically within stylesheets, facilitating theme creation and responsive design adjustments. These functions operate primarily in HSL (Hue, Saturation, Lightness) color space for adjustments, allowing precise control over color properties without manual RGB calculations. They accept color objects, such as hex values like#ff0000 or HSL notations, and output standard CSS-compatible colors.[5]
Basic adjustment functions include lighten and darken, which modify the lightness component of a color. The lighten(@color, @amount) function increases lightness by a specified percentage (0-100%), for example, lighten(#ff0000, 10%) results in #ff6666, a brighter red. Conversely, darken(@color, @amount) decreases lightness, such as darken(hsl(90, 80%, 50%), 20%) yielding #4d8a0f, a darker green. Both functions support an optional method parameter set to "relative" for proportional changes relative to the original lightness.[5]
For hue and saturation manipulation, Less offers functions like spin and saturate. The spin(@color, @degrees) function rotates the hue angle by the given degrees (positive or negative, wrapping around 0-360°), as in spin(hsl(10, 90%, 50%), 30) producing #f2a60d, shifting from a reddish to a yellowish tone. The saturate(@color, @amount) function boosts saturation by a percentage, for instance, saturate(hsl(90, 80%, 50%), 20%) outputs #80ff00, intensifying the green vibrancy. These tools are essential for creating color harmonies and variations in design systems.[5]
Blending capabilities are provided by the mix function, which interpolates between two colors based on a weight. The syntax mix(@color1, @color2, @weight: 50%) computes a weighted average, respecting opacity if present; for example, mix(#ff0000, #0000ff, 50%) generates #800080, a purple midpoint between red and blue. This function handles alpha channels by blending opacities proportionally.[5]
Opacity-related functions include fade and alpha. The fade(@color, @amount) sets the absolute opacity to a percentage (0-100%), converting to RGBA if necessary, such as fade(hsl(90, 90%, 50%), 10%) resulting in rgba(128, 242, 13, 0.1). The alpha(@color) extracts the current opacity as a float (0-1), like alpha(rgba(10, 20, 30, 0.5)) returning 0.5, useful for conditional styling.[5]
Color format conversions are supported through constructor functions like hsl and rgb. The hsl(@hue, @saturation, @lightness) creates an opaque color from HSL values, where parameters can be percentages or decimals (hue as 0-360 integer); for example, hsl(90, 100%, 50%) yields #80ff00. Similarly, rgb(@red, @green, @blue) builds from RGB components (0-255 integers or 0-100% percentages), such as rgb(90, 129, 32) producing #5a8120. These enable programmatic color definition in Less code.[5]
Advanced blending shortcuts include tint and shade, which are aliases for mix with white or black, respectively. The tint(@color, @weight: 50%) mixes with white to lighten, for instance, tint(#007fff, 50%) outputs #80bfff, a pastel blue. The shade(@color, @weight: 50%) mixes with black to darken, like shade(#007fff, 50%) resulting in #004080, a deeper navy. These simplify common operations for generating color scales in themes.[5]
Compilation and Implementation
Compiling to CSS
The Less compiler processes source files with a .less extension by parsing the syntax tree, resolving variables and mixins through substitution and evaluation, expanding nested rules into flat CSS selectors, and generating valid CSS output. This transformation ensures that dynamic features like operations and functions are computed and inlined, resulting in static CSS that browsers can interpret directly. For instance, a nested rule such as.parent { .child { color: red; } } is expanded to .parent .child { color: red; } during this phase.[21][2]
The primary tool for server-side compilation is lessc, a command-line interface provided by the official Less.js package, which requires Node.js and is installed globally via npm install -g less. Users invoke it with the syntax lessc [options] input.less [output.css], redirecting output to a file if needed, such as lessc styles.less > styles.css; stdin support allows piping input for dynamic workflows.[22]
Output can be customized for production use, including minification via the --compress flag to remove whitespace and comments, though this option is deprecated in favor of external tools like cssnano for better optimization; expanded, human-readable CSS is the default. Source maps, which map compiled CSS back to original Less lines for debugging, are generated using --source-map, with --source-map-include-sources embedding the Less source for completeness.[23][24]
Error handling during compilation includes detailed reporting of syntax errors, parse failures, or invalid operations, complete with line and column numbers in the source file for quick identification. Options like --math=parens-division (default in v4.0) enforce precise mathematical evaluations without silent approximations, throwing errors on ambiguous divisions, while --strict-units=on treats mismatched unit calculations (e.g., 1px / 2) as errors rather than coercing to unitless values; since version 3.0, these modes help surface potential issues as warnings or errors in linting runs via --lint. The --silent flag suppresses non-critical warnings to streamline output.[23][25]
The compiled output adheres to CSS 2.1 and later specifications, ensuring broad browser compatibility without proprietary extensions. Vendor-specific prefixes (e.g., -webkit- for gradients) are not added by default but can be automatically applied post-compilation using the official less-plugin-autoprefix, which integrates Autoprefixer based on Can I Use data; installation via npm install -g less-plugin-autoprefix allows usage as lessc --autoprefix="defaults" input.less output.css.[26][27]
Client-side vs Server-side Usage
Less, a dynamic stylesheet language, can be processed either client-side or server-side, each approach offering distinct advantages and trade-offs in terms of performance, development workflow, and deployment. Client-side compilation involves loading Less files directly in the browser using the Less.js JavaScript library, which dynamically converts.less files to CSS at runtime. This method requires including a <script> tag for Less.js and linking stylesheets with rel="stylesheet/less", as in <link rel="stylesheet/less" type="text/css" href="styles.less" rel="nofollow" />.[3]
One key benefit of client-side usage is the facilitation of live editing and real-time adjustments during development, such as modifying variables on the fly with functions like less.modifyVars(). However, it introduces drawbacks including a performance overhead from in-browser compilation, potential JavaScript errors that could disrupt rendering, and larger initial payloads due to transmitting both Less source files and the Less.js runtime (approximately 155 kB minified). Less.js supports modern browsers, including recent versions of Chrome, Firefox, Safari, and Edge, but lacks native compatibility with older browsers like Internet Explorer without additional polyfills.[3][3]
In contrast, server-side compilation pre-processes Less files into standard CSS before deployment, typically using the lessc command-line tool with Node.js, as in lessc styles.less styles.css. This approach yields faster page loads since browsers receive optimized CSS without needing to compile anything, eliminates JavaScript dependencies for styling, and ensures consistent output across all environments. The main limitations are the need for a build step—requiring recompilation whenever source files change—and initial setup of a Node.js environment. It supports source maps for debugging and plugins like clean-css for further minification, making it suitable for production static sites.[3][3]
A hybrid strategy often bridges these methods by employing client-side compilation for iterative development—allowing quick previews and tweaks—while switching to server-side precompilation for production releases. Development workflows commonly incorporate file watchers that automatically trigger recompilation on changes, streamlining the transition without manual intervention each time.[3]
From a security perspective, client-side processing exposes the full Less source code to end-users, as .less files are fetched and parsed in the browser, potentially revealing implementation details or proprietary mixins. Server-side compilation mitigates this by serving only the final CSS, keeping logic hidden from clients. Additionally, client-side execution carries risks of runtime vulnerabilities, such as remote code execution flaws in older Less.js versions if importing untrusted resources.[3][28]
Over time, usage has shifted toward server-side compilation, particularly after 2015, as advancements in HTTP/2 multiplexing and modern bundlers like Webpack reduced the need for client-side processing in static deployments, favoring prebuilt assets for better caching and reduced latency. Official documentation by the 2020s emphasizes client-side primarily for dynamic theming or prototyping, while deprecating it for production in favor of server-side for reliability and speed.[3][29]
Tools and Integrations
Official Software
The core software for Less is the less.js library, a JavaScript implementation that enables client-side compilation of Less stylesheets into CSS, supporting dynamic features like variables and mixins in the browser.[1] As of November 2025, the latest version is 4.4.2, which includes enhancements to the parser for better performance and compatibility with modern JavaScript environments.[7] The library is hosted and actively maintained on GitHub, where it receives regular updates from contributors to address bugs and add features.[9] Bundled with less.js is lessc, the official command-line interface (CLI) compiler for server-side processing of Less files into CSS, installable globally via Node.js with the commandnpm install -g less.[3] Usage involves running lessc input.less output.css to compile a file, with options for minification, source maps, and plugin integration directly from the terminal on Unix, OS X, or Windows systems.[3]
For quick prototyping, the official online playground at lesscss.org/less-preview/ provides a browser-based environment to write, compile, and preview Less snippets in real-time, demonstrating features like nesting and functions without local setup.[30]
Less supports an official plugin API introduced in version 3.0, allowing developers to extend functionality with custom functions, such as color manipulation plugins, by loading modules like less-plugin-* via npm during compilation.[31][3]
There is no official integrated development environment (IDE) for Less, though Visual Studio Code offers built-in syntax highlighting and IntelliSense for .less files to aid editing.[32] Third-party extensions can further enhance this support, but core documentation emphasizes the library's lightweight nature over specialized tools.[33]
As of 2025, Less remains under active maintenance on GitHub, with the latest releases ensuring compatibility with current web standards and Node.js versions.[6]
Build Tool Integrations
Less integrates with various build tools in the Node.js ecosystem, enabling automated compilation of Less files into CSS during development workflows. The grunt-contrib-less plugin, a core component for Grunt-based projects, processes Less files by leveraging the official Less compiler and supports options like source maps and minification for efficient task automation. Similarly, gulp-less serves as a stream-based plugin for Gulp, allowing seamless integration into piping workflows where Less compilation occurs alongside other transformations like concatenation or autoprefixing. For Webpack, the less-loader module handles Less file processing within the bundling pipeline, supporting features such as CSS modules and hot module replacement when configured appropriately. In popular frontend frameworks, Less receives built-in or configurable support through their command-line interfaces. Angular CLI enables Less usage via theng add @angular-builders/custom-webpack schematic or direct configuration in angular.json, allowing developers to replace default CSS with Less without ejecting the project structure. Vue CLI provides native Less support during project initialization with the --css less flag, compiling Less stylesheets as part of the Vue single-file component pipeline. For React applications created with Create React App, Less integration requires custom configuration using tools like CRACO or react-app-rewired to override the default webpack.config.js and include less-loader.
Modern bundlers continue to offer Less plugins, emphasizing speed and developer experience. Community plugins such as vite-plugin-less extend Vite's ecosystem, providing hot module replacement (HMR) for Less changes and full support for Less features like mixins and variables, with compatibility for recent Vite versions including Vite 5's esbuild-powered builds.[34] The esbuild-plugin-less plugin optimizes Less compilation for esbuild's ultra-fast bundling, supporting imports, variables, and mixins while minimizing build times in serverless or edge deployments.[35]
Less can also integrate with PostCSS workflows via plugins like postcss-less, which parses Less syntax directly in PostCSS pipelines for hybrid processing, such as applying autoprefixer or custom transformations to Less source before final CSS output.[36] This enables less-to-postcss conversions in tools like Gulp or Webpack for mixed preprocessor environments.[37]
As of 2025, new integrations for Less in build tools have declined, driven by the maturation of native CSS features like custom properties, nesting, and color functions, which reduce reliance on preprocessors.[38] less-loader for Webpack has seen continued updates, including version 12.3.0 released in May 2025, which added support for Node.js 18.12.0 and later.[39]
Comparisons with Other Preprocessors
Comparison with Sass
Less and Sass are both CSS preprocessors that extend CSS with features like variables and mixins, but they differ in syntax, capabilities, and implementation philosophies. Less aims for a CSS-like syntax to ease the transition for developers familiar with standard CSS, using the@ symbol for variables (e.g., @primary-color: #428bca;) and requiring semicolons to terminate statements, mirroring CSS conventions.[2] In contrast, Sass employs the $ prefix for variables (e.g., $primary-color: #428bca;) in its SCSS syntax, which is largely CSS-compatible and also mandates semicolons, while its indented Sass syntax omits them for a more concise, whitespace-sensitive structure.[40][41]
Both preprocessors support mixins for reusable code blocks, allowing parametric definitions to generate styles dynamically; for example, Less defines a mixin as .border-radius(@radius) { border-radius: @radius; }, while Sass uses @mixin border-radius($radius) { border-radius: $radius; } with @include for invocation.[2][42] However, Sass provides more advanced control structures, including true loops like @for (e.g., @for $i from 1 through 3 { .col-#{$i} { width: $i * 200px; } }) and @while for conditional iteration, enabling complex repetitions without workarounds. Less lacks native loops, instead simulating them through recursive guarded mixins (e.g., .loop(@counter) when (@counter > 0) { /* styles */ .loop((@counter - 1)); }), which can lead to deeper recursion limits in large projects.[2] Sass's control directives, such as @if/@else, are also more robust for logic, offering greater expressiveness for intricate stylesheets compared to Less's guard-based conditionals.[43]
In terms of compilation, Less originated as a JavaScript library for dynamic, client-side processing via Less.js, though it now supports server-side compilation with Node.js for better performance and security.[3] Sass, initially Ruby-based, has transitioned to a Dart implementation (Dart Sass) for faster, stricter parsing, emphasizing error-checking and modularity over Less's more lenient, dynamic evaluation.[44] This makes Sass suitable for larger-scale applications where parsing rigor prevents subtle bugs, while Less's flexibility appeals to rapid prototyping in JavaScript environments.[43]
The ecosystems reflect their origins: Sass thrives in Ruby-centric stacks like Ruby on Rails, where it serves as the default preprocessor with extensive libraries such as Compass for grid systems and Bourbon for mixins.[43] Less integrates seamlessly with Node.js and JavaScript frameworks like Bootstrap, benefiting from tools like Grunt and Webpack plugins, but its library ecosystem is less mature and more fragmented.[43]
| Aspect | Less | Sass |
|---|---|---|
| Variables | @var: value; (CSS-like) | $var: value; (SCSS) or indented (Sass) |
| Semicolons | Required | Required in SCSS; optional in indented Sass |
| Loops | Simulated via recursive mixins | Native @for, @while, @each |
| Compilation | JavaScript (client/server-side) | Dart (formerly Ruby); server-side focused |
| Ecosystem | Strong in JS/Node.js; e.g., Bootstrap integration | Dominant in Ruby/Rails; libraries like Compass, Bourbon |
Comparison with Stylus
Less and Stylus are both JavaScript-based CSS preprocessors, but they differ significantly in syntax flexibility, aiming to extend CSS in complementary ways. Less maintains a syntax closely resembling standard CSS, requiring curly braces to enclose blocks and semicolons to terminate declarations, which makes it familiar for developers transitioning from plain CSS. In contrast, Stylus employs an indentation-based syntax inspired by languages like Python and CoffeeScript, where braces and semicolons are optional, allowing for more concise code with significant whitespace defining structure.[47] This indentation approach in Stylus reduces verbosity, enabling cleaner, more readable stylesheets without punctuation overhead, though it may require adjustment for those accustomed to CSS conventions.[48] Variable declaration in Less uses the@ prefix (e.g., @primary-color: #blue;), providing straightforward assignment and basic interpolation within selectors or properties. Stylus offers greater flexibility, supporting assignment with = (e.g., primary-color = #blue) or the $ prefix (e.g., $primary-color = #blue), and enables advanced interpolation through curly braces (e.g., selector-{primary-color}) or direct property referencing with @ (e.g., @width to pull from existing declarations).[47] This makes Stylus variables more dynamic for complex expressions and runtime-like substitutions compared to Less's more static handling.
In terms of features, both preprocessors support mixins for reusable code blocks—Less via parametric mixins (e.g., .bordered(@width: 1px) { border: @width solid black; }), and Stylus through similar definitions with optional parentheses and block support (e.g., bordered(width = 1px) { border: width solid black; }).[49] However, Stylus includes native loops (e.g., for num in 1..5 { .item-{num} { width: num * 20%; } }) and conditionals (e.g., if active { display: block; }), facilitating iterative and logic-based generation without workarounds.[50] Less lacks built-in loops, relying instead on recursive mixins or guards for conditional logic (e.g., @if { ... }), which can lead to more verbose implementations for repetitive tasks.
Both are compiled using JavaScript engines—Less via the Less.js library for client- or server-side processing, and Stylus optimized for Node.js with a command-line interface (e.g., stylus input.styl -o output.css).[48] Stylus generally offers faster parsing and compilation speeds due to its streamlined lexer, particularly for large files, and provides extensibility through direct JavaScript plugins that integrate seamlessly with its runtime.[51] Less compilation, while efficient, is less plugin-oriented and more focused on pure CSS output without deep runtime modifications.
Philosophically, Less positions itself as a superset of CSS, emphasizing backward compatibility and minimal extensions to enhance maintainability without altering core CSS paradigms.[52] Stylus adopts a minimalist ethos, prioritizing expressiveness and reduced boilerplate to generate dynamic CSS, often described as a "CoffeeScript for stylesheets" for its concise, indentation-driven design.[48]
As of 2025, both Less and Stylus remain niche tools, with Less carrying more legacy usage in older projects and Stylus favored in Node.js environments for its speed; however, their adoption has declined as native CSS features like custom properties, nesting, and calc() functions replicate much of their utility, reducing the need for preprocessing in modern workflows. In July 2025, the Stylus NPM package was temporarily removed due to a security incident involving malicious activity but was restored shortly thereafter.[45][53][54]