Арифметические операции в LESS

В этой статье мы с Вами рассмотрим еще одну удивительную возможность LESS, позволяющую производить арифметические операции c числами, цветами и даже с переменными! Мы научимся применять такие операции как сложение, вычитание, умножение и деление.

Рис.10 Арифметические операции в Less.

До того как вы перейдете к прочтению статьи, хочу Вас познакомить, конечно если Вы еще не знакомы, с нативной функцией calc()css3, введенной в CSS 3, она позволит частично решать задачи с арифметическими операциями и, возможно, именно она подойдет для решения Вашей задачи. На текущий момент функция calc()css3 поддерживается всеми современными браузерами и даже Internet Explorer 9, ознакомьтесь с ней при случае.

Операции с числами

Рекомендую Вам явно указывать единицы измерения над которыми вы производите математические операции, это сделает Ваш код более прозрачным и позволит Вам каждый раз получать тот результат, который вы ожидаете. Одним из важных моментов при осуществлении математических операций является понимание работы компилятора при их вычислении.

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

/* инициализируем переменные */
@plus: 2 + 1; // производим операцию сложения
@minus: 2 - 1; // производим операцию вычитания
@multiplication: 2 * 1; // производим операцию умножения
@division: 2 / 1; // производим операцию деления

.plus {
    line-height: @plus; // используем переменную в качестве значения свойства
}
.minus {
    line-height: @minus; // используем переменную в качестве значения свойства
}
.multiplication {
    line-height: @multiplication; // используем переменную в качестве значения свойства
}
.division {
    line-height: @division; // используем переменную в качестве значения свойства
}

В этом примере мы инициализировали четыре переменные, которые использовали в качестве значений для свойств line-height, определяющих междустрочный интервал. Во время компиляции LESS автоматически производит вычисление значений переменных, благодаря чему внутри CSS файла мы увидим уже их вычисленные значения:

.plus {
    line-height: 3; // задаем междустрочный интервал
}
.minus {
    line-height: 1; // задаем междустрочный интервал
}
.multiplication {
    line-height: 2; // задаем междустрочный интервал
}
.division {
    line-height: 2; // задаем междустрочный интервал
}

Давайте рассмотрим еще один простой пример, но в этот раз будем использовать числа уже вместе с единицами измерения:

/* инициализируем переменные */
@plus: 4px + 1px; // производим операцию сложения
@minus: 3px - 1px; // производим операцию вычитания
@multiplication: 2px * 7; // производим операцию умножения
@division: 9px / 2; // производим операцию деления
@width: 100% / 4; // производим операцию деления

.plus {
    border-width: @plus; // используем переменную в качестве значения свойства
    width: @width; // используем переменную в качестве значения свойства
}
.minus {
    border-width: @minus; // используем переменную в качестве значения свойства
    width: @width; // используем переменную в качестве значения свойства
}
.multiplication {
    border-width: @multiplication; // используем переменную в качестве значения свойства
    width: @width; // используем переменную в качестве значения свойства
}
.division {
    border-width: @division; // используем переменную в качестве значения свойства
    width: @width; // используем переменную в качестве значения свойства
}

В этом примере мы создали четыре переменные, которые использовали в качестве значений для свойств border-width, определяющих ширину для границ элемента и одну переменную, которую использовали для всех свойств width, определяющую ширину элемента.


Допустим, наши элементы растягиваются по ширине в одной строке и нам необходимо добавить еще один элемент, в этом случае нам будет достаточно просто поменять делитель внутри переменной с четырех на пять. Согласитесь это достаточно удобно, так как LESS произведет все расчеты ширины элементов за Вас.


Результат компиляции должен быть очевиден для Вас:

.plus {
    border-width: 5px; // задаем ширину для границ элемента
    width: 25%; // задаем ширину для элемента
}
.minus {
    border-width: 2px; // задаем ширину для границ элемента
    width: 25%; // задаем ширину для элемента
}
.multiplication {
    border-width: 14px; // задаем ширину для границ элемента
    width: 25%; // задаем ширину для элемента
}
.division {
    border-width: 4.5px; // задаем ширину для границ элемента
    width: 25%; // задаем ширину для элемента
}

По аналогии с нативной CSS функцией calc()css3 при арифметеских операциях Вы можете использовать различные конвертируемые единицы измерения:

/* инициализируем переменные */
@cm: 1cm + 10mm;               // результат 2cm
@cm2: 1 - 3cm - 4mm;          // результат -2.4 cm
@inch: 3in - 96px;                  // результат 2in
@rad: 180deg + 200grad;     // результат 360deg
@deg: 90deg + 1turn;           // результат 450deg

В этом примере мы создали следующие пять переменных:

Перед тем как мы перейдем к следующим примерам, хочу обратить Ваше внимание, что в официальной документации есть такой пример (дословно):

// conversion is impossible (конвертация невозможна)
@incompatible-units: 2 + 5px - 3cm; // result is 4px

Если бы составитель документа, описывающий особенности метаязыка внимательно прочитал вышеуказанную статью учебника CSS - «Единицы измерения CSS, размер шрифта» то он был бы в курсе, что сантиметры могут быть конвертированы в пиксели (1cm ~ 38.8 пикселей).

Шутки шутками, но корректный результат примера из официальной документации должен быть таким, не смотря, что он некорректен для браузера:

// conversion is possible (конвертация возможна)
@incompatible-units: 2 + 5px - 3cm; // result is -106.38582677px

В следующем примере мы с Вами рассмотрим некоторые нюансы компиляции и увидим как LESS преобразует единицы измерения, которые нельзя явно конвертировать:

/* инициализируем переменные */
@var1: 1px + 1;                // результат 2px
@var2: 1px + 1em;          // результат 2px
@var3: 1em + 1px;          // результат 2em
@var4: 10px * 50%;        // результат 50px
@var5: 50% * 10px;        // результат 500%
@var6: 3cm * 3mm;      // результат 9cm
@var7: 3cm / 3mm;      // результат 1cm

Как вы уже поняли, LESS, если это возможно, при арифметических операциях преобразует единицы измерения. А что он делает если преобразование действительно невозможно? Давайте внимательно разберем наши переменные:

Операции с переменными

Если вы поняли предыдущий раздел, то понимание как происходят операции с переменными к вам придет моментально. Что такое переменная? Это просто контейнер со значением, которое участвует при вычислении. Примеров как происходят вычисления в LESS мы с Вами рассмотрели более чем достаточно, Вам лишь достаточно заменить любое из этих значений переменной и результат будет тот же, что и с использованием переменной.

Давайте закрепим наши знания и рассмотрим следующие примеры:

/* инициализируем переменные */
@a: 10px; 
@b: 5px;  

// производим операцию сложения переменных 
@c: @a + @b; // переменная содержит значение 15px

// производим операцию вычитания переменных 
@d: @a - @b; // переменная содержит значение 5px

// производим операцию умножения переменных 
@e: @a * @b; // переменная содержит значение 50px

// производим операцию деления переменных 
@f: @a / @b; // переменная содержит значение 2px

// производим операцию умножения переменной на процент и наоборот 
@g: @b * 10%; // переменная содержит значение 50px
@h: 10% * @b; // переменная содержит значение 50%

Кроме того, вы можете контролировать порядок математических операций с использованием скобок, и даже при необходимости инвертировать значение переменной (изменение положительного значения на отрицательное, или наоборот с положительного на отрицательное):

/* инициализируем переменные */
@a: 10px; 
@b: 5px;  
@c: 3px;

@d: -@a; // переменная содержит значение -10px
@e: -(@a + @b); // переменная содержит значение -15px
@f: (@a + @b) * @c; // переменная содержит значение 45px

Операции с цветами

В следующем разделе статьи мы с Вами рассмотрим примеры того как производятся операции с цветами. Если вы плохо знакомы со способами указания цвета с помощью шестнадцатеричных значений (HEX), значений цвета RGB, RGBA, HSL и HSLA, то я рекомендую Вам перед прочтением ознакомиться со статьей из учебника CSS - «Цветовое оформление в CSS».

Операции с HEX цветами

Цвет с использованием шестнадцатеричной системы задается с использованием следующего синтаксиса:

#RRGGBB // шестнадцатиричное значение цвета

Значение, фактически содержит три шестнадцатеричных числа (RR - для красного, GG - для зеленого, BB - для синего). Значение цвета получается при смешивании трех вышеуказанных составляющих. Каждое значение (RR, GG и BB) должно находиться в диапозоне между 00 и FF. В шестнадцатиричной системе счет ведется следующим образом: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F.

При проведении арифметических операций в шестнадцатиричной системе, заданная пользователем операция будет проведена отдельно для каждого цвета:

#RRGGBB операция значение 

#RR операция значение // новое значение для RR
#GG операция значение // новое значение для GG
#BB операция значение // новое значение для BB

#RRGGBB // новое значение после вычисления значений для каждого цвета

Обратите внимание, что при операциях с шестнадцатиричными цветами результатом всегда будет допустимый цвет, это достигается за счет того, что если результат окажется больше FF, или меньше 00, то значение будет округлено до этих значений.

Давайте рассмотрим несколько примеров арифметических операций с шестнадцатиричными цветами:

@color1: #111111 * 2; // переменная содержит значение #222222 (11 * 2 = 22 для каждого цвета)
@color2: #444444 * 2.5; // переменная содержит значение #aaaaaa (44 * 2,5 = aa для каждого цвета)
@color3: #aaaaaa / 2; // переменная содержит значение #555555 (aa / 2 = 55 для каждого цвета)

/* допускается сокращать шестнадцатеричные числа до трех символов,
в том случае если каждое из трех двухзначных чисел содержит одинаковые символы */

@color4: #222 - #111; // переменная содержит значение #111111 (22 - 11 = 11 для каждого цвета)
@color5: #222 - #555; // переменная содержит значение #000000 (22 - 55 ≈ 00 (округление) для каждого цвета)
@color6: #aaa + #999; // переменная содержит значение #ffffff (aa + 99 ≈ FF (округление) для каждого цвета)
@color7: #112233 + #111;// переменная содержит значение #223344 (11 + 11 = 22 для красного, 22 + 11 = 33 для зеленого, 33 + 11 = 44 для синего) 

Операции с RGB цветами

Чтобы указать значение в системе RGB необходимо использовать следующий синтаксис:
rgb(R,G,B); // значение цвета в системе RGB

Каждый параметр определяет интенсивность цвета и может быть целым числом от 0 до 255. По аналогии с операциями с шестнадцатиричными цветами, заданная пользователем операция будет проведена отдельно для каждого цвета:

rgb(R,G,B) операция значение 

R операция значение // новое значение для R
G операция значение // новое значение для G
B операция значение // новое значение для B

rgb(R,G,B) // новое значение после вычисления значений для каждого цвета

Обратите внимание, что при операциях с RGB цветами результатом всегда будет допустимый цвет, это достигается за счет того, что если результат окажется больше 255, или меньше 0, то значение будет округлено до этих значений.

Давайте рассмотрим несколько примеров арифметических операций с цветами в системе RGB:

@color8: rgb(35, 35, 35) * 2; // переменная содержит значение #464646 (rgb(70, 70, 70) --> HEX)
@color9: rgb(35, 35, 35) / 5; // переменная содержит значение #070707 (rgb(7, 7, 7) --> HEX)
@color10: rgb(150,150,150) + rgb(150,150,150); // переменная содержит значение #ffffff (округление до 255 для каждого цвета)  
@color11: rgb(0,0,255) + #110 // переменная содержит значение #1111ff (rgb(0,0,255) --> #00F + #110) 

Операции с HSL цветами

HSL это аббревиатура, которая объединяет в себе первые буквы трех следующих признаков:

Система HSL использует следующий синтаксис:

hsl(от  до 360°, от 0 до 100%, от 0% до 100%);

Обратите внимание, что при проведении арифметической операции с HSL цветом только значение, определяющее осветленность участвует при этом:

hsl(h, s, l операция значение):

Давайте рассмотрим несколько примеров арифметических операций с цветами в системе HSL:

@color10: hsl(240, 100%, 20%) * 2; // переменная содержит значение  #0000cc (hsl(240, 100%, 20%) --> hsl(240, 100%, 40%) --> HEX)
@color11: hsl(240, 100%, 20%) / 2; // переменная содержит значение #000033 (hsl(240, 100%, 10%) --> HEX)
@color12: hsl(240, 100%, 20%) * 5; // переменная содержит значение #0000ff 
@color13: hsl(240, 100%, 20%) * 6;// переменная содержит значение #0000ff (округление до 100)
@color14: hsl(240, 100%, 50%) + #010; // переменная содержит значение #0011ff

Операции с HSLA и RGBA цветами

В настоящее время LESS не умеет проводить операции с альфа-каналом (степень смешивания с фоном). Это означает, что альфа-канал определяется как undefined (неопределенный) и операции с цветовыми моделями RGBA и HSLA проводятся точно так же как и в цветовых моделях RGB и HSL.

@color15: rgb(35, 35, 35) * 2; // переменная содержит значение   #464646 (rgb(70, 70, 70) --> HEX)
@color16: rgba(35, 35, 35, .3) * 2; // переменная содержит значение  #464646 (альфа-канал не учитывается)
@color17: hsl(240, 100%, 20%) / 2; // переменная содержит значение #000033 (hsl(240, 100%, 10%)) --> HEX)
@color18: hsla(240, 100%, 20%, .6) / 2; // переменная содержит значение #000033 (hsla(240, 100%, 20%, undefined) --->  hsl(240, 100%, 20%) --> hsl(240, 100%, 10%) --> HEX)