Для масштабируемых интерфейсов Sass Maps — это благословение. Извлечение конфигурации из логики модуля — отличный способ структурирования. Позвольте мне объяснить вам, почему я считаю, что Sass Maps — лучшая функция в Sass 3.3.
Sass 3.3
Sass 3.3 уже давно доступен каждому, но многие из его реальных функций все еще незнакомы многим разработчикам. Новая версия Sass принесла нам новый тип данных с именем map . Карты содержат набор пар ключ / значение и помогают нам создавать небольшие области конфигурации для упрощенной базы кода.
Как использовать Sass Maps
Чтобы быть в курсе, мы рассмотрим основы использования Sass Maps, а затем рассмотрим некоторые варианты использования.
Генерация карты
Вот краткий обзор синтаксиса для нахальной карты. Начните с имени переменной (в данном случае $map
), а затем введите несколько ключей со значениями, разделенными запятыми, все в фигурных скобках:
1
2
3
4
|
$map: (
key: value,
nextkey: nextvalue
);
|
Как получить ценность
Сохраняя несколько пар ключ / значение в какой-то момент, вам потребуется извлечь эту информацию. Если вам нужно найти значение ключа, используйте функцию map-get()
. Мы собираемся передать ему два параметра: имя карты и затем ключ.
1
2
3
|
.element:before {
content: map-get($map, key);
}
|
После компиляции вывод будет следующим:
1
2
3
|
.element:before {
content: value;
}
|
Как проверить, доступен ли ключ
Настоятельно рекомендуется использовать надежную обработку ошибок в процессе разработки Sass. Для этого Sass дает нам функцию map-has-key()
. Этот помощник ищет, существует ли ключ, и, если нет, доставляет другой вывод, чтобы предупредить разработчика.
Взгляните на этот «Введение в обработку ошибок в Sass » Хьюго Жирауделя (Hugo Giraudel), чтобы узнать, как справляться с ошибками.
01
02
03
04
05
06
07
08
09
10
11
12
|
$map: (
key: value,
nextkey: nextvalue
);
.element {
@if map-has-key($map, key) {
content: ‘Map has this key.’;
} @else {
content: ‘Map has not this key.’;
}
}
|
Результат:
1
2
3
|
.element {
content: ‘Map has this key.’;
}
|
Как объединить карты вместе
Бонусное время: Sass позволяет нам объединять две или более карты вместе. Теперь вы уже знакомы с этим, так что взгляните на этот пример использования функции map-merge()
:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
$colors: (
light: #ccc,
dark: #000
);
$brand-colors: (
main: red,
alternative: blue
);
// Merge maps
$merged: map-merge($colors, $brand-colors);
.element {
content: map-get($merged, alternative);
}
|
Результат:
1
2
3
|
.element {
content: blue;
}
|
Реальные случаи использования
Мы рассмотрели как , теперь давайте посмотрим на где .
1. Как перебрать карту и создать классы
Карты также могут быть полезны без сопутствующих функций. Например, вы можете выполнить цикл по вашей карте, определить параметры со значениями, которые вы ожидаете, а затем добавить имя Sass Map. Делая это, можно работать с разными видами ценностей.
В этом примере я выводю классы для отображения значков. Я поставил имя значка в качестве ключа, оставив значение для хранения фактического content
(который мы затем добавили бы через псевдоэлементы).
Примечание . В реальном сценарии мы сначала объявляем некоторые базовые стили, но это выходит за рамки данного руководства.
01
02
03
04
05
06
07
08
09
10
11
12
13
|
/* Define the Sassy Map called $icons */
$icons: (
checkmark: a,
plus: b,
minus: c
);
/* For each key in the map, created an own class */
@each $name, $value in $icons {
.icon—#{$name} {
content: $value;
}
}
|
Вывод говорит сам за себя:
01
02
03
04
05
06
07
08
09
10
11
12
|
/* For each key in the map, created an own class */
.icon—checkmark {
content: «a»;
}
.icon—plus {
content: «b»;
}
.icon—minus {
content: «c»;
}
|
Это действительно эффективный способ вывода множества классов для иконок. Есть еще много вариантов использования — давайте посмотрим на некоторые.
2. Несколько значений для добавленной удивительности
Двигаясь дальше, можно дать ключу более одного значения. Это делается с помощью вырезок и ввода нескольких значений через запятую. Это, например, может быть полезно для переноса стилей для вариантов модуля.
Здесь я собираюсь стилизовать серию кнопок. Первое значение для каждого ключа — background-color
а второе — font-color
.
Затем я перебираю ключи с ожидаемым объектом $colors
. Я получаю значение первого ключа в этом объекте с помощью nth($colors, 1)
(начинаем с имени объекта, а затем положения искомого значения). Если вам нужно второе значение, введите 2
.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
// _m-buttons.scss
$buttons: (
error: (#d82d2d, #666),
success: (#52bf4a, #fff),
warning: (#c23435, #fff)
);
.m-button {
display: inline-block;
padding: .5em;
background: #ccc;
color: #666;
@each $name, $colors in $buttons {
$bgcolor: nth($colors, 1);
$fontcolor: nth($colors, 2);
&—#{$name} {
background-color: $bgcolor;
color: $fontcolor;
}
}
}
|
Выход:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
|
.m-button {
display: inline-block;
padding: .5em;
background: #ccc;
color: #666;
}
.m-button—error {
background-color: #d82d2d;
color: #666;
}
.m-button—success {
background-color: #52bf4a;
color: #fff;
}
.m-button—warning {
background-color: #c23435;
color: #fff;
}
|
3. Обработка слоев (z-index)
Я не знаю ни одного фронтенд-разработчика, который бы в какой-то момент не боролся с z-index . Проблемы обычно возникают из-за потери обзора, если вам нужно использовать z-index
в нескольких местах проекта. Sass карты могут помочь нам.
Давайте начнем с $layer
в качестве карты. Ключи должны быть логически названы, чтобы вы знали, какое значение для какого элемента — может быть offcanvas
, lightbox
, dropdown
offcanvas
и т. Д.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
|
// _config.scss
$layer: (
offcanvas: 1,
lightbox: 500,
dropdown: 10,
tooltip: 15
);
// _m-lightboxes.scss
@function layer($name) {
@if map-has-key($layer, $name) {
@return map-get($layer, $name);
}
@warn «The key #{$name} is not in the map ‘$layer'»;
@return null;
};
.m-lightbox {
z-index: layer(lightbox);
}
|
Здесь я написал функцию для получения значения определенного ключа, но почему я это сделал? Ответ к счастью прост: это быстрее, чем писать map-get()
каждый раз. Еще одним положительным моментом является то, что вы можете создать обработку ошибок и дать разработчику небольшую обратную связь о том, почему ничего не происходит.
Это вывод:
1
2
3
|
.m-lightbox {
z-index: 500;
}
|
4. Использование базовых стилей для шрифтов в проекте
Каждый проект имеет свой собственный файл конфигурации; основы для глобального использования. Например, в моих проектах я определяю некоторые значения для свойств шрифта: font-color, альтернативный font-color, font-family или font-size. Я использовал для создания переменной для каждого свойства, но карта будет лучше.
Вот быстрый пример, чтобы начать со старого решения:
1
2
3
4
|
$base-font-color: #666;
$base-font-family: Arial, Helvetica, Sans-Serif;
$base-font-size: 16px;
$base-line-height: 1.4;
|
Затем новое решение с использованием карты Sass:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
// _config.scss
$font: (
color: #666,
family: (Arial, Helvetica),
size: 16px,
line-height: 1.4
);
// _presets.scss
body {
color: map-get($font, color);
font-family: map-get($font, family);
font-size: map-get($font, size);
line-height: map-get($font, line-height);
}
|
5. Точки останова <3
Я люблю этот вариант использования. Прекрасно иметь область для точек останова, которые есть во всем вашем проекте. Итак, как и в разделе об обработке с помощью z-index, у вас есть обзор всех используемых точек останова. Если вы измените значение там, то вы измените поведение на протяжении всего проекта. Потрясающие.
Итак, давайте начнем с карты под названием $breakpoints
.
Наша цель — использовать точки останова с неявными именами вместо значений жестких пикселей в элементе. Из-за этого нам нужен миксин, который выведет значение указанного имени. Я назвал mixin response respond-to
и передать $breakpoint
в качестве параметра. С помощью $value
я получаю значение ожидаемой точки останова и помещаю ее позже в медиа-запрос.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
// Map with much breakpoints
$breakpoints: (
small: 320px,
medium: 600px,
large: 768px
);
// Respond-To Mixin
@mixin respond-to($breakpoint) {
@if map-has-key($breakpoints, $breakpoint) {
$value: map-get($breakpoints, $breakpoint);
@media screen and (min-width: $value) {
@content;
}
}
@warn «Unknown `#{$breakpoint}` in $breakpoints»;
}
|
Пример:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
// Sass
.m-tabs {
background-color: #f2f2f2;
@include respond-to(medium) {
background-color: #666;
}
}
// Output
.m-tabs {
background-color: #f2f2f2;
}
@media screen and (min-width: 600px) {
background-color: #666;
}
|
Этот вариант использования является одним из моих любимых!
6. Расширенное использование для цветов
Вещи становятся немного хитрее сейчас. Давайте посмотрим на вложенные карты — потрясающе для цветовых схем с диапазоном тонов.
Наша карта Sass в этом случае получает имя $colorscheme
и содержит объекты с ключами и значениями. У проекта разные серые тона, но мы не хотим объявлять переменную для каждого. Таким образом, мы добавляем gray
объект, добавляем вырезки, а затем ключи со значениями.
Начните с карты вот этой:
01
02
03
04
05
06
07
08
09
10
11
12
13
|
// Scheme of colors
$colorscheme: (
gray: (
base: #ccc,
light: #f2f2f2,
dark: #666
),
brown: (
base: #ab906b,
light: #ecdac3,
dark: #5e421c
)
);
|
Теперь давайте добавим функцию setcolor
для более короткого способа выбора цвета. Первым ожидаемым значением является объект карты Sass ( $scheme
) — в этом примере оно может быть gray
или brown
. Второй параметр — это цвет, который вы хотите ( $tone
) — значение по умолчанию для этого является ключевой base
.
1
2
3
4
|
// Our function for shorter usage of map-get();
@function setcolor($scheme, $tone: base) {
@return map-get(map-get($colorscheme, $scheme), $tone);
}
|
Наконец, вот пример того, как вы можете использовать его и как вы получаете разные цвета от вложенной карты. Это проще, чем вы думаете (возможно)!
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
// Sass
.element {
color: setcolor(brown);
}
.element—light {
color: setcolor(brown, light);
}
// Output
.element {
color: #ab906b;
}
.element—light {
color: #ecdac3;
}
|
Вы выполнили задание Теперь вы можете создать палитру, не разбрасывая код слишком большим количеством переменных для каждого типа цвета.
На эту технику меня вдохновил Том Дэвис, и я рекомендую вам ознакомиться с его статьей по этому вопросу.
Тематика с классами
Теперь кое-что для продвинутых пользователей Sass. В проектах часто требуется создавать различные виды тем с одной и той же кодовой базой. Итак, вот предложение установить класс темы в верхней части документа, чтобы применить определенный вид. Нам нужен объект, где мы можем обработать имя темы и установить различные стили для модуля.
Определите темы
Начните с карты Sass и определите темы глобально для вашего проекта. Значение — это имя и класс, который необходимо добавить к элементу <body>
. В этом примере я создал карту $themes
с двумя вариантами: theme-light
и theme-dark
.
1
2
3
4
5
|
// _config.scss
$themes: (
theme1: theme-light,
theme2: theme-dark
);
|
Получение ценности (Короткий путь)
Теперь нам нужна функция для быстрого получения значений модулей. Это краткий помощник и нуждается в трех параметрах. Эти:
-
$map
: определить имя карты, откуда берутся все значения. -
$object
: в этом случае ключ для темы. -
$style
: свойство для стиля, который необходим.
1
2
3
4
5
6
7
8
|
// _functions.scss
@function setStyle($map, $object, $style) {
@if map-has-key($map, $object) {
@return map-get(map-get($map, $object), $style);
}
@warn «The key ´#{$object} is not available in the map.»;
@return null;
}
|
Сборка модуля
Теперь создайте новую Sass Map с именем $config
. Каждая тема получает объект, и имя должно совпадать с ключом, который вы определили в $themes
: в противном случае вы получите ошибку.
01
02
03
04
05
06
07
08
09
10
11
12
|
// _m-buttons.scss
// 1.Config
$config: (
theme1: (
background: #f2f2f2,
color: #000
),
theme2: (
background: #666,
color: #fff
)
);
|
Цикл по темам
Наконец часть с небольшим количеством магии. Мы начинаем с такого модуля, как .m-button
а затем хотим создать новый вид в каждой теме. Поэтому мы используем @each
с $key
и $value
качестве ожидаемых значений, которые мы получаем из тем Map $themes
. Теперь Sass просматривает ключи на карте и создает что-то для каждой темы.
В начале этого раздела я упомянул, что необходимо, чтобы ключи были одинаковыми на каждой карте ( $themes
и $config
). Поэтому мы должны проверить, есть ли у карты $ config ключ от карты $themes
, поэтому используйте функцию map-has-key()
. Если ключ доступен, сделайте следующее, иначе выведите ошибку, чтобы сообщить разработчику.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
// _m-buttons.scss
// 2.Base
.m-button {
@each $key, $value in $themes {
@if map-has-key($config, $key) {
.#{$value} & {
background: setStyle($config, $key, background);
color: setStyle($config, $key, color);
}
} @else {
@warn «The key ´#{$key} isn’t defined in the map $config´»
}
}
}
|
После всего написанного кода, давайте посмотрим на результат. Превосходно, что область конфигурации отделена от логики модуля.
1
2
3
4
5
6
7
8
|
.theme-light .m-button {
background: #f2f2f2;
color: #000;
}
.theme-dark .m-button {
background: #666;
color: #fff;
}
|
Наконец пришло время попробовать это самостоятельно. Возможно, это решение не работает для вас, и вам нужно другое, но в целом я надеюсь, что оно поможет вам хорошо поддерживать ваш код. Вы можете поиграть с этим примером на Codepen:
Последние мысли
На мой взгляд, Sass Maps были лучшей функцией, представленной в Sass 3.3. Лично я считаю, что это отличный способ улучшить структуру вашего фонда и создать небольшие области конфигурации. Карты Sass упрощают обработку и изменение значений, не влияя на логику всей кодовой базы. Начните использовать их сегодня, ваши коллеги будут благодарны!
Если вы уже используете карты Sass, сообщите нам, как вы используете их в своих проектах!