Переменные¶
В этой статье вы узнаете, что такое переменные, как и для чего они используются в LESS, и в чем заключается преимущество в их использовании.
Переменная (variable) в LESS это поименованная область памяти, адрес (имя) которой можно использовать для осуществления доступа к заданному значению, и при необходимости изменять это значение в ходе объявления стилей. Другими словами это контейнер в который мы помещаем интересующее нас значение, и в любой момент мы можем воспользоваться этим значением, сославшись в нашем коде на этот контейнер (переменную).
Зачастую, одни и те же значения свойств могут повторяться десятки, а то и сотни раз в одной таблице стилей, препроцессор LESS поддерживает использование переменных, благодаря которым значительно упрощает монотонную работу. Переменные позволят Вам сделать код легче поддерживаемым, так как у вас появится возможность контролировать значения свойств из одного места, и при необходимости оперативно вносить необходимые правки.
Объявление переменной¶
Прежде чем использовать переменную в коде её необходимо объявить внутри файла less, или другими словами инициализировать. Имя переменной всегда должно начинаться со знака @
. Если вы хорошо знакомы с CSS, то вы знаете, что в каскадных таблицах стилей знак @
указывает, что перед нами директива, или еще их называют правилами. Полный перечень директив (правил) вы можете найти в следующем разделе, не путайте их с переменными.
Синтаксис переменных всегда должен состоять из пар имя/значение:
@variableName: value; // имя и значение переменной
Давайте перейдем к рассмотрению простого примера объявления переменных в LESS и постепенно будем увеличивать сложность примеров по ходу статьи. Допустим нам необходимо разместить кнопку (элемент <button>
), которая имеет одни цветовые стили для текста и границ элемента. Для этих целей создадим переменную:
@button-color: #b05049; // объявляем (инициализируем) переменную
После того как мы объявили переменную мы можем воспользоваться ей в своем коде, делается это следующим образом:
@button-color: #b05049; // объявляем (инициализируем) переменную
button {
color: @button-color; // используем переменную в качестве значения свойства
border: 1px solid @button-color; // используем переменную в качестве части значения свойства
}
Как вы можете догодаться после компиляции в CSS мы получим следующий результат:
button {
color: #b05049; // цвет текста
border: 1px solid #b05049; // стили для границ элемента
}
В следующем примере мы создадим две переменные и укажем в качестве значения свойства переменную, которая содержит в себе имя другой переменной:
@me: 'I am string';
@not-me: 'me';
.selector {
content: @@not-me; // @@not-me --> @me --> "I am string"
}
В этом примере мы указали для CSS свойства content
значение переменной, которое содержит в себе имя другой переменной. В ходе компиляции для начала будет найдено значение переменной @not-me
, оно будет подставлено для поиска значения, получившейся переменной @me
, которое и содержит финальный результат "I am string"
.
.selector {
content: 'I am string';
}
Хочу обратить Ваше внимание на то, что такая конструкция метаязыка LESS имеет право на жизнь, но встречается на практике очень редко, в основном для решения задач, которые можно решить и другим способом.
Давайте разберем пример, в котором объявим несколько переменных с одним именем уже после их использования в коде, и посмотрим, что мы получим при компиляции:
button {
color: @button-color; // используем переменную в качестве значения свойства
}
@button-color: #b05049; // объявляем переменную
@button-color: red; // объявляем одноименную переменную
В результате компиляции мы должны получить следующий результат:
button {
color: red; // цвет текста
}
Во-первых, необходимо понять из этого примера, что допускается использовать переменные до их инициализации (до того как они были объявлены). Во-вторых, переменные в LESS допускается переопределять, а это означает, что, если переменная ниже объявлена с тем же именем, то при компиляции будет использовано её значение. Но и здесь есть свои нюансы, связанные с областью видимости переменных, а что это такое мы узнаем в следующем разделе.
Область видимости переменных¶
В LESS, как и, например, в языках программирования JavaScript, PHP, или C# существует понятие области видимости переменных, она представляет из себя отдельный блок кода, в котором мы инициализируем переменную. Переменные в LESS бывают как глобальными, так и локальными. В этой статье мы уже с Вами сталкивались с объявлением глобальных переменных, например:
@section: #777; // объявляем глобальную переменную
@section_inside: #999; // объявляем глобальную переменную
div {
background: @section; // используем переменную в качестве значения свойства
> div {
// селектор дочерних элементов (выбираем элементы <div>, вложенные в <div>
background: @section_inside; // используем переменную в качестве значения свойства
}
}
Отличительной особенностью глобальных переменных служит то, что они не находятся внутри какого-то отдельного блока, а находятся в самом "верху", что делает доступным их из любого места в Вашем коде. Другими словами они имеют глобальную область видимости. В результате компиляции мы получим следующий результат:
div {
background: #777777; // цвет заднего фона
}
div > div {
background: #999999; // цвет заднего фона
}
Второй тип переменных - локальные, они как вы уже догадались, размещаются внутри какого-либо блока и имеют свою локальную область видимости.
Давайте рассмотрим пример, в котором мы создадим одноименные переменные, которые имеют как локальную, так и глобальную область видимости:
@myVariable: violet; // объявляем глобальную переменную
aside {
@myVariable: yellow; // объявляем локальную переменную
background: @myVariable; // используем переменную в качестве значения свойства
}
@myVariable: red; // объявляем глобальную переменную
В связи с тем, что у нас имеется одноименная локальная переменная, то в результате компиляции будет использовано именно её значение, так как эта переменная является последней переменной, которая была объявлена в текущей области видимости (локальная область видимости).
Результат компиляции будет следующий:
aside {
background: #ffff00; // желтый цвет в шестнадцатиричной системе
}
К этому месту статьи вы уже должны прийти к пониманию того, что глобальные переменные доступны из любого места в коде, а вот локальные переменные, только из текущей области видимости. Например:
article {
p {
@myVariable: green; // объявляем локальную переменную
color: @myVariable; // используем переменную в качестве значения свойства
span {
color: @myVariable; // используем переменную в качестве значения свойства
}
}
}
Внутри вложенного селектора span
доступно использование переменной, так как локальная область видимости распостроняется и на вложенные селекторы.
Обратите внимание на следующий пример в котором мы попытаемся воспользоваться локальной переменной, которая была инициализирована у вложенного элемента:
article {
color: @myVariable; // переменная не доступна (undefined) - ошибка компиляции
p {
@myVariable: green; // объявляем локальную переменную
color: @myVariable; // используем переменную в качестве значения свойства
span {
color: @myVariable; // используем переменную в качестве значения свойства
}
}
}
Вышеприведенный код не будет скомпилирован по той причине, что инициализированная локальная переменная не будет доступна для использования внутри селектора span
, так как она размещена не в текущей области видимости. Это очень важный момент, который необходимо понять при работе с локальными и глобальными переменными в LESS.
Обращаю Ваше внимание на то, что рекомендуется использовать переменные уже после их объявления, иначе, результат может быть не тем, который вы ожидаете. Рассмотрим следующий пример:
.selector {
width: @my-var;
@my-var2: 10%;
}
@my-var: @my-var2;
@my-var2: 100%;
Это типичный пример, который мы разобрали выше, но его результат, возможно, Вас смутит:
.selector {
width: 10%;
}
В этом примере мы в качесте значения свойства width
присваеваем переменную @my-var
, компилятор находит эту переменную в глобальной области видимости, значение этой переменной соответствует имени переменной @my-var2
. Теперь внимательно присмотритесь, у нас есть переменная @my-var2
как в локальной, так и глобальной области видимости. Компилятор выберет последнюю переменную, которая была объявлена в текущей области видимости, в нашем случае это локальная область видимости.
Ну и на последок пример, результат компиляции которого, я надеюсь, вы сможете определить самостоятельно:
@var: 0; // глобальная область видимости
.class {
@var: 1; // локальная область видимости
property: @var;
.nested-class {
// вложенный класс
@var: 2; // локальная область видимости
property: @var;
@var: 3; // локальная область видимости
}
}
Интерполяция переменных¶
Давайте с Вами разберем, что же такое интерполяция переменных в LESS, и в чем заключается её особенность. Интерполяция позволяет нам использовать произвольную строку, которая хранится в переменной в качестве строковых значений, или части строковых значений CSS правил, свойств, значений этих свойств, использовать это значение в наименовании селекторов и даже внутри селекторов.
В первую очередь рассмотрим пример интерполяции переменной внутри и вместо CSS свойств:
@myProperty: color; // инициализируем переменную
body {
@{myProperty}: #222; // интерполяция переменной в качестве свойства
[email protected]{myProperty}: #333; // интерполяция переменной в качестве части свойства
}
Обратите внимание на необходимость соблюдения определенного синтаксиса при проведении интерполяции, в котором необходимо помещать имя, интересующей нас переменной внутри конструкции:
@{} // имя переменной помещается между фигурных скобок
Результат компиляции нашего примера будет следующий:
body {
color: #222; // цвет текста
background-color: #333; // цвет заднего фона
}
В следующем примере мы произведем интерполяцию переменной внутри значения CSS свойства:
@path: '/wwwroot/images/'; // инициализируем переменную
body {
background: url('@{path}main.png'); // интерполяцию переменной внутри значения
header {
background: url('@{path}header.png'); // интерполяцию переменной внутри значения
nav {
background: url('@{path}nav.png'); // интерполяцию переменной внутри значения
}
}
}
В этом примере мы указали в качестве значения переменной строковый путь от корня сайта к файлам с изображениями, согласитесь это довольно удобно, так как нам достаточно определить интерполяцию переменной перед названием изображения. Даже если по каким-то причинам Вам необходимо будет физически переместить файлы с изображениями, то внесение изменений в стили займет минимум времени. Результат компиляции будет следующий:
body {
background: url('/wwwroot/images/main.png'); // фоновое изображение для элемента
}
body header {
background: url('/wwwroot/images/header.png'); // фоновое изображение для элемента
}
body header nav {
background: url('/wwwroot/images/nav.png'); // фоновое изображение для элемента
}
В заключении этого раздела рассмотрим пример в котором мы произведем интерполяцию переменной внутри селектора:
@my-selector: main-logo; // инициализируем переменную
section [email protected]{my-selector} {
// интерполяцию переменной внутри селектора
display: none; // элемент не будет отображаться
}
По аналогии с предыдущими примерами для интерполяции переменной достаточно лишь поместить её внутри конструкции @{}
. После компиляции в CSS мы получим следующий результат:
section .main-logo {
display: none; // элемент не будет отображаться
}
Экранирование в LESS¶
В этом разделе мы рассмотрим такую возможность LESS как экранирование символов. В настоящее время эта особенность метаязыка устарела и не так часто используется, но встречается при решении некоторых специфических задач. Для чего может использоваться экранирование? Например, если Вам необходимо использовать произвольную строку в качестве CSS свойства, или его значения, а по мнению компилятора Ваш код считается не валидным (не стандартным), то необходимо поместить его в одну из следующих конструкций:
~"value" // синтаксис с двойной кавычкой
~'value' // синтаксис с одинарной кавычкой
Не будем тратить время и сразу перейдем к примеру:
@myVariable: myValue; // инициализируем переменную
body:before {
filter: ~'ms:special.browser.syntax()'; // код будет скомпилирован только с экранированием (указано не стандартное значение)
content: ~'@{myVariable}'; // интерполяция внутри экранирования
}
В этом примере мы применили экранирование к значениям CSS свойств, в первом свойстве оно позволило скомпилировать код для использования не стандартного значения, а во втором лишь для демонстрации работы интерполяции внутри экранирования.
Главное правило экранирования, которое необходимо понять: все, что Вы поместите внутри ~""
будет скомпилировано без изменений, за исключением использования интерполяции внутри конструкции экранирования.
Результат компиляции:
body:before {
filter: ms:special.browser.syntax(); // не стандартное значение свойства
content: myValue; // строковое содержимое свойства
}
Свойства как переменные¶
С выходом LESS версии 3.0 стало доступно использование такого синтаксиса, при котором имена объявленных свойств могут использоваться в качестве пременной, для этого достаточно вызвать интересующее Вас свойство со следующим синтаксисом:
.myClass {
color: #fff;
background: $color; // используем имя свойства как переменную
}
Если вы используете LESS версии 3.0 или старше, то результат компиляции должен быть следующий:
.myClass {
color: #fff;
background: #fff;
}
Давайте рассмотрим следующий пример, в котором используем свойство в качестве переменной для вложенного селектора:
.parent {
color: #fff;
.nested {
background: $color; // используем имя свойства как переменную
}
color: #000;
}
Обратите внимание, что, как и при работе с обычными переменными компилятор LESS выберет последнее свойство в текущей, или родительской области видимости в качестве значения, которое будет установлено.
Если вы используете LESS версии 3.0 или старше, то результат компиляции должен быть следующий:
.parent {
color: #fff;
color: #000;
}
.parent .nested {
background: #000;
}