Как создать все свои полезные классы с помощью Sass Maps

1656668771 kak sozdat vse svoi poleznye klassy s pomoshhyu sass maps

Сара Дайан

fksFkPSX1rrJaxBcepas1W3NvxW1ccTGfLtI
Фото Vic на Flickr

Одно из преимуществ полезных классов состоит в том, что они предоставляют вам доступ к каждой мелкой концепции вашей системы проектирования во множестве контекстов. Если ваш основной цвет – королевский синий, вы можете применить его как цвет текста ко всему, что имеет a .text-royal-blue класс как фоновый цвет с a .bg-royal-blue класс и так далее.

Но как написать их эффективным, последовательным и масштабируемым способом?

TL; DR: эта публикация подробно рассказывает о том, как это сделать. Если вы хотите понять весь процесс мышления, читайте дальше. В противном случае вы можете получить код на GitHub или протестировать его на SassMeister.

$royal-blue: #0007ff;
.text-royal-blue {  color: $royal-blue;}
.bg-royal-blue {  background: $royal-blue;}
...

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

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

Что такое Sass Maps?

Карты являются типом данных Sass, представляющим ассоциация между ключами и значениями. Если вы знакомы с другими языками сценариев, вы можете увидеть это как ассоциативный массив. Это позволяет хранить данные и называться для ссылки на каждую часть.

Списки и карты немного похожи, поскольку оба они хранят коллекцию данных и оба могут повторяться в @each петля. Но в отличие от списков карты позволяют легко ссылаться на любую информацию, называя ее по имени. Это делает его безупречным для группирования логически связанной информации.

$colors: (  mako-grey: #404145,  fuel-yellow: #ecaf2d,  pastel-green: #5ad864);

Добавим немного логики

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

@mixin color-modifiers {  // do stuff}

Давайте теперь используем @each директива для прохождения $colors и получить нужные данные.

@mixin color-modifiers {  @each $name, $hex in $colors {    // do stuff  }}

Мы повторяем $colors и в каждом цикле будет ссылаться на текущий ключ $name и будет введен шестнадцатеричный код цвета $hex. Мы можем приступить к созданию нашего набора правил.

@mixin color-modifiers {  @each $name, $hex in $colors {    &-#{$name} {      color: $hex;    }  }}

Теперь для каждой пары на карте @each создаст набор правил, ссылающийся на родительский селектор с помощью & символ, добавляет дефис и название цвета и устанавливает color атрибут к текущему шестнадцатеричному значению.

Другими словами, делая это:

.text {  @include color-modifiers;}

Сгенерирует это:

.text-mako-grey {  color: #404145;}.text-fuel-yellow {  color: #ecaf2d;}.text-pastel-green {  color: #5ad864;}

Достаточно аккуратно, да? На самом деле, мы едва поцарапали поверхность. Сейчас наш mixin может выводить только правила из color атрибут. Что если мы хотим создать несколько полезных классов для фоновых цветов?

К счастью, Sass позволяет нам передавать доводы миксинам.

@mixin color-modifiers($attribute: 'color') {  @each $name, $hex in $colors {    &-#{$name} {      #{$attribute}: $hex;    }  }}

Теперь мы можем точно указать, какой атрибут мы хотим.

Давайте еще немного усовершенствуем наш миксин: префикс модификатора является жестко закодированным дефисом. Это значит, что ваши занятия всегда будут в форме .base-modifier. Что делать, если вам это нужно изменить? Что делать, если вы хотите создать некоторые модификаторы со вкусом BEM (два дефиса)? Опять же мы можем достичь этого, используя аргументы.

@mixin color-modifiers($attribute: 'color', $prefix: '-') {  @each $name, $hex in $colors {    &#{$prefix}#{$name} {      #{$attribute}: $hex;    }  }}

Теперь мы можем генерировать классы-модификаторы с любым префиксом, который нам заблагорассудится. Итак, делая это:

.text {  @include color-modifiers($prefix: '--');}

Сгенерирует это:

.text--mako-grey {  color: #404145;}.text--fuel-yellow {  color: #ecaf2d;}.text--pastel-green {  color: #5ad864;}

Профессиональный совет: в Sass вы можете явно называть аргументы, когда вызываете миксин или функцию (как в примере выше). Это позволяет избежать необходимости предоставлять их в порядке.

Карты в картах

Мне нравится использовать несколько иную цветовую систему, чтобы я мог управлять тональными вариациями. Вкладывая карты в карты, у меня чистый и читабельный способ сохранять оттенки сгруппированными вместе.

$colors: (  grey: (    base: #404145,    light: #c7c7cd  ),  yellow: (    base: #ecaf2d  ),  green: (    base: #5ad864  ));

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

@mixin color-modifiers($attribute: 'color', $prefix: '-', $separator: '-') {  @each $name, $color in $colors {    &#{$prefix}#{$name} {      @each $tone, $hex in $color {        &#{$separator}#{$tone} {          #{$attribute}: $hex;        }      }    }  }}

Мы добавили новый аргумент, $separator, чтобы связать имя цвета и тон. Мы могли бы использовать $prefix но оно не имеет той же цели. Использование выделенной переменной со значением по умолчанию является лучшим выбором, поскольку это дает нам полную свободу при использовании mixin.

Теперь делаем это:

.text {  @include color-modifiers;}

Сгенерирует это:

.text-grey-base {  color: #404145;}.text-grey-light {  color: #c7c7cd;}.text-yellow-base {  color: #ecaf2d;}.text-green-base {  color: #5ad864;}

Прекрасно! Теперь у нас есть помощники, состоящие из базового класса, цвета и тона. Одна вещь, которую нам нужно улучшить, является то, как выводятся модификаторы базового цвета. Нам это действительно не нужно -base суффикс – достаточно базового класса и цвета.

Что мы должны сделать, так это проверить тон во вложенном @each и только выводить его и $separator когда это не «база». К счастью для нас, Sass уже имеет все необходимое.

@if, @else, if()

Нашим первым инстинктом может быть использование @if/@else директивы. Проблема в том, что это вынудит нас повторить код и приведет к сложному коду. Вместо этого мы используем одно из секретных оружий Саса: if().

if() является условным (троечным) оператором Сасса. Он принимает три аргумента: условие и два оператора возврата. Если условие выполняется, if() вернет первый оператор. Иначе вернется второй. Вы можете видеть это как @if/@else сокращение.

@mixin color-modifiers($attribute: 'color', $prefix: '-', $separator: '-', $base: 'base') {  @each $name, $color in $colors {    &#{$prefix}#{$name} {      @each $tone, $hex in $color {        &#{if($tone != $base, #{$separator}#{$tone}, '')} {          #{$attribute}: $hex;        }      }    }  }}

Каждый раз вложены @each цикл разберет a $tone что отличается от «базы», ​​он вернет $separator и $tone как суффикс класса. Иначе он ничего не вернет, оставив класс как есть.

.text-grey {  color: #404145;}.text-grey-light {  color: #c7c7cd;}.text-yellow {  color: #ecaf2d;}.text-green {  color: #5ad864;}

Высушите все это

Скорее всего, в реальном проекте вы захотите использовать разные структуры карты. К примеру, вы можете иметь одноуровневые карты глубины для размеров шрифта и двухуровневые карты глубины для цветов. Вы не собираетесь писать разные миксины для каждого уровня глубины. Это было бы повторяющимся и невозможным. Вы должны быть в состоянии положиться на один миксин, чтобы справиться с этим.

Мы хотим, чтобы общий миксин генерировал все модификаторы и мог обрабатывать многомерные карты. Если вы сравните два миксина, которые мы придумали в этом учебнике, вы заметите, что они очень похожи. Единственное отличие состоит в том, что выполняется дополнительный цикл перед печатью вычисленной декларации CSS. Это типичная работа для a рекурсивный mixin.

Он начнется с an @each директива, с которой мы можем приступить к созданию нашего селектора. Здесь мы проверим, ток ли $key равно «базе», поэтому мы можем решить выводить его или нет. Затем мы проверим, ток ли $value является самой картой: если да, нам нужно снова запустить mixin из того места, где мы есть, и передать ему вложенную карту. В противном случае мы можем распечатать декларацию CSS.

@mixin modifiers($map, $attribute, $prefix: '-', $separator: '-', $base: 'base') {  @each $key, $value in $map {    &#{if($key != $base, #{$prefix}#{$key}, '')} {      @if type-of($value) == 'map' {        @include modifiers($value, $attribute, $separator);      }      @else {        #{$attribute}: $value;      }    }  }}

И вуаля! Этот миксин будет работать с картами любой глубины. Не стесняйтесь использовать его в своих проектах! Если вам это нравится, вы можете продемонстрировать свою любовь, отметив это на GitHub. Кроме того, если вы хотите его улучшить, оставьте комментарий по существу, чтобы я мог его обновить?

Первоначально опубликовано на frontstuff.io.

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

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