作为一个CSS预处理器,Sass正受到越来越多的青睐,诸如Github、Codepen、CSS-Tricks、SitePoint、w3cplus等网站采用Sass组织、管理CSS文件,Sass正在逐渐成为事实上的CSS预处理器行业标准。接下来几篇文章,我们来研读下Sass中的关键功能,今天来看map,大家不妨一坐,精彩内容马上呈现。
在Sass中,maps代表一种数据类型,可以包含若干键值对的对象类型,使用()包围一个map,里面的键值对用逗号隔开,键和值可以是任何的Sass数据类型,尽管一个值可以用在多个键上,但是通过一个键我们必须只能找到一个值。map不能直接在css中使用,如果你把一个map赋值给一个元素将会报错。下面的代码示例一个经典的map。
<code class="hljs yaml">$map: ( <span class="hljs-attr"> key1:</span> value1, <span class="hljs-attr"> key2:</span> value2, <span class="hljs-attr"> key3:</span> value3 );</code>
我们可以使用一系列的函数操作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,如下所示。
<code class="hljs ruby">$map<span class="hljs-symbol">:</span> ( <span class="hljs-symbol">key1:</span> value1, <span class="hljs-symbol">key2:</span> value2, <span class="hljs-symbol">key3:</span> value3 ); <span class="hljs-regexp">/* 遍历map */</span> @each $key, $value <span class="hljs-keyword">in</span> $map { .element--<span class="hljs-comment">#{$key} {</span> <span class="hljs-symbol">background:</span> $value; } }</code>
map在Sass中应用广泛,有很多场合可以用到map,下面列举一二。
css里有很多属性可以指定多个值,例如transition、box-shadow等,这个时候我们可以使用map来定义不同的值,然后可以统一使用。例如
<code class="hljs dts"><span class="hljs-comment">/* 使用map定义不同的值 */</span> $card_transition_map: ( <span class="hljs-symbol"> trans1:</span> <span class="hljs-number">200</span>ms transform ease-in-out, <span class="hljs-symbol"> trans2:</span> <span class="hljs-number">400</span>ms background ease-in, <span class="hljs-symbol"> trans3:</span> <span class="hljs-number">600</span>ms color linear ); <span class="hljs-comment">/* map-values统一使用 */</span> .<span class="hljs-class">card </span>{ <span class="hljs-symbol"> transition:</span> map-values($card_transition_map); }</code>
编译之后输出
<code class="sourceCode css hljs"><span class="fl"><span class="hljs-selector-class">.card</span></span> <span class="kw">{</span> <span class="kw"><span class="hljs-attribute">transition</span>:</span> <span class="dt"><span class="hljs-number">200ms</span></span> transform ease-in-out, <span class="dt"><span class="hljs-number">400ms</span></span> <span class="dt">background</span> ease-in, <span class="dt"><span class="hljs-number">600ms</span></span> color linear<span class="kw">;</span> <span class="kw">}</span></code>
我们可以使用zip函数来压缩多值,例如操作animate时:
<code class="hljs perl">$animation_config: ( name: none, duration: 0s, timing: ease, delay: 0s, iteration: <span class="hljs-number">1</span>, <span class="hljs-regexp">//</span> infinite direction: normal, <span class="hljs-regexp">//</span> <span class="hljs-keyword">reverse</span>, alternate, alternate-<span class="hljs-keyword">reverse</span> fill-mode: none, <span class="hljs-regexp">//</span> forwards, backwards, both play-<span class="hljs-keyword">state</span>: running ); @function sh-setup($config) { @return zip(<span class="hljs-keyword">map</span>-<span class="hljs-keyword">values</span>($config)...); } .object { animation: sh-setup($animation_config); }</code>
编译之后输出结果为
<code class="hljs css"><span class="hljs-selector-class">.object</span> { <span class="hljs-attribute">animation</span>: none <span class="hljs-number">0s</span> ease <span class="hljs-number">0s</span> <span class="hljs-number">1</span> normal none running; }</code>
我们可以使用一个循环来遍历不同的map,达到指定不同皮肤的功效。
<code class="hljs yaml">$background_color: ( <span class="hljs-attr"> jeremy:</span> <span class="hljs-comment">#0989cb,</span> <span class="hljs-attr"> beth:</span> <span class="hljs-comment">#8666ae,</span> <span class="hljs-attr"> matt:</span> <span class="hljs-comment">#02bba7,</span> <span class="hljs-attr"> ryan:</span> <span class="hljs-comment">#ff8178</span> ); $font: ( <span class="hljs-attr"> jeremy:</span> Helvetica, <span class="hljs-attr"> beth:</span> Verdana, <span class="hljs-attr"> matt:</span> Times, <span class="hljs-attr"> ryan:</span> Arial ); @each $key, $value in $background_color { .<span class="hljs-comment">#{$key} {</span> <span class="hljs-attr"> background:</span> $value; <span class="hljs-attr"> font-family:</span> map-get($font, $key); } }</code>
编译之后输出
<code class="sourceCode css hljs"><span class="fl"><span class="hljs-selector-class">.jeremy</span></span> <span class="kw">{</span> <span class="kw"><span class="hljs-attribute">background</span>:</span> <span class="dt"><span class="hljs-number">#0989cb</span></span><span class="kw">;</span> <span class="kw"><span class="hljs-attribute">font-family</span>:</span> Helvetica<span class="kw">;</span> <span class="kw">}</span> <span class="fl"><span class="hljs-selector-class">.beth</span></span> <span class="kw">{</span> <span class="kw"><span class="hljs-attribute">background</span>:</span> <span class="dt"><span class="hljs-number">#8666ae</span></span><span class="kw">;</span> <span class="kw"><span class="hljs-attribute">font-family</span>:</span> Verdana<span class="kw">;</span> <span class="kw">}</span> <span class="fl"><span class="hljs-selector-class">.matt</span></span> <span class="kw">{</span> <span class="kw"><span class="hljs-attribute">background</span>:</span> <span class="dt"><span class="hljs-number">#02bba7</span></span><span class="kw">;</span> <span class="kw"><span class="hljs-attribute">font-family</span>:</span> Times<span class="kw">;</span> <span class="kw">}</span> <span class="fl"><span class="hljs-selector-class">.ryan</span></span> <span class="kw">{</span> <span class="kw"><span class="hljs-attribute">background</span>:</span> <span class="dt"><span class="hljs-number">#ff8178</span></span><span class="kw">;</span> <span class="kw"><span class="hljs-attribute">font-family</span>:</span> Arial<span class="kw">;</span> <span class="kw">}</span></code>
使用Sass的一个最大的优点在于,我们可以对css文件进行统一的组织与管理,使用配置文件是达到目的的主要手段,例如我们把网页中所有层的z-index放配置文件里,在需要的地方进行调用。
<code class="hljs groovy"><span class="hljs-comment">/*定义配置文件*/</span> $z-<span class="hljs-string">index:</span> ( <span class="hljs-string">modal :</span> <span class="hljs-number">200</span>, <span class="hljs-string">navigation :</span> <span class="hljs-number">100</span>, <span class="hljs-string">footer :</span> <span class="hljs-number">90</span>, <span class="hljs-string">triangle :</span> <span class="hljs-number">60</span>, navigation-<span class="hljs-string">rainbow :</span> <span class="hljs-number">50</span>, share-<span class="hljs-string">type :</span> <span class="hljs-number">41</span>, <span class="hljs-string">share :</span> <span class="hljs-number">40</span>, ); <span class="hljs-comment">/*在合适的时机调用*/</span> .navigation { z-<span class="hljs-string">index:</span> map-get($z-index, navigation); }</code>
编译之后输出
<code class="hljs css"><span class="hljs-selector-class">.navigation</span> { <span class="hljs-attribute">z-index</span>: <span class="hljs-number">100</span>; }</code>
上面案例调用的时候还用到map-get函数,还是比较麻烦,我们继续简化。
<code class="hljs perl">$z-<span class="hljs-keyword">index</span>: ( modal : <span class="hljs-number">200</span>, navigation : <span class="hljs-number">100</span>, footer : <span class="hljs-number">90</span>, triangle : <span class="hljs-number">60</span>, navigation-rainbow : <span class="hljs-number">50</span>, share-type : <span class="hljs-number">41</span>, share : <span class="hljs-number">40</span>, ); @function z-<span class="hljs-keyword">index</span>($key) { @return <span class="hljs-keyword">map</span>-get($z-<span class="hljs-keyword">index</span>, $key); } @mixin z-<span class="hljs-keyword">index</span>($key) { z-<span class="hljs-keyword">index</span>: z-<span class="hljs-keyword">index</span>($key); } /*调用时*<span class="hljs-regexp">/ .navigation { @include z-index(navigation); }</span></code>
下面代码演示如何在项目管理中如何进行断点管理。
<code class="hljs perl">// _config.scss $breakpoints: ( small: <span class="hljs-number">767</span>px, medium: <span class="hljs-number">992</span>px, large: <span class="hljs-number">1200</span>px ); <span class="hljs-regexp">//</span> _mixins.scss @mixin respond-to($breakpoint) { @if <span class="hljs-keyword">map</span>-has-key($breakpoints, $breakpoint) { @media (min-width: <span class="hljs-comment">#{map-get($breakpoints, $breakpoint)}) {</span> @content; } } @else { @warn <span class="hljs-string">"Unfortunately, no value could be retrieved from `#{$breakpoint}`. "</span> + <span class="hljs-string">"Please make sure it is defined in `$breakpoints` map."</span>; } } // _component.scss .element { color: hotpink; @include respond-to(small) { color: tomato; } }</code>
编译之后输出结果为
<code class="hljs css"><span class="hljs-selector-class">.element</span> { <span class="hljs-attribute">color</span>: hotpink; } @<span class="hljs-keyword">media</span> (min-width: <span class="hljs-number">767px</span>) { <span class="hljs-selector-class">.element</span> { <span class="hljs-attribute">color</span>: tomato; } }</code>
下面我们来看map在处理前缀mixin中的应用,两个参数类型分别为map和list,使用需要注意。
<code class="hljs php"><span class="hljs-comment">/*定义*/</span> <span class="hljs-comment">/// Mixin to prefix several properties at once</span> <span class="hljs-comment">/// @author Hugo Giraudel</span> <span class="hljs-comment">/// @param {Map} $declarations - Declarations to prefix</span> <span class="hljs-comment">/// @param {List} $prefixes (()) - List of prefixes to print</span> @mixin prefix($declarations, $prefixes: ()) { @each $property, $value in $declarations { @each $prefix in $prefixes { <span class="hljs-comment">#{'-' + $prefix + '-' + $property}: $value;</span> } <span class="hljs-comment">// Output standard non-prefixed declaration</span> <span class="hljs-comment">#{$property}: $value;</span> } } <span class="hljs-comment">/*使用*/</span> .selector { @<span class="hljs-keyword">include</span> prefix(( column-count: <span class="hljs-number">3</span>, column-gap: <span class="hljs-number">1.5</span>em, column-rule: <span class="hljs-number">2</span>px solid hotpink ), webkit moz); }</code>
编译之后输出为
<code class="hljs css"><span class="hljs-selector-class">.selector</span> { <span class="hljs-attribute">-webkit-column-count</span>: <span class="hljs-number">3</span>; <span class="hljs-attribute">-moz-column-count</span>: <span class="hljs-number">3</span>; <span class="hljs-attribute">column-count</span>: <span class="hljs-number">3</span>; <span class="hljs-attribute">-webkit-column-gap</span>: <span class="hljs-number">1.5em</span>; <span class="hljs-attribute">-moz-column-gap</span>: <span class="hljs-number">1.5em</span>; <span class="hljs-attribute">column-gap</span>: <span class="hljs-number">1.5em</span>; <span class="hljs-attribute">-webkit-column-rule</span>: <span class="hljs-number">2px</span> solid hotpink; <span class="hljs-attribute">-moz-column-rule</span>: <span class="hljs-number">2px</span> solid hotpink; <span class="hljs-attribute">column-rule</span>: <span class="hljs-number">2px</span> solid hotpink; }</code>
Hugo Giraudel大牛定义的反向函数。
<code class="hljs php"><span class="hljs-comment">/*定义*/</span> <span class="hljs-comment">/// Returns the opposite direction of each direction in a list</span> <span class="hljs-comment">/// @author Hugo Giraudel</span> <span class="hljs-comment">/// @param {List} $directions - List of initial directions</span> <span class="hljs-comment">/// @return {List} - List of opposite directions</span> @<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">opposite</span>-<span class="hljs-title">direction</span><span class="hljs-params">($directions)</span> </span>{ $opposite-directions: (); $direction-map: ( <span class="hljs-string">'top'</span>: <span class="hljs-string">'bottom'</span>, <span class="hljs-string">'right'</span>: <span class="hljs-string">'left'</span>, <span class="hljs-string">'bottom'</span>: <span class="hljs-string">'top'</span>, <span class="hljs-string">'left'</span>: <span class="hljs-string">'right'</span>, <span class="hljs-string">'center'</span>: <span class="hljs-string">'center'</span>, <span class="hljs-string">'ltr'</span>: <span class="hljs-string">'rtl'</span>, <span class="hljs-string">'rtl'</span>: <span class="hljs-string">'ltr'</span> ); @each $direction in $directions { $direction: to-lower-<span class="hljs-keyword">case</span>($direction); @<span class="hljs-keyword">if</span> map-has-key($direction-map, $direction) { $opposite-directions: append($opposite-directions, unquote(map-get($direction-map, $direction))); } @<span class="hljs-keyword">else</span> { @warn <span class="hljs-string">"No opposite direction can be found for `#{$direction}`. Direction omitted."</span>; } } @<span class="hljs-keyword">return</span> $opposite-directions; } <span class="hljs-comment">/*使用*/</span> .selector { background-position: opposite-direction(top right); }</code>
编译之后输出结果为
<code class="hljs css"><span class="hljs-selector-class">.selector</span> { <span class="hljs-attribute">background-position</span>: bottom left; }</code>
本文的写作过程大量参考了以下文章,大家可以仔细阅读下面文章获得更深的体会。
前端开发whqet,关注前端开发,分享相关资源。csdn专家博客,王海庆希望能对您有所帮助。
本文原文链接,http://whqet.github.io/2015/02/15/Sass%20map%E8%AF%A6%E8%A7%A3/*
欢迎大家访问CSDN博客,http://blog.csdn.net/whqet/ *