Sass map详解

WBOY
WBOYoriginal
2016-06-10 15:03:051154parcourir

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

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相关的函数有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案例

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>

深入阅读

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

  • 官方文档
  • mapfunction
  • Real Sass, Real Maps
  • Making Use of Sass’ Zip() Function
  • Sass Maps Are Awesome!
  • Using Sass Maps
  • Sass Mixins to Kickstart Your Project

声明

前端开发whqet,关注前端开发,分享相关资源。csdn专家博客,王海庆希望能对您有所帮助。
本文原文链接,http://whqet.github.io/2015/02/15/Sass%20map%E8%AF%A6%E8%A7%A3/*
欢迎大家访问CSDN博客,http://blog.csdn.net/whqet/ *

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Article précédent:Web缓存杂谈Article suivant:修改js confirm alert 提示框文字