Статьи

Использование Sass Maps

Третья основная версия Sass принесла новый тип данных под названием map . Хотя вы можете быть незнакомы с этим именем, мы уже часто используем карты на других языках, обычно под именами ассоциативных массивов или хэшей . Другими словами, карта Sass — это массив, соответствующий ключам значений.

Не всегда понятно, зачем нам нужны карты в CSS (да, Sass — это CSS), поэтому в этой статье даются подсказки. Этот список, очевидно, не является исчерпывающим, поэтому вы можете найти и поделиться другими вариантами использования.

Синтаксис для Sass Maps

Прежде чем идти дальше, давайте прокачаем всех по теме.

Карта Sass использует скобки в качестве внешних разделителей, двоеточия для сопоставления ключей и значений и запятые для разделения пар ключ / значение. Вот действительная карта Sass:

 $map: ( key: value, other-key: other-value ); 

Несколько вещей, которые вам нужно знать:

Да, ключи не обязательно являются строками; они могут быть чем угодно. Даже null Даже карты. Крис Эппштейн, Мика Годболт, Джеки Бальцер и я поговорили об этом в Твиттере пару недель назад. Имея вид фона JavaScript, я не чувствую себя комфортно, когда в качестве хеш-ключа есть что-то кроме строки. Во всяком случае, это возможно в Sass.

Хорошо, теперь вы должны быть готовы к работе!

Конфигурация проекта

Давайте начнем с общего случая использования. Карты идеально подходят для конфигурации проекта. Идея проста: вы связываете значения с ключами, а затем map-get($map, $key) доступ к ним из любой точки проекта, используя map-get($map, $key) .

Я уже углубился в это в своей статье об управлении отзывчивыми точками останова в Sass . Вот быстрый пример:

 // _config.scss $breakpoints: ( small: 767px, medium: 992px, large: 1200px ); // _mixins.scss @mixin respond-to($breakpoint) { @if map-has-key($breakpoints, $breakpoint) { @media (min-width: #{map-get($breakpoints, $breakpoint)}) { @content; } } @else { @warn "Unfortunately, no value could be retrieved from `#{$breakpoint}`. " + "Please make sure it is defined in `$breakpoints` map."; } } // _component.scss .element { color: hotpink; @include respond-to(small) { color: tomato; } } 

В результате чего:

 .element { color: hotpink; } @media (min-width: 767px) { .element { color: tomato; } } 

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

 // _config.scss $colors: ( sexy: #FA6ACC, glamour: #F02A52, sky: #09A6E4 ); // _component.scss .element { background-color: map-get($colors, sky); } 

В конце концов, вы устанете повторять map-get($colors, ...) снова и снова, так что вы можете использовать небольшую вспомогательную функцию, чтобы облегчить боль:

 // _functions.scss @function color($key) { @if map-has-key($colors, $key) { @return map-get($colors, $key); } @warn "Unknown `#{$key}` in $colors."; @return null; } // _component.scss .element { background-color: color(sky); // #09A6E4 } 

По теме, вы можете прочитать эту статью Erskine Design.

Давайте рассмотрим последний вариант использования карт в качестве конфигурации перед переходом к слоям z-index . Я думаю, что это впервые пришло от Криса Койера, когда он писал о том, как он управляет z-index в проектах Sass. Вы знаете, как вы пишете z-index: 999999999 ? Ну, эти дни прошли.

 // _config.scss $z-layers: ( bottomless-pit: -9999, default: 1, dropdown: 3000, overlay: 4000 modal: 4001 ); // _functions.scss @function z($key) { @if map-has-key($z-layers, $key) { @return map-get($z-layers, $key); } @warn "Unknown `#{$key}` in $z-layers."; @return null; } // _component.scss .overlay { z-index: z(overlay); } .element { z-index: (z(default) + 1); } 

Учитывая, насколько запутанным может быть z-index , я думаю, что было бы хорошо собрать все индексы в одну карту и придерживаться их. Затем вы узнаете, сколько слоев использует приложение, что позволяет легко понять, что происходит (и, рано или поздно, отладить).

Конфигурация модуля

Мы будем придерживаться конфигурации, но давайте углубимся в уровни приложений, занимаясь настройкой модуля / компонента. Я уже писал об использовании карт Sass в качестве объектов конфигурации и почему может быть интересно отказаться от подписи с несколькими аргументами в пользу одного параметра карты. Быстрое подтверждение концепции:

 // _mixins.scss @mixin module($options: ()) { $configuration: map-merge(( color: grey, duration: 0s, border: null ), $options); color: map-get($configuration, color); transition: map-get($configuration, duration); border: map-get($configuration, border); } // _component.scss .element { @include module(( color: pink, duration: .15s )); } 

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

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

 // _mixins.scss @mixin module($color: grey, $duration: 0s, $border: null) { color: $color; transition: $duration; border: $border; } // _component.scss .element { @include module(( duration: .15s, color: pink )...); } 

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

Вот как вы можете использовать карты Sass для настройки ваших миксинов, которые запрашивают несколько аргументов. Если я не ошибаюсь, Python — один из немногих (известных) языков, который позволяет вам вызывать функцию с многомерным массивом, в то время как он запрашивает несколько аргументов. То, что Сасс способен это сделать, довольно удивительно.

Повторяющиеся вещи

До сих пор мы использовали карты, чтобы получить значение, связанное с конкретным ключом. Еще один вид использования Sass-карт — избегать повторяющихся вещей. CSS — очень влажный (напишите все дважды) язык, повторения кода распространены. Именно здесь наличие цикла и списка / карты очень помогает в создании кода СУХОЙ (не повторяйте себя).

Подумайте о значках шрифтов. Шрифт значка обычно представляет собой набор закодированных символов, передаваемых через свойство content псевдоэлемента :before . Например :

 .fa-glass:before { content: "\f000"; } .fa-music:before { content: "\f001"; } .fa-search:before { content: "\f002"; } .fa-envelope-o:before { content: "\f003"; } .fa-heart:before { content: "\f004"; } /* ... */ 

Вау. Очень повторение. Много ВЛАЖНЫХ. Что если вместо этого мы сопоставим имена классов с закодированными символами?

 $icons: ( glass: "\f000", music: "\f001", search: "\f002", envelope-o: "\f003", heart: "\f004" ); @each $name, $icon in $icons { .fa-#{$name}:before { content: $icon; } } 

Лучше не так ли? Особенно, когда у вас есть десятки и десятки иконок в шрифте. Если вы хотите продвинуться дальше, Фредерик Перрен создал классное небольшое демо, используя эту идею на CodePen. Есть также статья от ThoughtBot, использующая тот же подход с фоновыми изображениями.

CSS Dump

Вот еще один вариант использования (впервые представленный Микой Годболтом , если я не ошибаюсь). Мы будем использовать карту Sass в качестве списка CSS-объявлений. Видите ли, разработчики Sass стараются максимально приблизиться к официальному синтаксису CSS при реализации новых функций. Вот почему они решили использовать () для списков / карт (используется в медиа-запросах) и двоеточие в качестве оператора отображения (используется в любом объявлении).

Так как карты Sass выглядят как списки правил CSS, возможно, вы могли бы создать миксин, сбрасывающий содержимое карты Sass:

 // _mixins.scss @mixin print($declarations) { @each $property, $value in $declarations { #{$property}: $value } } // _component.scss .element { @include print(( margin: 0 auto, max-width: 50%, overflow: hidden )); } 

Теперь вы можете думать, почему? Почему бы просто не написать CSS вручную с самого начала, а не пропустить его через миксин? Это все о контексте. При работе с модулем или чем-то, у вас обычно есть карта, хранящая пару переменных, определяющих, как компонент должен вести себя. Например:

 // _component.scss $configuration: ( padding: 1em, margin: 0 1em, color: grey ); .element { color: map-get($configuration, color); padding: map-get($configuration, padding); margin: map-get($configuration, margin); &::before { background-color: map-get($configuration, color); } } 

Вместо того, чтобы вручную получать каждое значение из ключа, вы можете просто напечатать карту с помощью css() mixin;

 // _component.scss .element { @include print($configuration); &::before { background-color: map-get($configuration, color); } } 

В результате чего:

 .element { padding: 1em; margin: 0 1em; color: grey; } .element::before { background-color: grey; } 

Это не так много, но это что-то!

Последние мысли

Как видите, функция карт Sass является мощным инструментом. Это не только делает код более структурированным, но и помогает избежать некоторого раздувания и повторения кода. Как насчет вас, как вы используете карты Sass?