Статьи

Понимание Меньше Стражей и Петель

Желание разработчиков перенести функции из программирования в CSS привело к созданию CSS-препроцессоров. Они позволяют нам определять переменные и создавать функции так же, как мы делаем это в JavaScript; но что еще более важно, мы можем сделать наш код более гибким, используя условные и итеративные блоки.

Такие блоки могут быть созданы с использованием Less , но синтаксис для их использования весьма отличается от традиционного if..else и for шаблонов. В отличие от Sass и Stylus , Less старается держаться как можно ближе к оригинальному CSS. Поэтому для построения условных выражений и циклов используется синтаксис, заимствованный из медиа-запросов . Поначалу это может немного смущать, но как только мы узнаем, как это работает, мы увидим, что это просто еще один способ сказать то же самое.

Меньше смешанных гвардейцев

Меньше называет свои условные высказывания смешанными охранниками . Чтобы построить условный блок, нам нужно использовать mixins вместе с охранниками. Покажем основную схему на примере:

 .theme (@mode) when (@mode = "dark") { background-color: darkblue; } .theme (@mode) when (@mode = "light") { background-color: lightblue; } div { width: 50px; height: 50px; .theme("light"); } 

Здесь у нас есть миксин с одним параметром .theme(@mode) . Мы проверяем, соответствует ли этот параметр определенному условию. Только после того, как параметр пройдет тест, код внутри mixin будет выполнен. Для каждого отдельного условия нам нужно повторить имя миксина вместе с его параметром (ами). В нашем случае у нас есть два условия. Как мы видим, для замены ключевого слова if , используемого во многих других языках программирования, Less использует элементы защиты. Охранник создается ключевым словом when за которым следует определенное условие. Чтобы понять это проще, давайте посмотрим, как будет выглядеть вышеуказанный блок в JavaScript:

 function theme(mode){ if (mode == "dark"){ element.style.backgroundColor = "darkblue"; } else if (mode == "light"){ element.style.backgroundColor = "lightblue"; } } 

Таким образом, mixin guard — это просто функция с вложенным оператором if..else . Хотя он создан по-другому.

В нашем примере с div мы используем mixin guard с передачей «light» в качестве параметра — .theme("light") . И когда код скомпилирован с помощью Less, мы получим следующий вывод:

 div { width: 50px; height: 50px; background-color: lightblue; } 

Здорово! Но что, если у нас есть общий стиль, который мы хотим применить в обоих случаях. Например, когда тема установлена ​​на «светлый», наряду со светло-голубым цветом фона, мы хотим добавить оранжевую рамку. Для этого нам нужно добавить миксин без охраны, после наших условий:

 .theme (@mode) when (@mode = "dark") { background-color: darkblue; } .theme (@mode) when (@mode = "light") { background-color: lightblue; } .theme (@mode) { border: thick solid orange; } div { width: 50px; height: 50px; .theme("light"); } 

Теперь мы видим, что стиль из последнего блока нашего mixin guard добавлен в скомпилированный код:

 div { width: 50px; height: 50px; background-color: lightblue; border: thick solid orange; } 

Если мы изменим режим темы на «темный», стиль рамки все равно останется.

OK. Давайте посмотрим на другой немного другой вариант. На этот раз мы хотим добавить стиль по умолчанию, который будет применяться, когда ни первое условие, ни второе не будут выполнены. Для этого мы добавляем миксин со специальным типом защиты — вместо обычного условия мы используем функцию default() .

 .theme (@mode) when (@mode = "dark") { background-color: darkblue; } .theme (@mode) when (@mode = "light") { background-color: lightblue; } .theme (@mode) when (default()) { background-color: @mode; } div { width: 50px; height: 50px; .theme(red); } 

Этот вариант эквивалентен последнему в блоке JavaScript if..else :

 function theme(mode){ if (mode == "dark"){ element.style.backgroundColor = "darkblue"; } else if (mode == "light"){ element.style.backgroundColor = "lightblue"; } else { element.style.border = mode; } } 

Мы используем красный в качестве параметра, и он не совпадает ни с «светлым», ни с «темным». Следовательно, цвет фона в скомпилированном коде установлен на красный:

 div { width: 50px; height: 50px; background-color: red; } 

Менее также позволяет нам использовать логические операторы с охранниками. Итак, если нам нужно отменить условие, мы можем сделать это, используя ключевое слово not , например:

 .theme(@mode) when not (@mode = "dark"), (@mode = "light") { background-color: @mode; } 

Здесь мы также используем оператор OR , который в Less эмулируется запятой. Код для этой защиты имеет тот же эффект, что и функция default() .

Меньше петель

Less определяет цикл аналогично смешиванию охранников. Сначала мы создаем миксин с параметром счетчика и охрану с нашим условием. Затем мы помещаем код, который мы хотим генерировать, в миксин. Последнее, что нам нужно, это способ увеличить / уменьшить значение счетчика. Мы используем тот факт, что mixin может вызывать сам себя, и мы добавляем тот же mixin, что и вложенную функцию. В результате этого наш миксин будет циклически повторяться до тех пор, пока выполняется условие, установленное в страже. Давайте проясним ситуацию с помощью следующего примера:

 .make-variants(@i:1) when (@i =< 3) { .variant-@{i} { width: @i * 40px; height: @i * 20px; background-color: orange; margin-bottom: 10px; } .make-variants(@i + 1); // increment function } .make-variants(); 

У нас есть параметр счетчика, установленный на 1 ( @i:1 ), и условие ( @i =) which will return true пока значение счетчика не станет равным или меньшим, чем 3. Внутри миксина мы помещаем код, который хотим генерировать на каждой итерации. И, наконец, чтобы сделать возможной итерацию, мы добавляем сам миксин как вложенную функцию, которая будет увеличивать значение счетчика на единицу ( @i + 1 ).

Приведенный выше блок кода похож на следующий цикл for в JavaScript:

 for (i = 1; i <=3 ; i++) { ... } 

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

 .variant-1 { width: 40px; height: 20px; background-color: orange; margin-bottom: 10px; } .variant-2 { width: 80px; height: 40px; background-color: orange; margin-bottom: 10px; } .variant-3 { width: 120px; height: 60px; background-color: orange; margin-bottom: 10px; } 

Обратите внимание, что место, где вы помещаете функцию приращения, имеет значение. Если вы поместите его выше стилей, порядок в скомпилированном коде будет обратным — .variant-3 будет .variant-3 , и так далее.

Резюме

Как мы видим, варианты if..else и if..else for Less не так запутаны, как может показаться на первый взгляд. Как только мы поймем, как они работают, мы можем легко использовать их, чтобы сделать наш CSS более гибким и многократно используемым.