As a CSS preprocessor, Sass is becoming more and more popular. Websites such as Github, Codepen, CSS-Tricks, SitePoint, w3cplus and other websites use Sass to organize and manage CSS files. Sass is becoming more and more popular. Gradually becoming the de facto CSS preprocessorindustry standard. In the next few articles, we will study the key functions in Sass. Today we will look at map. You may as well sit down and the exciting content will be presented immediately.
In Sass, maps represent a data type, which can contain an object type of several key-value pairs. Use () to surround a map , the key-value pairs inside are separated by commas. The key and value can be any Sass data type. Although a value can be used on multiple keys, we must only find one value through a key. Map cannot be used directly in CSS. If you assign a map to an element, an error will be reported. The following code example is a classic map.
$map: ( key1: value1, key2: value2, key3: value3);
We can use a series of functions to operate the map, and we can use the loop instruction to traverse the map.
Map-related functions include map-keys(), map-values(), map-get(), map-has-key(), map-merge(), map-remove(), keywords(), etc. , the function functions are shown in the following table.
map-keys(map) | 返回map里面所有的key(list) | map-keys(("foo": 1, "bar": 2)) => "foo", "bar" |
map-values(map) | 返回map里面所有的value(list) | map-values(("foo": 1, "bar": 2)) => 1, 2 |
map-get(map,key) | 返回map里面指定可以的value | map-get(("foo": 1, "bar": 2), "foo") => 1 |
map-has-key(map,key) | 返回map里面是否含有指定的key | map-has-key(("foo": 1, "bar": 2), "foo") => true |
map-merge(map1,map2) | 合并map(map) | map-merge(("foo": 1), ("bar": 2)) => ("foo": 1, "bar": 2) |
map-remove(map,keys) | 删除指定map中的指定key(map) | map-remove(("foo": 1, "bar": 2), "bar") => ("foo": 1) |
keywords(args) | 返回一个函数参数组成的map(map) | @mixin foo(args...) { at debug keywords($args); //=> (arg1: val, arg2: val)} |
我们可以使用@each指令遍历map,如下所示。
$map: ( key1: value1, key2: value2, key3: value3);/* 遍历map */@each $key, $value in $map { .element--#{$key} { background: $value; }}
map在Sass中应用广泛,有很多场合可以用到map,下面列举一二。
css里有很多属性可以指定多个值,例如transition、box-shadow等,这个时候我们可以使用map来定义不同的值,然后可以统一使用。例如
/* 使用map定义不同的值 */$card_transition_map: ( trans1: 200ms transform ease-in-out, trans2: 400ms background ease-in, trans3: 600ms color linear);/* map-values统一使用 */.card { transition: map-values($card_transition_map);}
编译之后输出
.card { transition: 200ms transform ease-in-out, 400ms background ease-in, 600ms color linear;}
我们可以使用zip函数来压缩多值,例如操作animate时:
$animation_config: ( name: none, duration: 0s, timing: ease, delay: 0s, iteration: 1, // infinite direction: normal, // reverse, alternate, alternate-reverse fill-mode: none, // forwards, backwards, both play-state: running);@function sh-setup($config) { @return zip(map-values($config)...);} .object { animation: sh-setup($animation_config);}
编译之后输出结果为
.object { animation: none 0s ease 0s 1 normal none running;}
我们可以使用一个循环来遍历不同的map,达到指定不同皮肤的功效。
$background_color: ( jeremy: #0989cb, beth: #8666ae, matt: #02bba7, ryan: #ff8178);$font: ( jeremy: Helvetica, beth: Verdana, matt: Times, ryan: Arial);@each $key, $value in $background_color { .#{$key} { background: $value; font-family: map-get($font, $key); }}
编译之后输出
.jeremy { background: #0989cb; font-family: Helvetica;}.beth { background: #8666ae; font-family: Verdana;}.matt { background: #02bba7; font-family: Times;}.ryan { background: #ff8178; font-family: Arial;}
使用Sass的一个最大的优点在于,我们可以对css文件进行统一的组织与管理,使用配置文件是达到目的的主要手段,例如我们把网页中所有层的z-index放配置文件里,在需要的地方进行调用。
/*定义配置文件*/$z-index: ( modal : 200, navigation : 100, footer : 90, triangle : 60, navigation-rainbow : 50, share-type : 41, share : 40,);/*在合适的时机调用*/.navigation { z-index: map-get($z-index, navigation);}
编译之后输出
.navigation { z-index: 100;}
上面案例调用的时候还用到map-get函数,还是比较麻烦,我们继续简化。
$z-index: ( modal : 200, navigation : 100, footer : 90, triangle : 60, navigation-rainbow : 50, share-type : 41, share : 40,);@function z-index($key) { @return map-get($z-index, $key);}@mixin z-index($key) { z-index: z-index($key);}/*调用时*/.navigation { @include z-index(navigation);}
下面代码演示如何在项目管理中如何进行断点管理。
// _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; }}
下面我们来看map在处理前缀mixin中的应用,两个参数类型分别为map和list,使用需要注意。
/*定义*//// Mixin to prefix several properties at once/// @author Hugo Giraudel/// @param {Map} $declarations - Declarations to prefix/// @param {List} $prefixes (()) - List of prefixes to print@mixin prefix($declarations, $prefixes: ()) { @each $property, $value in $declarations { @each $prefix in $prefixes { #{'-' + $prefix + '-' + $property}: $value; } // Output standard non-prefixed declaration #{$property}: $value; }}/*使用*/.selector { @include prefix(( column-count: 3, column-gap: 1.5em, column-rule: 2px solid hotpink ), webkit moz);}
编译之后输出为
.selector { -webkit-column-count: 3; -moz-column-count: 3; column-count: 3; -webkit-column-gap: 1.5em; -moz-column-gap: 1.5em; column-gap: 1.5em; -webkit-column-rule: 2px solid hotpink; -moz-column-rule: 2px solid hotpink; column-rule: 2px solid hotpink;}
Hugo Giraudel大牛定义的反向函数。
/*定义*//// Returns the opposite direction of each direction in a list/// @author Hugo Giraudel/// @param {List} $directions - List of initial directions/// @return {List} - List of opposite directions@function opposite-direction($directions) { $opposite-directions: (); $direction-map: ( 'top': 'bottom', 'right': 'left', 'bottom': 'top', 'left': 'right', 'center': 'center', 'ltr': 'rtl', 'rtl': 'ltr' ); @each $direction in $directions { $direction: to-lower-case($direction); @if map-has-key($direction-map, $direction) { $opposite-directions: append($opposite-directions, unquote(map-get($direction-map, $direction))); } @else { @warn "No opposite direction can be found for `#{$direction}`. Direction omitted."; } } @return $opposite-directions;}/*使用*/.selector { background-position: opposite-direction(top right);}
编译之后输出结果为
.selector { background-position: bottom left;}
本文的写作过程大量参考了以下文章,大家可以仔细阅读下面文章获得更深的体会。