Циклы в CSS препроцессорах

Циклы в CSS препроцессорах

От автора: если вы смотрели старые фантастические фильмы, то должны знать, насколько циклы там мощная штука. Скормите роботу бесконечный цикл и бабах. Останется от робота только пыль. Циклы в препроцессорах не вызывают драматических взрывов в космосе (надеюсь), но они очень полезны при написании чистого CSS кода. Пока все говорят о библиотеках шаблонов и модульном дизайне, основное внимание приковано к CSS селекторам. Неважно, в чем вы пишите селекторы (BEM, OOCSS, SMACSS, ETC), циклы добавят читабельности вашим шаблонам и упростят работу с ними, заложив их в ваш код.

Мы рассмотрим возможности циклов, а также как их использовать в основных CSS препроцессорах: Sass, Less и Stylus. У каждого языка свой уникальный синтаксис, но все они делают одно и то же. Зациклить кошку можно разными способами.

PostCSS тоже популярный, но у него нет своего синтаксиса. Иногда его называют постпроцессором, я бы назвал его метапроцессором. PostCSS позволяет писать и делиться синтаксисом своего собственного препроцессора. Если бы вы захотели, вы бы могли переписать Sass или Less в PostCSS, но кто-то уже опередил вас.

Условия цикла

Звездный путь был от части прав. Если опрометчиво подойти к делу, бесконечный цикл может замедлить или сломать компилятор. Не самый лучший способ превратить робота в пар, но бесконечные циклы могут раздражать тех, кто использует ваш код. Вот почему циклы всегда должны решать ограниченные задачи. Обычно задается ряд повторов с инкрементом или ставится задача по сбору объектов.

Препроцессоры. Быстрый старт

Овладейте азами работы с препроцессорами Less и Sass с полного нуля менее чем за 2 недели

Узнать подробнее

Из программирования:

Циклы while – общие, они выполняются, пока соблюдается условие. Будьте осторожны! Обычно именно тут возникают бесконечные циклы.

Циклы for – инкрементные, повторяются заданное число раз.

Циклы for-each проходятся по коллекции или списку, вытягивая по одному элементу за раз.

Каждый тип циклов более узконаправленный, чем предыдущий. Цикл for-each – частный случай цикла for, который в свою очередь является одним из вариантов цикла while. Однако большинство ваших случаев применения будут подпадать под более конкретные категории. Я не смог найти чистый цикл while на реальных сайтах, большая часть примеров намного лучше работает на for или for-each. Возможно, поэтому в Stylus прописан синтаксис только для последнего. В Sass есть синтаксис для всех трех циклов, а в Less вообще нет циклов. Но это нас не остановит! Поехали.

Коллекция и циклы for-each

Циклы в препроцессорах чаще всего полезны, когда вам нужно обработать коллекцию (список или массив) элементов. К примеру, массив иконок социальных сетей и цветов или список состояний-модификаторов (success, warning, error и т.д.). Циклы for-each привязаны к известной коллекции элементов, из-за чего, как правило, это самые конкретные и понятные циклы.

Начнем с прогона в цикле простого списка цветов, чтобы понять принцип работы.

В Sass для получения цветов нам понадобится воспользоваться директивой @each (@each $item in $list):

В Stylus с коллекциями работает синтаксис for (for item in list):

В Less нет синтаксиса для циклов, но их можно сымитировать с помощью рекурсии. Рекурсия – это когда вы вызываете функцию или миксин из самой себя. В Less для рекурсии можно использовать миксины:

.recursion() {
  /* бесконечный рекурсивный цикл! */
  .recursion();
}

Теперь давайте добавим условие when в миксин, чтобы цикл не был бесконечным.

.recursion() when (@conditions) { 
  /* рекурсивный цикл "while" с условием! */
  .recursion();
}

Данный цикл можно превратить в for, если добавить счетчик (@i), начинающийся с 1 с постоянным инкрементом на каждом повторении (@i + 1), пока будет выполняться наше условие (@i <= length(@list)). Где length(@list) ограничивает количество итераций длиной нашей коллекции. Если при каждом проходе извлекать следующий элемент списка, мы получим самодельный цикл for-each:

В Less все намного сложнее. Закаляет характер.

Кнопки социальных сетей

Прогонять списки в цикле полезно, но чаще всего вы будете проходить в цикле по объектам. Один из распространенных примеров – присвоение разных цветов и иконок кнопкам социальных сетей. Для каждого элемента в списке нам необходимо название сайта и цвет бренда этой социальной сети:

$social: (
  'facebook': #3b5999,
  'twitter': #55acee,
  'linkedin': #0077B5,
  'google': #dd4b39,
);

В Sass чтобы получить доступ к паре ключ/значение (название сети/цвет бренда), нам понадобится синтаксис @each $key, $value in $array. Ниже представлен полный цикл:

В Stylus похожий синтаксис: for key, value in array

В Less необходимо извлекать части пары вручную:

Инкрементные циклы for

Циклы for могут повторяться намного больше раз, чем длина объекта. С их помощью можно создавать grid макеты (for columns from 1 through 12), пробегаться по цветовому колесу (for hue from 1 through 360) и считать количество тегов div с псевдоклассом nth-child и сгенерированным контентом.

Давайте начнем с того, что пробежимся в цикле через 36 элементов div, будем присваивать им номера и задавать фон при помощи :nth-child.

В Sass для этого есть специальный синтаксис for: @for $count from $start through $finish, где $start и $finish – целочисленные значения. Если первое значение больше второго, Sass запустит обратный отсчет.

Ключевое слово through обозначает, что наш цикл будет повторяться 36 раз. Также можно использовать ключевое слово to, но тогда последнее значение не будет включаться: @for $i from 1 to 36 повторится только 35 раз.

В Stylus реализован похожий синтаксис инкрементации, только to и through заменены на … и .. соответственно:

В Stylus также есть функция range(), в которой можно менять значение инкремента. Код for hue in range(0, 360, 10) увеличивает счетчик на 10 в каждом повторении.

В Less нам опять придется использовать рекурсивные миксины. Для количества итераций (@i) можно создать аргумент, добавив условие when (@i > 0), вычитая единицу на каждой итерации. Так мы сымитируем уменьшающийся цикл:

Стоит отметить, что нумерацию с помощью nth-child в CSS можно написать и без препроцессоров. В CSS нет структуры циклов, но в нем есть counter() – функция, которую можно инкрементировать по любым DOM условиям. Данную функцию можно использовать в генерируемом контенте. К сожалению, ее нельзя использовать за пределами свойства content (пока что), т.е. наш фон не применится:

Система сеток

Время от времени я использую инкрементные циклы в абстрактном Sass, но почти никогда в настоящих стилях. Исключение составляют только генерируемые нумерованные селекторы, создаваемые с помощью nth-child (как в примере выше) или с помощью автоматически генерируемых классов (часто используются в системах сеток). Давайте построим простую жидкую систему сеток без разделителей, чтобы усложнить вычисления:

Препроцессоры. Быстрый старт

Овладейте азами работы с препроцессорами Less и Sass с полного нуля менее чем за 2 недели

Узнать подробнее

Каждый элемент сетки представлен в процентах. Значение вычисляется по формуле span / context * 100% — стандартное вычисление для всех систем сеток. Пример в Stylus и Less:

Уникальные аватарки

Не так давно на сайте OddBird мы проектировали приложение с дефолтными аватарками пользователей. Но мы хотели, чтобы дефолтные аватарки были максимально уникальными. В конце концов, мы создали лишь 9 уникальных иконок и использовали циклы, чтобы трансформировать их в 1296 различных аватарок. Большинство пользователей никогда не увидят дубликат.

У всех аватаров 5 атрибутов:

&lt;svg class=&quot;avatar&quot; data-dark=&quot;1&quot; data-light=&quot;2&quot; data-reverse=&quot;true&quot; data-rotation=&quot;3&quot;&gt;
  &lt;use xlink:href=&quot;#icon-avatar-1&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot;&gt;&lt;/use&gt;
&lt;/svg&gt;

форма начальной иконки (9 вариантов);

поворот на 0, 90, 180 или 270 градусов (4 варианта);

темный цвет заливки (6 вариантов);

светлый цвет фона (6 вариантов);

атрибут true/false, инвертирующий цвета (2 варианта).

В коде 6 цветов и три цикла:

@for $i from 0 through 3 дает нам 4 поворота;

@for $i from 1 through length($colors) позволяет пробегаться в цикле по списку цветов ($colors) и присваивать каждому цвету число ($i). Обычно я бы воспользовался циклом @each для коллекции цветов, но с циклом @for легче, когда нужно присвоить число каждому элементу;

Вложенный @each $reverse in (true, false) позволяет нам переворачивать передний и задний фон для каждой комбинации цвета.

Конечный результат в Sass:

Конвертировать код в Less и Stylus можете сами, это будет ваша домашняя работа. Я устал смотреть на этот код.

Общие циклы while

Циклы while используются редко, но я время от времени использую их. Для меня они больше всего полезны, когда мне нужно проследовать по какому-то пути и узнать, что в конце. Я не хочу бегать в цикле через всю коллекцию или заданное число итераций, я хочу бегать в цикле до тех пор, пока не найду то, что искал. Такие циклы я использую в абстрактных средствах, но это не что-то, что вам будет нужно каждый день в стилях.

Я создал инструмент, который хранит и манипулирует цветами в Sass. Хранение цветов в переменных – наверное, самый частый случай использования в любых препроцессорах. Большинство делает так:

$pink: #E2127A;
$brand-primary: $pink;
$site-background: $brand-primary;

Понимаю, что pink, скорее всего, не единственный цвет на вашем сайте, но мне пока что понадобится только он. Я специально присвоил несколько имен, так как полезно задавать слой абстракции – от простых цветов (pink) до более широких шаблонов (brand-primary) и конкретных кейсов (site-background). Также я хочу перевести список цветов в палитру, которую будет понимать мой препроцессор. Я должен как-то сказать, что все эти значения связаны и входят в шаблон. Для этого я храню все цвета темы в одной карте Sass с парами ключ-значение:

$colors: (
  'pink': #E2127A,
  'brand-primary': 'pink',
  'site-background': 'brand-primary',
);

Зачем? Так я могу указать генератор стилей в одну переменную и автоматически создать обновленную палитру цветов. Но есть и побочные эффекты, способ не для всех. Карта не позволяет мне делать прямое назначение в парах, как я могу это делать с переменными. Чтобы найти значение для каждого цвета, мне нужно пройти путь из ключевых имен в цикле while:

Я всегда так делаю, но если вы попробуете поискать мой код для Sass цикла @while, вы не найдете его. Потому что то же самое можно написать с помощью рекурсивной функции, что сделает код повторно используемым:

Теперь функцию color() можно вызывать в любом месте кода. В Stylus нет синтаксиса для циклов while, но в нем есть массивы и рекурсивные функции:

В Less нет встроенных массивов, но их можно сымитировать, создав список с парами, как мы делали для цветов социальных сетей:

@colors:
  'pink' #E2127A,
  'brand-primary' 'pink',
  'site-background' 'brand-primary'
;

Нам придется создать свой собственный миксин @array-get, чтобы вытягивать значения из массива по ключам, после чего создать свой рекурсивный цикл while, чтобы следовать пути:

В рамках демонстрации код работает, но в Less это можно сделать гораздо лучше, так как там можно задавать пространство имен для переменных без массива (в отличие от Sass и Stylus):

Теперь, когда мои цвета успешно собраны в одной переменной, я могу с помощью другого цикла сгенерировать палитру цветов. Пример в Sass:

Уверен, вы можете написать гораздо лучше, чем я.

Зацикливаемся!

Если вы не уверены, когда использовать циклы в своем коде, а когда нет, следите за повторениями. У вас в коде есть множество селекторов, следующих похожему шаблону, или вычисления, которые постоянно повторяются? Как понять, какой цикл лучше подходит:

Если вы можете перечислить элементы в цикле и присвоить им имена, используйте цикл for-each.

Если важнее количество повторений, чем набор исходных элементов, или если нужно узнать общее количество элементов, используйте цикл for.

Если в один цикл нужно входить с разными данными, попробуйте использовать рекурсивную функцию.

Для всего остального (почти никогда) используйте цикл while.

Если работаете на Less… удачи!

Автор: Miriam Suzanne

Источник: https://css-tricks.com/

Редакция: Команда webformyself.

Препроцессоры. Быстрый старт

Овладейте азами работы с препроцессорами Less и Sass с полного нуля менее чем за 2 недели

Узнать подробнее
Самые свежие новости IT и веб-разработки на нашем Telegram-канале

Препроцессоры. Быстрый старт

Овладейте азами работы с препроцессорами с полного нуля

Получить

Метки:

Похожие статьи:

Комментарии Вконтакте:

Комментарии Facebook:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree