Less
lesscss.org
Приступая к работе с 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;
}
Комментарии к статье
в последней таблице демонстрирующей результат не показано как в стилях отобразились
color: red;
clear: both;
Статья - топ! Спасибо