Popular Tags

Less (Leaner Style Sheets)

Learn about Less syntax, files structure, Less variables, and more.

Less (Leaner Style Sheets)

Contents

  1. How To Install Less
  2. How to Compile Less
  3. How to Import Multiple Less Files
  4. Syntax

Less (Leaner Style Sheets) is a CSS preprocessor, an extension of the syntax of CSS. Files using Less syntax have the .less extension. 

In many ways, Less is similar to SCSS: both use nesting, variables, extends, mixins, and maps. However, Less has more options and doesn’t require to install Ruby.

How To Install Less

To install Less, you need the command line (CMD). Once the command prompt is open, type the following command: npm install less -g, like this:

    
        
Microsoft Windows [Version 10.0.17763.615]

Shark@DESKTOP-8K49678 C:\Users\Shark
$ npm install less -g
    

The -g option installs Less globally. After installing, your CMD will look like this:

    
        
Microsoft Windows [Version 10.0.17763.615]

Shark@DESKTOP-8K49678 C:\Users\Shark
$ npm install less -g
C:\Users\Shark\AppData\Roaming\npm\lessc -> C:\Users\Shark\AppData\Roaming\npm\node_modules\less\bin\lessc
+ less@3.9.0
added 60 packages from 123 contributors in 4.406s
    

How to Compile Less

If you use an IDE, you can install a plugin inside your IDE to compile LESS. Alternatively, you can use the CMD. It’s not difficult at all.

Type in the CMD the following command and press Enter:

    
        
npm install -g less-watch-compiler
    

The result will look like this:

    
        
Shark@DESKTOP-8K49678 C:\Users\Shark
$ npm install -g less-watch-compiler
C:\Users\Shark\AppData\Roaming\npm\less-watch-compiler -> C:\Users\Shark\AppData\Roaming\npm\node_modules\less-watch-compiler\dist\less-watch-compiler.js
+ less-watch-compiler@1.13.0
added 83 packages from 138 contributors in 7.078s
    

Next, create two folders, say, src (which will contain .less files) and dist (which will contain the compiled .css file). Below is an example of the file structure:

    
        
root 
 └──src
 │    └── main.less
 │    └── ....less
 └──dist
      └── main.css
    

You can create the main.less file and put it into your src folder. It will contain imports of other .less files.

After that, indicate in the CMD the path to the folder that contains src and dist files, for example: 

    
        
cd C:\Users\Shark\Documents\Projects\Test
    

One it’s done, you have one of two methods to choose.

Method 1: Continue with the CMD

Type in the CMD the following command:

    
        
less-watch-compiler src dist main.less
    

less-watch-compiler is the command, src is the folder containing your main.less and other .less files, dist is the folder with the compiled main.css file.

Here is the template:

    
        
less-watch-compiler [options] <source_dir> <destination_dir> [main-file]
    

[options] and [main-file] are not required.

After typing the command, your CMD will look like this:

    
        
less-watch-compiler src dist main.less
Watching directory for file changes.
    

It means that all changes in .less files will be detected and compiled to CSS every time you save the changes.

Method 2: Create a JSON File

Create a file with the name less-watch-compiler.config.json and put it in the root of your project. Put inside it the following:

    
        
{
    "watchFolder": "src",
    "outputFolder": "dist",
    "mainFile": "main.less"
}
    

By default, “minified” is turned on to always compress the output. You can set the minification to false by adding "minified": false in the config file.

Finally, type in the CMD the following and press Enter:

    
        
less-watch-compiler
    

If you type some Less code in one of your Less files and press Ctrl+S, those files will be automatically compiled to .css files and the CMD will show an indication that a certain file was changed and will show a path to a new .css file.

You need to type in the CMD the less-watch-compiler command every time you launch your project. Otherwise, changes won’t be watched and your .less files won’t be compiled. 

How to Import Multiple Less Files

Like SCSS, Less allows splitting the code over several files. You put rules for each component and layout element into its own file and create different files for fonts, variables, and mixins. It helps make your code easier to maintain and reuse.

Below is an example of how your file architecture can look like:

    
        
css/
|
|--dist
| |--main.css      // Compiled CSS file
|
|--src
| |--main.less     // Main Less file where you import all other Less files
| |-- helpers/     // Special files
| | |-- variables.less
| | |-- mixins.less
|
| |-- base/        // Base files
| | |-- reset.less
| | |-- grid.less
| | |-- fonts.less
|
| |-- layout/      // Files with page elements’ styles 
| | |-- header.less
| | |-- navigation.less
| | |-- footer.less
| | |-- sidebar.less
| | |-- form.less
|
| |-- components/  // Smaller components’ styles
| | |-- buttons.less
| | |-- dropdown.less
| | |-- popup.less
| | |-- carousel.less
|
| |–- pages/       // Page specific styles
| | |–- home.less         
| | |–- contact.less
| | |–- about.less      
|
| |–- vendors/      // Vendors’ files (Bootstrap, jQuery UI, etc.)
| | |–- bootstrap.less    
| | |–- jquery-ui.less
    

The main Less file (main.less) includes only imports of all other Less files. It may look like this:

    
        
@import 'helpers/variables';  
@import 'helpers/mixins';     
         
@import 'base/reset';
@import 'base/grid';
@import 'base/fonts';

@import 'layout/header';
@import 'layout/navigation';
@import 'layout/footer';
@import 'layout/sidebar';
@import 'layout/form';

@import 'components/buttons';
@import 'components/dropdown';
@import 'components/popup';
@import 'components/carousel';

@import 'pages/home';
@import 'pages/contact';
@import 'pages/about';

@import 'vendors/bootstrap';
@import 'vendors/jquery-ui';
    

Less uses lazy loading, so it doesn’t matter where you import the variables.less.

For the sake of readability, you’d better omit file extensions and underscores in the main file. Also, use one file per import, one @import per line, and add a new line after the last import from a folder.

Syntax

To start using Less, it’s enough to know just five basic things: nesting, variables, extends, mixins, and maps.

Nesting

Like Sass, Less allows CSS rules to be nested within one another. The inner rule only applies within the outer parent’s selector. For example:

    
        
main {
  width: 60%;
  margin: 0 auto;

  .article {
    background-color: #fff;
  }

  h1 {
    text-align: center;
  }
}
    

You can write pseudo-classes in a much less repetitive way using the & operator.

    
        
a {
  color: blue;
  
  &:hover {
    color: green;
  }
}
    

Compiles to:

    
        
a {
  color: blue;
}

a:hover {
  color: green;
}
    

The & operator is useful to produce repetitive class names:

    
        
.button {
  padding: 5px 12px;
  border-radius: 5px;

  &-ok {
    background-image: url('ok.png');
  }
  
  &-cancel {
    background-image: url('cancel.png');
  }
}
    

Compiles to:

    
        
.button {
  padding: 5px 12px;
  border-radius: 5px;
}

.button-ok {
  background-image: url('ok.png');
}

.button-cancel {
  background-image: url('cancel.png');
}
    

Variables

Variables allow reusing styles without having to copy them over and over again. Use a variable if the value is repeated at least twice and is likely to be updated at least once. To declare a variable, use the @ sign:

    
        
@color-font: #333;
    

You can use the declared variables anywhere in the Less files of your project:

    
        
color: @color-font;
    

Selector names, property names, URLs and @import statements can also be used as variables. Sometimes this can make your code a little lighter and more reusable.

Selectors

    
        
@selector: box;

.@{selector}__left {
  margin: 0 auto;
  border: 1px solid #333;
}
    

Compiles to:

    
        
.box__left {
  margin: 0 auto;
  border: 1px solid #333;
}
    

Properties

    
        
.item {
  color: #333;
  border: 1px solid $color;
}
    

Compiles to:

    
        
.item {
  color: #333;
  border: 1px solid #333;
}
    

URLs

    
        
@images: '../img';

.item {
  color: #333;
  background: url('@{images}/shark.jpg');
}
    

Compiles to:

    
        
.item {
  color: #333;
  background: url('../img/shark.jpg');
}
    

Import Statements

    
        
@themes: '../../src/themes';

@import '@{themes}/dark.less';
    

Extends

Extends make it possible to extend styles of one selector to the styles of another one. You can extend styles of one or several elements at once. For example:

    
        
.inline {
  color: red;
}

button {
  border-radius: 5px;
}

nav ul {
  &:extend(.inline, button);
  background: blue;
}
    

Compiles to:

    
        
.inline,
nav ul {
  color: red;
}

button,
nav ul {
  border-radius: 5px;
}

nav ul {
  background: blue;
}
    

Extend is not able to match selectors with variables. If a selector contains a variable, extend will ignore it.

    
        
@variable: .item;
@{variable} { 
  color: blue;
}

.box:extend(.item) {} // does nothing
    

An :extend inside a @media declaration will only match selectors inside the same media declaration:

    
        
@media print {
  .screenClass:extend(.selector) {} // extend inside media
  .selector { // this will be matched — it is in the same media
    color: black;
  }
}
.selector { // ruleset on top of style sheet — extend ignores it
  color: red;
}

@media screen {
  .selector {  // ruleset inside another media — extend ignores it
    color: blue;
  }
}
    

Mixins

Mixins allow defining styles that can be reused throughout the stylesheet. If you find a group of CSS properties that always appear together for a reason, you can put them in a mixin.

A mixin reference can supply parameters values by their names. Any parameter can be referenced by its name and they do not have to be in any special order:

    
        
.mixin(@color: black; @margin: 10px; @padding: 20px) {
  color: @color;
  margin: @margin;
  padding: @padding;
}

.class1 {
  .mixin(@margin: 20px; @color: #333);
}

.class2 {
  .mixin(#efca44; @padding: 40px);
}
    

Compiles to:

    
        
.class1 {
  color: #333;
  margin: 20px;
  padding: 20px;
}

.class2 {
  color: #888;
  margin: 10px;
  padding: 40px;
}
    

There is the @arguments variable that contains all the arguments passed, when the mixin was called. This is useful if you don’t want to deal with individual parameters:

    
        
.box-shadow(@x: 0; @y: 0; @blur: 1px; @color: #000) {
  -webkit-box-shadow: @arguments;
  -moz-box-shadow: @arguments;
  box-shadow: @arguments;
}
.big-block {
  .box-shadow(2px; 5px);
}
    

Compiles to:

    
        
.big-block {
  -webkit-box-shadow: 2px 5px 1px #000;
  -moz-box-shadow: 2px 5px 1px #000;
  box-shadow: 2px 5px 1px #000;
}
    

Less is able to create “guarded mixins”. These are mixins that only take effect when a certain condition is true. For example, you want to set a background color based on the current text color. If the text color is light you’ll need a darker background. And if the text color is dark you’ll need a lighter background. So you have to create a single mixin broken into two parts with these guards that ensure that only one of them takes effect:

    
        
.set-bg-color (@text-color) when (lightness(@text-color) >= 50%) {
  background: black;
}

.set-bg-color (@text-color) when (lightness(@text-color) < 50%) {
  background: grey;
}
    

When you use it, you’ll get the correct background:

    
        
.box-1 {
  color: white;
  .set-bg-color(white);
}

.box-2 {
  color: black;
  .set-bg-color(black);
}
    

Compiles to:

    
        
.box-1 {
  color: white;
  background: black;
}

.box-2 {
  color: black;
  background: grey;
}
    

Maps

A detached ruleset is a group of css properties, nested rulesets, media declarations or anything else stored in a variable:

    
        
@detached-ruleset: { background: blue; }; 

.item {
  @detached-ruleset(); 
}
    

By combining namespacing with the lookup [] syntax, you can turn your rulesets into maps:

    
        
@sizes: {
  mobile: 320px;
  tablet: 768px;
  desktop: 1024px;
}

.navbar {
  display: block;

  @media (min-width: @sizes[tablet]) {
    display: inline-block;
  }
}
    

Compiles to:

    
        
.navbar {
  display: block;
}

@media (min-width: 768px) {
  .navbar {
    display: inline-block;
  }
}
    

The official guide to all Less features: lesscss.org/features.