Продолжим изучать возможности препроцессора LESS: познакомимся с примесями, научимся применять примеси с условиями, разберёмся, как создавать и использовать циклы. Также мы рассмотрим примеры использования примесей для решения типовых задач вёрстки.
В прошлом курсе мы познакомились с базовыми возможностями LESS: переменными, вложенными CSS-правилами, математическими операциями и встроенными функциями. В этом курсе мы продолжим изучать LESS и рассмотрим миксины.
Для начала давайте вспомним, как создавать переменные и задавать им значения.
@red
со значением #ff4136
..red
, в нём задайте цвету фона значение @red
..monster-happy
задайте в HTML класс red
.Ещё одна интересная возможность LESS — примеси. Мы можем «примешивать» содержимое одного CSS-правила в другое. Для этого нужно написать имя «примешиваемого» правила внутри другого правила. Рассмотрим пример:
LESS.white { color: white; } /* объявление примеси */
.text { .white; } /* применение примеси */
Этот LESS-код скомпилируется в такой CSS:
CSS.white { color: white; }
.text { color: white; }
Как мы видим, в правиле, где была «вызвана» примесь .white
, появилось её содержимое.
Чтобы не выводить саму примесь в CSS, нужно после объявления примеси поставить скобки:
LESS.white() { color: white; } /* объявление невыводимой примеси */
.text { .white; } /* применение примеси */
CSS.text { color: white; }
При применении примеси скобки писать необязательно.
LESS/* Эти выражения дают один и тот же результат: */
.mixin();
.mixin;
.monster-foolish
примените в LESS примесь .red
..red
невыводимой в стили.К одному правилу можно применить несколько примесей одновременно. В таком случае примеси просто «вызываются» по очереди.
Например:
LESS.big() {
width: 100500px;
}
.white() {
color: white;
}
.block {
.big();
.white();
}
CSS.block {
width: 100500px;
color: white;
}
.paint-blue()
, внутри неё задайте цвет фона @blue
..paint-blue()
к монстру .monster-foolish
..reduce()
, внутри неё задайте ширину и высоту 150px
..reduce()
к монстру .monster-foolish
.
В примесь можно передавать параметры. Они указываются внутри скобок объявления примесей. Названия параметров начинаются с символа @
. Рассмотрим пример:
LESS.margin(@value) {
margin-top: @value;
margin-bottom: @value;
}
.block {
.margin(10px);
}
CSS.block {
margin-top: 10px;
margin-bottom: 10px;
}
Параметры позволяют сделать примеси более универсальными.
.paint()
с параметром @color
.background-color
значение @color
..paint()
с параметром @green
к монстру .monster-happy
.Параметризованные примеси удобны, когда над разными элементами нужно провести однотипные действия с отличающимися результатами.
Давайте попрактикуемся в применении примесей с параметром.
С помощью примеси .paint()
покрасьте:
.monster-foolish
в красный цвет,.monster-friendly
в синий цвет.Параметризованные примеси можно сделать ещё универсальнее.
Параметру примеси можно задать значение по умолчанию. Оно указывается через двоеточие после названия параметра. Если в примесь при применении параметр не передаётся, то используется значение по умолчанию.
Рассмотрим пример, в котором значение параметра по умолчанию указано, но не задействуется, так как в примесь передаётся явный параметр.
LESS.big(@size: 100500px) {
width: @size;
}
.block {
.big(10px);
}
CSS.block {
width: 10px;
}
В следующем примере примесь применяется без параметров, поэтому используется значение по умолчанию:
LESS.big(@size: 100500px) {
width: @size;
}
.block {
.big();
}
CSS.block {
width: 100500px;
}
@yellow
со значением #ffdc00
..paint()
задайте параметру @color
значение по умолчанию @yellow
..paint()
без параметров к монстру .monster-friendly
.
В примесь можно передавать несколько параметров. Параметры перечисляются через запятую ,
или через точку с запятой ;
. Рекомендуется использовать точку с запятой. Пример:
LESS.offset(@padding; @margin) {
padding: @padding;
margin: @margin;
}
.block {
.offset(5px; 10px);
}
CSS.block {
padding: 5px;
margin: 10px;
}
Попробуем передать в примесь несколько параметров.
.resize
с двумя параметрами: @width
и @height
.@width
, а высоте — @height
..monster-happy
примените примесь .resize
с параметрами 150px
для ширины и высоты.Проверим знания в испытании.
В исходном коде созданы разные примеси. Вам нужно применить их к кусочкам головоломки так, чтобы кусочки «закрыли» пустоты частей головоломки. Часть примесей применяется без параметров, а некоторые принимают параметры.
В качестве подсказки мы уже применили несколько примесей ко всем кусочкам .piece
. Удачи!
Иногда бывает полезным изменить поведение примеси в зависимости от передаваемых параметров. Например, у нас есть примесь, задающая размер шрифта:
LESS.set-font-size(@size) {
font-size: @size;
}
Мы можем создать ещё одну примесь с таким же названием, но передать дополнительно первым параметром название шаблона этой примеси. Имя шаблона указывается первым перед параметрами самой примеси. Добавим примеси дополнительный первый параметр smaller
и немного изменим принцип её работы:
LESS.set-font-size(smaller; @size) {
font-size: @size / 2;
}
Теперь можно вызывать эту примесь с названием шаблона и без него и, в зависимости от этого, получать соответствующие результаты:
LESS.text {
.set-font-size(100px);
}
.small-text {
.set-font-size(smaller; 100px);
}
CSS.text {
font-size: 100px;
}
.small-text {
font-size: 50px;
}
Таким образом можно для схожих действий не создавать несколько примесей с разными названиями. Лучше делать шаблоны одной примеси и просто вызывать её с дополнительным параметром.
Давайте попробуем создать шаблон примеси и применить её для окраски монстров.
В задании применяется встроенная в LESS функция lighten
для работы с цветом. Она рассматривается в задании первой части курса по LESS.
.paint()
с первым параметром light
и со вторым параметром @color
.background-color
значение lighten(@color, 20%)
..paint()
с первым параметром light
и вторым параметром @red
к монстру .monster-light
.Теперь у нас есть примесь, раскрашивающая монстра в определённый цвет, и её шаблон, делающий цвет более светлым.
Давайте создадим и применим второй шаблон, в котором цвет будет становиться наоборот чуть темнее, чем в оригинальной примеси.
В задании применяются встроенные в LESS функции lighten
и darken
для работы с цветом. Они рассматриваются в задании первой части курса по LESS.
.paint
с первым параметром dark
и со вторым параметром @color
.background-color
значение darken(@color, 20%)
..paint
с первым параметром dark
и со вторым параметром @red
к монстру .monster-dark
.Если нужно задать общие свойства для нескольких шаблонов одной и той же примеси, можно создать универсальный шаблон:
LESS.font-size(bigger; @size) {
font-size: @size * 2;
}
.font-size(smaller; @size) {
font-size: @size / 2;
}
.font-size(@_; @size) {
color: #000000;
} // универсальный шаблон
.content-bigger {
.font-size(bigger, 20px);
}
.content-smaller {
.font-size(smaller, 20px);
}
Универсальный шаблон применяется вместе с остальными шаблонами:
CSS.content-bigger {
font-size: 40px;
color: #000000;
}
.content-smaller {
font-size: 10px;
color: #000000;
}
В качестве имени в универсальный шаблон передаётся специальная переменная @_
, за ней следуют параметры. Важно, чтобы универсальный шаблон принимал те же параметры, что и все остальные шаблоны.
Давайте применим к монстрам разные шаблоны и создадим универсальный шаблон, который применится одновременно со всеми остальными.
.monster-happy
примените примесь .transform
с первым параметром increase
и со вторым параметром 50px
,.monster-foolish
примените примесь .transform
с параметрами decrease
и 50px
..transform
с первым параметром @_
и со вторым параметром @size
. Внутри задайте фоновый цвет @red
.
Обратите внимание, что универсальный шаблон .transform(@_; @size)
применился к обоим монстрам.
В этом испытании также нужно использовать созданные примеси с шаблонами и трансформировать портреты монстров.
В примесях можно использовать полноценные условия, которые могут изменять поведение примеси в зависимости от значений входных параметров.
Чтобы создать условие, нужно после названия примеси поставить ключевое слово when
, за которым в скобках написать условную конструкцию. Пример:
LESS.mixin(@variable) when (@variable = 1) {
// сделать что-то
}
Такая примесь применится, если «вызвать» её с параметром 1
. В противном случае примесь не применится.
LESS.some-class {
.mixin(1);
}
В условной конструкции допускаются следующие операторы: >
, >=
, =
, =<
, <
. Также допустимо использовать встроенные функции LESS, которые возвращают конкретные значения.
К примеру, в LESS есть встроенная функция lightness
, которая принимает в качестве параметра значение цвета и возвращает степень его светлоты. Чёрный цвет обладает 0%
светлоты, а белый — 100%
. Вот пример её использования:
LESS.mixin(@color) when (lightness(@color) > 50%) {
// сделать что-то, когда цвет светлее серого
}
.mixin(@color) when (lightness(@color) = 100%) {
// сделать что-то, когда цвет полностью белый
}
Давайте создадим примесь, которая в зависимости от цвета текста, будет задавать контрастный фоновый цвет блока. Сначала сделаем вариант со светлым текстом и тёмным фоном.
.set-color
с параметром white
к подписи .note
..set-color
с параметром @color
и с условием lightness(@color) >= 50%
background-color
значение black
.Можно создать несколько примесей с одинаковыми названиями, но разными условиями. Тогда применяться будут только те примеси, условия которых выполняются.
В прошлом задании мы создали примесь, которая добавляет чёрный фон для светлого текста, но если цвет текста будет тёмным, то эта примесь не сработает и у блока совсем не будет фонового цвета.
Теперь обработаем второй случай: если цвет текста тёмный, то фоновый цвет должен быть белым.
Снова воспользуемся примесью с условием и функцией lightness
.
.set-color
с параметром @color
и с условием lightness(@color) < 50%
. Внутри примеси задайте свойству background-color
значение white
..note
измените в примеси параметр white
на black
.Условия в примесях могут работать не только с параметрами, с которыми «вызвана» примесь, но и с переменными, объявленными вне примесей. Например, если создать примесь с условием, но без параметров:
LESS.text-color() when (@theme = light) {
color: white;
}
А потом создать внешнюю переменную и вызвать где-то примесь:
LESS@theme: light;
.content {
.text-color();
}
То условие выполнится, созданная примесь отработает:
CSS.content {
color: white;
}
То есть можно управлять условиями примесей с помощью внешних переменных.
Давайте попробуем покрасить монстра в разные цвета в зависимости от значения одной переменной.
.paint
без параметров с условием @type = good
и задайте внутри примеси background-color: #7fdbff;
..paint()
к монстру .monster-happy
..paint
с условием @type = bad
и задайте внутри background-color: #ff4136;
.@type
с good
на bad
.В LESS есть вcтроенные функции для проверки типа значения. Их можно применять в условиях примесей для проверки типа переданного параметра. Пример:
LESS// проверка: значение — цвет
.mixin(@param) when (iscolor(@param)) { … }
// проверка: значение — число
.mixin(@param) when (isnumber(@param)) { … }
// проверка: значение — строка
.mixin(@param) when (isstring(@param)) { … }
// проверка: значение — ключевое слово
.mixin(@param) when (iskeyword(@param)) { … }
// проверка: значение — url
.mixin(@param) when (isurl(@param)) { … }
Все эти функции возвращают true
, если переданный в них параметр соответствует проверяемому типу.
Таким образом можно создать универсальную примесь, которая в зависимости от типа переданных параметров будет работать по-разному.
Попробуем такой подход на практике.
.magic
с параметром @parameter
и условием iscolor(@parameter)
. В ней задайте фоновый цвет со значением @parameter
..magic
с параметром @parameter
и условием isnumber(@parameter)
. В ней задайте ширину и высоту равные @parameter
..monster-happy
примените примесь .magic
с параметром @red
,.monster-foolish
— с параметром 150px
.В этом испытании вам вновь предстоит поработать с портретами монстров.
Но на этот раз примеси уже созданы и применены ко всем монстрам. Вам нужно дописать к примесям условия таким образом, чтобы к нужным монстрам применились только нужные примеси.
Пожалуйста, не меняйте применения примесей! Испытание нужно пройти только с помощью условий примесей.
Переменные можно использовать не только в значениях CSS-свойств, но и как составные части селекторов, названий свойств или как «кусочки» значений свойств. С помощью такой подстановки переменных, или Variable Interpolation, можно динамически формировать разные части CSS-правил.
Чтобы сделать подстановку значения переменной, нужно использовать фигурные скобки вокруг её имени:
LESS@state: success;
@property: color;
@icon: "question";
@pixels: 2;
.btn-@{state} {
background-color: green;
}
.btn-error {
background-@{property}: red;
}
.btn-help {
background-image: url("/img/icons/@{icon}.png");
}
.btn-info {
border: ~"@{pixels}px" solid blue;
}
Из примеров выше скомпилируется такой CSS:
CSS.btn-success {
background-color: green;
}
.btn-error {
background-color: red;
}
.btn-help {
background-image: url("/img/icons/question.png");
}
.btn-info {
border: 2px solid blue;
}
Кстати, тильда ~
в примере выше нужна для хитрого механизма экранирования LESS. Без неё «склеивание» переменной и единицы измерения не сработает.
С помощью «переменных-вставок» можно формировать имена селекторов динамически в зависимости от определённых условий или в цикле. Эти приёмы мы рассмотрим далее в курсе.
@number
и задайте ей значение 1
..monster-@{number}
,@red
.@number
на 2
.Обратите внимание какие CSS-классы при этом генерируются.
В LESS нет специального синтаксиса для циклов. Но есть возможность вызывать примеси внутри самих себя. Так с помощью рекурсии и реализуются циклы. Рассмотрим пример:
LESS.mixin(@n) {
.mixin(@n + 1);
}
.mixin(1);
В примере создаётся «бесконечный» цикл с увеличивающейся переменной-счётчиком, который никогда не закончится. Чтобы рекурсия всё таки когда-нибудь прекращалась, к примеси добавляется условие выполнения:
LESS.mixin(@n) when (@n > 0) {
.mixin(@n - 1);
}
.mixin(2);
Теперь цикл выполнится два раза, сработает условие выполнения примеси и произойдёт выход из рекурсии.
Для чего можно применять циклы? Например, для генерирования целых CSS-правил. Если в цикле в имени селектора использовать переменную-вставку из прошлого задания, то можно на выходе получить набор правил с разными селекторами. В примере ниже цикл исполняется три раза, в каждой итерации создастся правило с переменной-счётчиком @n
в качестве суффикса селектора:
LESS.mixin(@n) when (@n > 0) {
.text-@{n} {
}
.mixin(@n - 1);
}
.mixin(3);
CSS.text-3 {}
.text-2 {}
.text-1 {}
Опробуем циклы на практике.
.generate-colors
создайте CSS-правило .monster-@{n}
, а внутри него задайте цвет фона @red
.@n > 0
..generate-colors(@n - 1);
.generate-colors(1)
измените параметр 1
на 3
.Обратите внимание какие CSS-классы при этом генерируются.
Внутри «цикла» переменную-счётчик можно использовать не только в условиях или в селекторах, но и в значениях свойств.
В этом задании мы раскрасим монстров в разные цвета в цикле с помощью функции spin
, которая рассматривалась в задании первой части курса по LESS.
Давайте подставим в качестве аргумента функции spin
переменную-счётчик @n
, увеличенную в несколько раз, и посмотрим что будет!
.monster-@{n}
замените значение фонового цвета на spin(@red, @n * 10)
,spin(@red, @n * 20)
spin(@red, @n * 100)
.Теперь проверим знания о циклах.
В испытании нужно сгенерировать правила для десяти ступенек (.stair-1 … stair-10
) с помощью примеси generate-stairs
, которую нужно вызывать рекурсивно.
Цвет отсчитывается от @base-color
начиная с первой ступеньки и вычисляется с помощью функции spin
в цикле. Шаг изменения цвета кратен 5
. Кстати, шаг может быть отрицательным или положительным.
Ширина ступенек задаётся в процентах от ширины контейнера .stairs
и кратна 10
.
С помощью примесей и небольших вычислений можно красиво и быстро создать «вертикальный ритм» текста с заголовками, параграфами и списками. Мы уже немного рассказывали про «вертикальный ритм» в задании курса «Оформление текста с помощью CSS». В этой серии рассмотрим другой подход.
Основу для вертикального ритма будет задавать переменная @line
, в которой хранится высота одной «визуальной» строки текста. Крупные блоки текста, например, заголовки первого уровня h1
будут занимать три «визуальные» строки. Заголовки h2
и h3
будут занимать две строки. Обычный текст в параграфах будет однострочным. Размер шрифта при этом подберём так, чтобы текст при заданной высоте строки смотрелся гармонично.
Между блоками текста (заголовками, параграфами, списками) нужно установить соразмерный отступ. По умолчанию сделаем его равным @line
.
Итак, в деле нам пригодятся две примеси: .set-font
, которая устанавливает размер шрифта и высоту строки, и .set-margin
для задания вертикальных отступов.
В примеси .set-font
для высоты строки и в .set-margin
для верхнего и нижнего отступа зададим значение по умолчанию @line
.
Для наглядности мы добавили на страницу вертикальную «сетку», шаг которой тоже зависит от @line
. В итоге все блоки текста должны будут «идти в ритм» с вертикальной сеткой.
Начнём с выравнивания заголовков.
body
примените миксин .set-font
с параметром @line * 0.6
.h1
примените .set-font
с параметрами @line * 2, @line * 3
и .set-margin
без параметров.h2
примените .set-font
с параметрами @line * 1.5, @line * 2
и .set-margin
.h3
примените .set-font
с параметрами @line * 1.2, @line * 2
и .set-margin
.Далее займёмся параграфами и списками.
Для параграфов немного уменьшим размер шрифта относительно @line
.
Для списка просто добавим стандартные вертикальные отступы.
А для элементов списка тоже немного уменьшим шрифт, как у параграфов, и зададим вертикальные отступы в половину величины @line
Когда значения размера шрифта, высоты строки и отступов будут заданы, можно легко управлять всеми величинами с помощью одной переменной @line
. При этом «вертикальный ритм» будет сохраняться.
В конце можно убрать «сетку», чтобы увидеть, как гармонично смотрится текст.
p
примените миксин .set-font
с параметром @line * 0.8
.ul
примените .set-margin
без параметров, а к li
примените .set-font
с параметром @line * 0.8
и .set-margin
с параметрами @line / 2, @line / 2
.@line
задайте значение 16px
.body
уберите класс grid
.В задании первой части курса по LESS мы рассматривали, как с помощью встроенных функций создать палитру и оттенки цветов для отдельных блоков.
Мы создавали для каждого цвета и оттенка отдельную переменную. Недостаток данного подхода — дублирование кода для вычисления искомых цветов.
Избавиться от дублирования нам помогут примеси. Давайте вынесем повторяющий участок LESS-кода в примесь и будем применять её с разными параметрами к соответствующим блокам.
В примеси .generate-colors
:
@bg-color
и задайте ей значение lighten(@color, 35%)
,@bg-color
,darken(@bg-color, 50%)
,darken(spin(@bg-color, -10), 5%)
.Итак, примесь готова.
Остаётся только применить её с подходящими параметрами ко всем блокам.
Код стал компактнее, нет повторяющихся участков кода, и не создаются лишние переменные.
Отсюда следует основное предназначение примесей — выделять повторяющийся код в отдельные блоки для последующего использования. Чем меньше дублируется код, тем его меньше. А чем меньше кода, тем ниже вероятность ошибок в нём. Профит!
Примените примесь .generate-colors
:
.alert-error
с параметром @error-color
;.alert-info
с параметром @info-color
;.alert-warning
с параметром @warning-color
;.alert-success
с параметром @success-color
.Дальше мы рассмотрим несколько полезных примесей, которые могут часто использоваться в повседневной практике.
Одна из самых распространённых задач — горизонтальное и вертикальное выравнивание блока относительно родительского контейнера.
В этом задании давайте создадим примесь для быстрого выравнивания. Особенности этого метода:
top
, right
, bottom
, left
и автоматических внешних отступов.Попробуем этот метод на практике.
.zero-centered
задайте абсолютное позиционирование,top
, right
, bottom
и left
равными 0
,.centered-box
задайте ширину и высоту равные 100px
(так как блок может быть произвольных размеров, не будем включать задание ширины и высоты в примесь)..zero-centered
задайте внешний отступ со всех сторон со значением auto
.Ещё одна распространённая задача — реализовать блок треугольной формы с помощью CSS. Для её решения подходит управление шириной и цветом рамок, который мы уже рассматривали в серии заданий курса «Рамки и фоны, часть 2».
Универсальную примесь для создания «треугольников» на CSS удобно держать в своём арсенале наготове, чтобы при необходимости просто написать одну строчку кода, не вспоминая подробности реализации.
Итак, нам нужна примесь, которая будет принимать в качестве параметров: направление, в которое «смотрит» треугольник, его размер и цвет.
Так как в примеси нужно учесть четыре направления (вверх, вправо, вниз и влево), уместно будет воспользоваться шаблонами примесей. В универсальном шаблоне будут заданы общие для всех сторон свойства, а в специфичных шаблонах — разные.
В задании в LESS-код уже добавлена универсальная примесь .triangle
, в которой заданы правила для всех «треугольников»: нулевые ширина и высота (так как мы будем работать с рамками, сами блоки будут невидимы), а также сплошной стиль рамки.
Давайте применим примесь к блоку и зададим оставшиеся параметры рамки — цвет и толщину.
.triangle
с параметрами top
, 100px
и #ff4136
к блоку .triangle-box
..triangle
задайте толщину рамки @size
@color
.
Следующим шагом сделаем шаблон примеси для «треугольника», направленного вверх. Напомним, что к .triangle-box
мы уже применили примесь с шаблоном top
:
LESS.triangle-box {
.zero-centered;
.triangle(top; 100px; #ff4136);
}
Теперь создадим сам шаблон top
примеси .triangle
. В нём левой и правой рамке зададим прозрачный цвет, а верхнюю часть рамки уберём, чтобы она не занимала место.
.triangle
с именем top
и параметрами @size
и @color
.transparent
левой и правой рамке,border-top-style
со значением none
.Теперь остаётся создать шаблоны для остальных направлений «треугольной» примеси подобно сделанному варианту.
Мы уже применили эти шаблоны примесей к блокам .triangle-box-top
, .triangle-box-right
, .triangle-box-bottom
и .triangle-box-left
с разными параметрами цвета. Вам остаётся написать нужное наполнение этих шаблонов.
Создайте шаблоны right
, bottom
и left
примеси .triangle
.
right
задайте прозрачный цвет верхней и нижней рамке, а правой — стиль none
.bottom
задайте прозрачный цвет левой и правой рамке, а нижней — стиль none
.left
задайте прозрачный цвет верхней и нижней рамке, а левой — стиль none
.В этом испытании вам предстоит построить уже знакомую вам по курсу Рамки и фоны, часть 2 круглую стрелку с помощью рамки.
Вам дан набор примесей, которые нужно применить для .arrow-round
и его псевдоэлемента ::after
. Все числовые значения примесей кратны 5
и задаются в пикселях.
Удачи!