Открыть меню    

Less

lesscss.org

Приступая к работе с LESS

Приступая к работе с LESS Less это препроцессор CSS, а это значит: less (надстройка языка CSS) расширяет язык CSS, добавляет возможность использовать переменные, функции, примеси, и много других техник, которые, в свою очередь, позволяют сделать CSS управляемым и расширяемым.

Less работает внутри Node, в браузере, и внутри Rhino. Есть также много сторонних инструментов, которые позволяют компилировать ваши файлы и наблюдать за изменениями.

Например:

LESS

    @base: #f938ab;

.box-shadow(@style, @c) when (iscolor(@c)) {
  -webkit-box-shadow: @style @c;
  box-shadow:         @style @c;
}
.box-shadow(@style, @alpha: 50%) when (isnumber(@alpha)) {
  .box-shadow(@style, rgba(0, 0, 0, @alpha));
}
.box {
  color: saturate(@base, 5%);
  border-color: lighten(@base, 30%);
  div { .box-shadow(0 0 5px, 30%) }
}

Компилируется в:

CSS

    .box {
  color: #fe33ac;
  border-color: #fdcdea;
}
.box div {
  -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
  box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
}

Использование на клиентской стороне

Использование less.js в браузере отлично подойдет для разработки, но не рекомендуется для производства (релиза).

Компиляция на стороне клиента это простой путь начать разрабатывать на Less, но в производстве, когда важны производительность и надежность, мы рекомендуем для пре-компиляции использовать node.js или другие инструменты.

Свяжите ваш документ с .less файлом через атрибут rel со значением stylesheet/less.

HTML

    <link rel="stylesheet/less" type="text/css" href="/styles.less" />

Затем, скачайте less.js и подключите его в тег script, который, в свою очередь, вставьте в тег head. Стилевой файл должен идти перед тегом script (как обычно).

HTML

    <script src="less.js" type="text/javascript"></script>

Опции браузера

Опции, определяющие настройки глобального объекта Less, поставьте перед тегом script:

    <!-- set options before less.js script -->
<script>
  less = {
    env: "development",
    async: false,
    fileAsync: false,
    poll: 1000,
    functions: {},
    dumpLineNumbers: "comments",
    relativeUrls: false,
    rootpath: ":/a.com/"
  };
</script>
<script src="less.js"></script>

Переменные

Это довольно очевидно:

    @nice-blue: #5B83AD;
@light-blue: @nice-blue + #111;

#header {
  color: @light-blue;
}

Вывод:

    #header {
  color: #6c94be;
}

Обратите внимание: все переменные фактически являются ‛константами“, так как они могут быть определены лишь один раз.

Примеси

Примеси являются одним из способов подключить набор свойств из одного правила в другое правило. Итак, например, мы имеем следующий класс:

    .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).

Примеси с параметрами

Опционально после имени примеси можно ставить круглые скобки.

Примесям можно передавать аргументы, которые в качестве переменных используются в блоке примеси.

Например:

    .border-radius(@radius) {
         -webkit-border-radius: @radius;
         -moz-border-radius: @radius;
          border-radius: @radius;
}

Применяем в различных правилах:

    #header {
  .border-radius(4px);
}
.button {
  .border-radius(6px);
}

Параметры в примесях могут иметь значения по умолчанию:

    .border-radius(@radius: 5px) {
         -webkit-border-radius: @radius;
         -moz-border-radius: @radius;
          border-radius: @radius;
}

Как вариант, допустимый вызов примеси:

    #header {
  .border-radius;
}

И будет подключен 5px border-radius:

Вы также можете использовать примеси, которые не принимают параметры. Это полезно, если вы захотите спрятать примесь в CSS, при этом сама примесь будет использоваться (внутри блока объявлений).

    .wrap() {
  text-wrap: wrap;
  white-space: -moz-pre-wrap;
  white-space: pre-wrap;
  word-wrap: break-word;
}
pre { .wrap }

Вывод:

    pre {
  text-wrap: wrap;
  white-space: -moz-pre-wrap;
  white-space: pre-wrap;
  word-wrap: break-word;
}

Примеси с несколькими параметрами

Параметры разделяются запятой или точкой с запятой. Рекомендуется использовать точку с запятой. Запятая имеет двойной смысл: ее можно интерпретировать как разделитель для разделения примесей или как разделитель селекторов в CSS.

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

  • Два аргумента и каждый содержит запятую: .name(1, 2, 3; something, else)
  • Три аргумента и каждый содержит одну цифру: .name(1, 2, 3)
  • Используется фиктивная точка с запятой, чтобы создать примесь с одним аргументом, который содержит запятые: .name(1, 2, 3;)
  • Значение по умолчанию с разделителем запятой: .name(@param1: red, blue;)

Вполне допустимо определять несколько примесей с одним и тем же именем и количеством параметров. Если вы используете примесь с одним параметром, например, .mixin(green);, затем свойства всех примесей с точно таким же обязательным параметром будут использованы:

    .mixin(@color) {
  color-1: @color;
}
.mixin(@color; @padding:2) {
  color-2: @color;
  padding-2: @padding;
}
.mixin(@color; @padding; @margin: 2) {
  color-3: @color;
  padding-3: @padding;
  margin: @margin @margin @margin @margin;
}
.some .selector div {
  .mixin(#008000);
}

Компилируется в:

    .some .selector div {
  color-1: #008000;
  color-2: #008000;
  padding-2: 2;
}

Примеси как функции

Возвращение значений из примеси.

Все переменные, определенные в примеси, могут быть использованы в вызывающей области видимости (если в вызывающей области видимости уже не определена переменная с таким же именем).

    .mixin() {
  @width:  100%;
  @height: 200px;
}

.caller {
  .mixin();
  width:  @width;
  height: @height;
}

Результат:

    .caller {
  width:  100%;
  height: 200px;
}

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

    .average(@x, @y) {
  @average: ((@x + @y) / 2);
}

div {
  .average(16px, 50px); // "call" the mixin
  padding: @average;    // use its "return" value
}

Результат:

    div {
  padding: 33px;
}

Сдерживатели примеси

Сдерживатели (if-else) (Guards), в отличие от простых значений, полезны, когда вы хотите получить соответствие шаблону, . Если вы знакомы с функциональным программированием, вы наверняка сталкивались с ними.

Пытаясь не отходить от декларативной природы CSS, Less реализовал выполнение условий через сдерживание примесей, вместо использования операторов if/else, в духе использования медиа-запросов.

    .my-optional-style() when (@my-option = true) {
  button {
    color: white;
  }
}
.my-optional-style();

When это ключевое слово, которое вводит сдерживание.

До версии 1.5 вы могли использовать следующий код:

    button when (@my-option = true) {
  color: white;
}

Вы можете комбинировать условие с &, например:

    & when (@my-option = true) {
  button {
    color: white;
  }
  a {
    color: blue;
  }
}

Операторы сравнения для сдерживании

Полный список операторов сравнения для сдерживания: >, >=, =, =<, <. Кроме того, ключевое значение true делает эквивалентными следующие две примеси:

    .truth (@a) when (@a) { ... }
.truth (@a) when (@a = true) { ... }

Любое значение кроме ключевого слова true является ложью (false).

    .class {
  .truth(40); // Will not match any of the above definitions.
}

Отметьте, вы можете сравнить аргументы друг с другом или с не-аргументами.

    @media: mobile;

.mixin (@a) when (@media = mobile) { ... }
.mixin (@a) when (@media = desktop) { ... }

.max (@a; @b) when (@a > @b) { width: @a }
.max (@a; @b) when (@a < @b) { width: @b }

Циклы

В Less примеси могут вызывать сами себя. Такие рекурсивные примеси в сочетании со сдерживателями и шаблонами соответствия, могут быть использованы для создания циклов.

    .loop(@counter) when (@counter > 0) {
  .loop((@counter - 1));    // next iteration
  width: (10px * @counter); // code for each iteration
}

div {
  .loop(5); // launch the loop
}

Вывод:

    div {
  width: 10px;
  width: 20px;
  width: 30px;
  width: 40px;
  width: 50px;
}

Общие пример использования рекурсивного цикла, который создает классы для CSS сетки.

CSS

    .generate-columns(4);

.generate-columns(@n, @i: 1) when (@i =< @n) {
  .column-@{i} {
    width: (@i * 100% / @n);
  }
  .generate-columns(@n, (@i + 1));
}

Вывод:

    .column-1 {
  width: 25%;
}
.column-2 {
  width: 50%;
}
.column-3 {
  width: 75%;
}
.column-4 {
  width: 100%;
}

Запятая

Добавьте значения через запятую:

Пример:

    .mixin() {
  box-shadow+: inset 0 0 10px #555;
}
.myclass {
  .mixin();
  box-shadow+: 0 0 20px black;
}

Вывод:

    .myclass {
  box-shadow: inset 0 0 10px #555, 0 0 20px black;
}

Пробел

Добавьте пробел между значениями:

    .mixin() {
  transform+_: scale(2);
}
.myclass {
  .mixin();
  transform+_: rotate(15deg);
}

Вывод:

    .myclass {
  transform: scale(2) rotate(15deg);
}

Родительские селекторы

Оператор & ссылается на родительский селектор вложенного правила и чаще всего используется, когда требуется присоединить (модифицировать) псевдо-класс или класс к существующему селектору:

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

Результат:

    a {
  color: blue;
}

a:hover {
  color: green;
}

Обратите внимание, что без & в приведенном выше примере в селекторе появится пробел a :hover (потомок элемента a), и это совсем не то, что мы ожидаем получить от псевдо-класса :hover.

Оператор ‛Родительские селектор“ имеет множество применений. Например, чтобы объединить группу правил одного элемента, имеющего различные состояния. Например, типичный пример использования & это создание повторяющихся наименований класса:

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

  &-custom {
    background-image: url("custom.png");
  }
}

Результат:

    .button-ok {
  background-image: url("ok.png");
}
.button-cancel {
  background-image: url("cancel.png");
}
.button-custom {
  background-image: url("custom.png");
}

Несколько &

В одном селекторе & можно использовать несколько раз. Это дает возможность повторно обратиться к родительскому селектору, не повторяя его название.

    .link {
  & + & {
    color: red;
  }

  & & {
    color: green;
  }

  && {
    color: blue;
  }

  &, &ish; {
    color: cyan;
  }
}

Результат:

    .link + .link {
  color: red;
}
.link .link {
  color: green;
}
.link.link {
  color: blue;
}
.link, .linkish {
  color: cyan;
}

Отметьте, что & представляет все родительские селекторы (не только ближайшего предка), можете увидеть на примере:

    .grand {
  .parent {
    & > & {
      color: red;
    }

    & & {
      color: green;
    }

    && {
      color: blue;
    }

    &, &ish; {
      color: cyan;
    }
  }
}

Результат:

    .grand .parent > .grand .parent {
  color: red;
}
.grand .parent .grand .parent {
  color: green;
}
.grand .parent.grand .parent {
  color: blue;
}
.grand .parent,
.grand .parentish {
  color: cyan;
}

Меняем порядок селекторов

Может быть полезно поставить селектор перед родительским селектором. Это можно сделать, поставив & после текущего селектора. Например, при использовании Modernizr, вы можете задать различные правила на основе поддерживаемых особенностей:

    .header {
  .menu {
    border-radius: 5px;
    .no-borderradius & {
      background-image: url('images/button-background.png');
    }
  }
}

На выходе:

    .header .menu {
  border-radius: 5px;
}
.no-borderradius .header .menu {
  background-image: url('images/button-background.png');
}

Комбинируем селекторами

& можно также использовать, чтобы сгенерировать все возможные комбинации селекторов через запятую:

    p, a, ul, li {
border-top: 2px dotted #366;
  & + & {
      border-top: 0;
  }
}

    p,
a,
ul,
li {
  border-top: 2px dotted #366;
}
p + p,
p + a,
p + ul,
p + li,
a + p,
a + a,
a + ul,
a + li,
ul + p,
ul + a,
ul + ul,
ul + li,
li + p,
li + a,
li + ul,
li + li {
  border-top: 0;
}

Вложенные правила

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;
  }
}

Медиа-запросы и вложенные медиа-запросы

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

    .screencolor{
  @media screen {
    color: green;
    @media (min-width:768px) {
    color: red;
    }
    }
  @media tv {
    color: black;
  }
}

На выходе:

    @media screen {
  .screencolor {
    color: green;
  }
}
@media screen and (min-width: 768px) {
  .screencolor {
    color: red;
  }
}
@media tv {
  .screencolor {
    color: black;
  }
}

Операции

Над числами, цветом или переменными могут быть осуществлены все допустимые операции. Вот несколько примеров:

    @base: 5%;
@filler: @base * 2;
@other: @base + @filler;

color: #888 / 4;
background-color: @base-color + #111;
height: 100% / 2 + @filler;

Less понимает разницу между цветом и, например, единицами измерения. Если единицы используются, например, так:

    @var: 1px + 5;

В этом случае на выходе Less покажет 6px.

Функции

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

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

    @base: #f04615;
@width: 0.5;

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

Пространство имен

Иногда может потребоваться сгруппировать ваши примеси в организационных целях или с целью инкапсуляции. В 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;
}

Отметьте, что переменные объявленные внутри пространства имен будут видимы лишь в этом пространстве имен и не будут доступны снаружи через тот же синтаксис, который вы используете для примесей (#Namespace > .mixin-name). Например, вы не сможете сделать следующее: (#Namespace > @this-will-not-work).

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

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

    @var: red;

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

Следующий код идентичен предыдущему примеру:

    @var: red;

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

Комментарии

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

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

// Get in line!
@var: white;

Строчные комментарии не переносятся при компиляции css файла.

Importing

Importing работает так же, как и ожидалось. Вы можете импортировать .less файл и все переменные будут доступны.

Extend

Extend является псевдо-классом, который группирует селектор (создается множественный селектор: "selector1, selector2; где selector1 – селектор-родитель, selector2 – на какой селектор ссылаемся) с блоком объявлением того селектора, на который ссылаемся.

    nav ul {
  &:extend(.inline);
  background: blue;
}
.inline {
  color: red;
}

На выходе:

    nav ul {
  background: blue;
}
.inline,
nav ul {
  color: red;
}

В вышеприведенном правиле селектор: extend расширит селектор (nav ul) селектором .inline (сгруппирует: поставит через запятую). Блок объявлений будет использоваться как есть, то есть расширяться не будет.

Extend через ключевое слово all прикрепляет набор правил, это похоже на использование псевдоклассов.

Например:

    .cle {
  &:before,
  &:after {
    content: "123"; // 1
    display: table; // 2
  }
  &:after {
    clear: both;
  }
}

.opa {
    color: red;
    &:extend(.cle all);
}

Результат:

    .cle:before, .cle:after, .opa:before, .opa:after {
    content: "123";
    display: table;
}

Комментарии к статье

аватарка пользователя
2016-10-03
Лора

в последней таблице демонстрирующей результат не показано как в стилях отобразились
color: red;
clear: both;

аватарка пользователя
2017-04-30
Alex

Статья - топ! Спасибо