转载

[原]Sass map详解

作为一个CSS预处理器, Sass 正受到越来越多的青睐,诸如Github、Codepen、CSS-Tricks、SitePoint、w3cplus等网站采用Sass组织、管理CSS文件,Sass正在逐渐成为事实上的CSS预处理器 行业标准 。接下来几篇文章,我们来研读下Sass中的关键功能,今天来看map,大家不妨一坐,精彩内容马上呈现。

map简介

在Sass中, maps 代表一种 数据类型 ,可以包含若干键值对的对象类型,使用()包围一个map,里面的键值对用逗号隔开,键和值可以是任何的Sass数据类型,尽管一个值可以用在多个键上,但是通过一个键我们必须只能找到一个值。map不能直接在css中使用,如果你把一个map赋值给一个元素将会报错。下面的代码示例一个经典的map。

$map: (   key1: value1,   key2: value2,   key3: value3 );

map使用

我们可以使用一系列的函数 操作**map,可以使用循环指令 遍历**map。

map相关的函数有map-keys()、map-values()、map-get()、map-has-key()、map-merge()、map-remove()、keywords()等,函数功能如下表所示。

函数 功能 示例
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…){@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案例

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; }

深入阅读

本文的写作过程大量参考了以下文章,大家可以仔细阅读下面文章获得更深的体会。

正文到此结束
Loading...