Обзор

Less (Leaner Style Sheets) - это обратно совместимое расширение CSS. Здесь собрана официальная документация по самому языку Less и по Less.js, JavaScript-компилятору, который превращает код Less в обычный CSS.

Поскольку синтаксис Less почти не отличается от CSS, войти в него очень легко. Язык добавляет к CSS всего несколько действительно полезных возможностей, поэтому его можно освоить быстро и без лишнего порога входа.

Что именно Less добавляет к CSS? Ниже - короткий обзор.

Переменные

Здесь все довольно очевидно:

@width: 10px;
@height: @width + 10px;

#header {
  width: @width;
  height: @height;
}

Вывод:

#header {
  width: 10px;
  height: 20px;
}

Подробнее о переменных

Миксины

Миксины позволяют подмешивать набор свойств из одного блока правил в другой. Допустим, у нас есть такой класс:

.bordered {
  border-top: dotted 1px black;
  border-bottom: solid 2px black;
}

И теперь мы хотим использовать эти свойства в других блоках. Для этого достаточно вызвать имя класса там, где нужны его свойства:

#menu a {
  color: #111;
  .bordered();
}

.post a {
  color: red;
  .bordered();
}

Свойства класса .bordered будут подставлены и в #menu a, и в .post a. Обратите внимание: в роли миксинов можно использовать и #id-селекторы.

Подробнее о миксинах

Вложенность

Less позволяет писать вложенные правила вместо длинных каскадных селекторов или вместе с ними. Допустим, у нас есть такой CSS:

#header {
  color: black;
}
#header .navigation {
  font-size: 12px;
}
#header .logo {
  width: 300px;
}

В Less это можно записать так:

#header {
  color: black;
  .navigation {
    font-size: 12px;
  }
  .logo {
    width: 300px;
  }
}

Такой код короче и лучше повторяет структуру HTML.

Тем же способом можно связывать с миксинами и псевдоселекторы. Вот классический clearfix, переписанный как миксин. Символ & обозначает текущий родительский селектор:

.clearfix {
  display: block;
  zoom: 1;

  &:after {
    content: " ";
    display: block;
    font-size: 0;
    height: 0;
    clear: both;
    visibility: hidden;
  }
}

Подробнее о родительских селекторах

Вложенные at-правила и всплытие

At-правила вроде @media и @supports можно вкладывать так же, как селекторы. Само правило поднимается наверх, а порядок элементов внутри того же блока сохраняется. Это поведение называется всплытием.

.component {
  width: 300px;
  @media (min-width: 768px) {
    width: 600px;
    @media  (min-resolution: 192dpi) {
      background-image: url(/img/retina2x.png);
    }
  }
  @media (min-width: 1280px) {
    width: 800px;
  }
}

Результат:

.component {
  width: 300px;
}
@media (min-width: 768px) {
  .component {
    width: 600px;
  }
}
@media (min-width: 768px) and (min-resolution: 192dpi) {
  .component {
    background-image: url(/img/retina2x.png);
  }
}
@media (min-width: 1280px) {
  .component {
    width: 800px;
  }
}

Операции

Арифметические операции +, -, *, / могут работать с числами, цветами и переменными. Если это возможно, Less учитывает единицы измерения и приводит значения к совместимому виду перед сложением, вычитанием или сравнением. Результат получает тип единицы из левого явно указанного операнда. Если преобразование невозможно или бессмысленно, единицы просто игнорируются. Например, нельзя адекватно перевести px в cm или rad в %.

// numbers are converted into the same units
@conversion-1: 5cm + 10mm; // result is 6cm
@conversion-2: 2 - 3cm - 5mm; // result is -1.5cm

// conversion is impossible
@incompatible-units: 2 + 5px - 3cm; // result is 4px

// example with variables
@base: 5%;
@filler: @base * 2; // result is 10%
@other: @base + @filler; // result is 15%

Умножение и деление единицы не преобразуют. В большинстве случаев это и не нужно: длина, умноженная на длину, дает площадь, а CSS не умеет задавать площади как тип значения. Поэтому Less работает с числами как есть и присваивает результату явно указанную единицу.

@base: 2cm * 3mm; // result is 6cm

С цветами тоже можно выполнять арифметические операции:

@color: (#224488 / 2); // result is #112244
background-color: #112244 + #111; // result is #223355

Но на практике чаще удобнее пользоваться цветовыми функциями Less.

Начиная с версии 4.0 деление вне круглых скобок через / не выполняется.

@color: #222 / 2; // results in `#222 / 2`, not #111
background-color: (#FFFFFF / 16); //results is #101010

При желании это можно изменить настройкой Math, но по умолчанию так безопаснее и понятнее.

Исключение для calc()

Выпущено в v3.0.0

Для совместимости с CSS функция calc() не вычисляет выражение целиком, но подставляет переменные и считает математику внутри вложенных функций.

@var: 50vh/2;
width: calc(50% + (@var - 20px));  // result is calc(50% + (25vh - 20px))

Экранирование

Экранирование позволяет использовать произвольную строку как значение свойства или переменной. Все, что записано внутри ~"anything" или ~'anything', вставляется без изменений, кроме интерполяции.

@min768: ~"(min-width: 768px)";
.element {
  @media @min768 {
    font-size: 1.2rem;
  }
}

Получаем:

@media (min-width: 768px) {
  .element {
    font-size: 1.2rem;
  }
}

Начиная с Less 3.5 это можно записать и проще:

@min768: (min-width: 768px);
.element {
  @media @min768 {
    font-size: 1.2rem;
  }
}

В версиях 3.5+ многие случаи, где раньше требовалось экранирование кавычек, больше не нужны.

Функции

Less включает множество функций для работы с цветами, строками и вычислениями. Полное описание есть в справке по функциям.

Пользоваться ими просто. В следующем примере percentage превращает 0.5 в 50%, saturate увеличивает насыщенность базового цвета на 5%, а spin(lighten(...)) задает фоновый цвет, осветленный на 25% и повернутый на 8 градусов по цветовому кругу:

@base: #f04615;
@width: 0.5;

.class {
  width: percentage(@width); // returns `50%`
  color: saturate(@base, 5%);
  background-color: spin(lighten(@base, 25%), 8);
}

См. справочник по функциям

Пространства имен и доступ к значениям

(Не путать с CSS @namespace или селекторами пространства имен.)

Иногда удобно сгруппировать миксины просто ради порядка или чтобы слегка инкапсулировать набор правил. В Less это делается очень естественно. Допустим, вы хотите собрать несколько миксинов и переменных под пространством имен #bundle, чтобы потом переиспользовать или распространять их как единый набор:

#bundle() {
  .button {
    display: block;
    border: 1px solid black;
    background-color: grey;
    &:hover {
      background-color: white;
    }
  }
  .tab { ... }
  .citation { ... }
}

Теперь, если мы хотим подмешать класс .button в #header a, можно написать так:

#header a {
  color: orange;
  #bundle.button();  // can also be written as #bundle > .button
}

Примечание: если не хотите, чтобы пространство имен попало в итоговый CSS, добавляйте к нему () - например, #bundle().

Карты

Начиная с Less 3.5 миксины и блоки правил можно использовать и как карты значений.

#colors() {
  primary: blue;
  secondary: green;
}

.button {
  color: #colors[primary];
  border: 1px solid #colors[secondary];
}

Результат будет именно таким:

.button {
  color: blue;
  border: 1px solid green;
}

См. также: Карты

Область видимости

Область видимости в Less очень похожа на CSS. Сначала переменные и миксины ищутся локально, а если не находятся, поиск поднимается в родительскую область.

@var: red;

#page {
  @var: white;
  #header {
    color: @var; // white
  }
}

Как и в случае с CSS custom properties, определения миксинов и переменных не обязательно ставить выше строки, где они используются. Поэтому следующий код Less полностью эквивалентен предыдущему примеру:

@var: red;

#page {
  #header {
    color: @var; // white
  }
  @var: white;
}

См. также: Ленивая загрузка

Комментарии

Можно использовать и блочные, и однострочные комментарии:

/* One heck of a block
 * style comment! */
@var: red;

// Get in line!
@var: white;

Импорт

Импорт работает почти так, как вы ожидаете. Можно подключать .less-файлы, и все объявленные в них переменные будут доступны. Для файлов .less расширение указывать необязательно.

@import "library"; // library.less
@import "typo.css";

Подробнее об импорте