列表函数主要包括一些对列表参数的函数使用,主要包括以下几种:
- length($list):返回一个列表的长度值;
- nth($list, $n):返回一个列表中指定的某个标签值
- join($list1, $list2, [$separator]):将两个列给连接在一起,变成一个列表;
- append($list1, $val, [$separator]):将某个值放在列表的最后;
- zip($lists…):将几个列表结合成一个多维的列表;
- index($list, $value):返回一个值在列表中的位置值。
列表函数中的每个函数都有其独特的作用与功能,接下来我们通过命令终端向大家展示每个列表函数的功能与使用。
length()函数
length() 函数主要用来返回一个列表中有几个值,简单点说就是返回列表清单中有多少个值:
>> length(10px) 1 >> length(10px 20px (border 1px solid) 2em) 4 >> length(border 1px solid) 3
length() 函数中的列表参数之间使用空格隔开,不能使用逗号,否则函数将会出错:
>> length(10px,20px,(border 1px solid),2em) SyntaxError: wrong number of arguments (4 for 1) for `length' >> length(1,2px) SyntaxError: wrong number of arguments (2 for 1) for `length'
nth()函数
语法:
nth($list,$n)
nth() 函数用来指定列表中某个位置的值。不过在 Sass 中,nth() 函数和其他语言不同,1 是指列表中的第一个标签值,2 是指列给中的第二个标签值,依此类推。如:
>> nth(10px 20px 30px,1) 10px >> nth((Helvetica,Arial,sans-serif),2) "Arial" >> nth((1px solid red) border-top green,1) (1px "solid" #ff0000)
注:在 nth($list,$n) 函数中的 $n 必须是大于 0 的整数:
>> nth((1px solid red) border-top green 1 ,0) SyntaxError: List index 0 must be a non-zero integer for `nth'
join()函数
join() 函数是将两个列表连接合并成一个列表。
>> join(10px 20px, 30px 40px) (10px 20px 30px 40px) >> join((blue,red),(#abc,#def)) (#0000ff, #ff0000, #aabbcc, #ddeeff) >> join((blue,red),(#abc #def)) (#0000ff, #ff0000, #aabbcc, #ddeeff)
不过 join() 只能将两个列表连接成一个列表,如果直接连接两个以上的列表将会报错:
>> join((blue red),(#abc, #def),(#dee #eff)) SyntaxError: $separator: (#ddeeee #eeffff) is not a string for `join'
但很多时候不只碰到两个列表连接成一个列表,这个时候就需要将多个 join() 函数合并在一起使用:
>> join((blue red), join((#abc #def),(#dee #eff))) (#0000ff #ff0000 #aabbcc #ddeeff #ddeeee #eeffff)
在 join() 函数中还有一个很特别的参数 $separator,这个参数主要是用来给列表函数连接列表值是,使用的分隔符号,默认值为 auto。
join() 函数中 $separator 除了默认值 auto 之外,还有 comma 和 space 两个值,其中 comma 值指定列表中的列表项值之间使用逗号(,)分隔,space 值指定列表中的列表项值之间使用空格( )分隔。
在 join() 函数中除非明确指定了 $separator值,否则将会有多种情形发生:
如果列表中的第一个列表中每个值之间使用的是逗号(,),那么 join() 函数合并的列表中每个列表项之间使用逗号,分隔:
>> join((blue, red, #eff),(green orange)) (#0000ff, #ff0000, #eeffff, #008000, #ffa500)
但当第一个列表中只有一个列表项,那么 join() 函数合并的列表项目中每个列表项目这间使用的分隔符号会根据第二个列表项中使用的,如果第二列表项中使用是,分隔,则使用逗号分隔;如果第二列项之间使用的空格符,则使用空格分隔:
>> join(blue,(green, orange)) (#0000ff, #008000, #ffa500) >> join(blue,(green orange)) (#0000ff #008000 #ffa500)
如果列表中的第一个列表中每个值之间使用的是空格,那么 join() 函数合并的列表中每个列表项之间使用空格分隔:
>> join((blue green),(red,orange)) (#0000ff #008000 #ff0000 #ffa500) >> join((blue green),(red orange)) (#0000ff #008000 #ff0000 #ffa500)
如果当两个列表中的列表项小于1时,将会以空格分隔:
>> join(blue,red) (#0000ff #ff0000)
如此一来,会有多种情形发生,造成使用混乱的情形,如果你无法记得,什么时候会是用逗号分隔合并的列表项,什么时候是使用空格分隔合并 的列表项,在些建议大家使用 join() 函数合并列表项的时候就明确指定 $separator 参数,用来指定合并的列表中使用什么方式来分隔列表项:
>> join(blue,red,comma) (#0000ff, #ff0000) >> join(blue,red,space) (#0000ff #ff0000) >> join((blue green),(red,orange),comma) (#0000ff, #008000, #ff0000, #ffa500) >> join((blue green),(red,orange),space) (#0000ff #008000 #ff0000 #ffa500) >> join((blue, green),(red,orange),comma) (#0000ff, #008000, #ff0000, #ffa500) >> join((blue, green),(red,orange),space) (#0000ff #008000 #ff0000 #ffa500) >> join(blue,(red,orange),comma) (#0000ff, #ff0000, #ffa500) >> join(blue,(red,orange),space) (#0000ff #ff0000 #ffa500) >> join(blue,(red orange),comma) (#0000ff, #ff0000, #ffa500) >> join(blue,(red orange),space) (#0000ff #ff0000 #ffa500)
append()函数
append() 函数是用来将某个值插入到列表中,并且处于最末位。
>> append(10px 20px ,30px) (10px 20px 30px) >> append((10px,20px),30px) (10px, 20px, 30px) >> append(green,red) (#008000 #ff0000) >> append(red,(green,blue)) (#ff0000 (#008000, #0000ff))
如果没有明确的指定 $separator 参数值,其默认值是 auto。
- 如果列表只有一个列表项时,那么插入进来的值将和原来的值会以空格的方式分隔。
- 如果列表中列表项是以空格分隔列表项,那么插入进来的列表项也将以空格分隔;
- 如果列表中列表项是以逗号分隔列表项,那么插入进来的列表项也将以逗号分隔。
当然,在 append() 函数中,可以显示的设置 $separator 参数,
- 如果取值为 comma 将会以逗号分隔列表项
- 如果取值为 space 将会以空格分隔列表项
>> append((blue green),red,comma) (#0000ff, #008000, #ff0000) >> append((blue green),red,space) (#0000ff #008000 #ff0000) >> append((blue, green),red,comma) (#0000ff, #008000, #ff0000) >> append((blue, green),red,space) (#0000ff #008000 #ff0000) >> append(blue,red,comma) (#0000ff, #ff0000) >> append(blue,red,space) (#0000ff #ff0000)
zip()函数
zip()函数将多个列表值转成一个多维的列表:
>> zip(1px 2px 3px,solid dashed dotted,green blue red) ((1px "solid" #008000), (2px "dashed" #0000ff), (3px "dotted" #ff0000))
在使用zip()函数时,每个单一的列表个数值必须是相同的:
>> zip(1px 2px 3px, solid , green blue red) NoMethodError: undefined method `options=' for nil:NilClass Use --trace for backtrace.
否则将会出错。
zip()函数中每个单一列表的值对应的取其相同位置值:
|--- List ---|--- nth(1) ---|--- nth(2) ---|--- nth(3) ---|
|------------|--------------|--------------|--------------|
| List1 | 1px | 2px | 3px |
|------------|--------------|--------------|--------------|
| List2 | solid | dashed | dotted |
|------------|--------------|--------------|--------------|
| List3 | green | blue | red |
|------------|--------------|--------------|--------------|
zip()函数组合出来就成了:
1px solid green, 2px dashed blue, 3px dotted red
index()函数
index() 函数类似于索引一样,主要让你找到某个值在列表中所处的位置。在 Sass 中,第一个值就是1,第二个值就是 2,依此类推:
>> index(1px solid red, 1px) 1 >> index(1px solid red, solid) 2 >> index(1px solid red, red) 3
在 index() 函数中,如果指定的值不在列表中(没有找到相应的值),那么返回的值将是 false,相反就会返回对应的值在列表中所处的位置。
>> index(1px solid red,dotted) //列表中没有找到 dotted false >> index(1px solid red,solid) //列表中找到 solid 值,并且返回他的位置值 2 2
Introspection函数
Introspection 函数包括了几个判断型函数:
- type-of($value):返回一个值的类型
- unit($number):返回一个值的单位
- unitless($number):判断一个值是否带有单位
- comparable($number-1, $number-2):判断两个值是否可以做加、减和合并
这几个函数主要用来对值做一个判断的作用,我们来依次看每个函数的功能。
Introspection 函数 -type-of()
type-of() 函数主要用来判断一个值是属于什么类型:
返回值:
- number 为数值型。
- string 为字符串型。
- bool 为布尔型。
- color 为颜色型。
>> type-of(100) "number" >> type-of(100px) "number" >> type-of("asdf") "string" >> type-of(asdf) "string" >> type-of(true) "bool" >> type-of(false) "bool" >> type-of(#fff) "color" >> type-of(blue) "color" >> type-of(1 / 2 = 1) "string"
unit()函数
unit() 函数主要是用来获取一个值所使用的单位,碰到复杂的计算时,其能根据运算得到一个“多单位组合”的值,不过只充许乘、除运算:
>> unit(100) "" >> unit(100px) "px" >> unit(20%) "%" >> unit(1em) "em" >> unit(10px * 3em) "em*px" >> unit(10px / 3em) "px/em" >> unit(10px * 2em / 3cm / 1rem) "em/rem"
但加、减碰到不同单位时,unit() 函数将会报错,除 px 与 cm、mm 运算之外:
>> unit(1px + 1cm) "px" >> unit(1px - 1cm) "px" >> unit(1px + 1mm) "px" >> unit(10px * 2em - 3cm / 1rem) SyntaxError: Incompatible units: 'cm' and 'px*em'. >> unit(10px * 2em - 1px / 1rem) SyntaxError: Incompatible units: '' and 'em'. >> unit(1px - 1em) SyntaxError: Incompatible units: 'em' and 'px'. >> unit(1px - 1rem) SyntaxError: Incompatible units: 'rem' and 'px'. >> unit(1px - 1%) SyntaxError: Incompatible units: '%' and 'px'. >> unit(1cm + 1em) SyntaxError: Incompatible units: 'em' and 'cm'.
unit() 函数对于单位运算相对来说也没有规律,而且有些单位也无法整合成一个单位,对于我们在 CSS 中运用中并不适合,比如:
>> unit(10px * 3em) "em*px" >> unit(10px / 3em) "px/em" >> unit(10px * 2em / 3cm / 1rem) "em/rem"
换句话说,上面运算出来的单位,对于在 CSS 中使用将是没有任何意义的。
unitless()函数
unitless() 函数相对来说简单明了些,只是用来判断一个值是否带有单位,如果不带单位返回的值为 true,带单位返回的值为 false:
>> unitless(100) true >> unitless(100px) false >> unitless(100em) false >> unitless(100%) false >> unitless(1 /2 ) true >> unitless(1 /2 + 2 ) true >> unitless(1px /2 + 2 ) false
具体例子,见右侧代码编辑器。右侧代码实现:用户在调用混合宏时,如果用户没有给参数值加上单位,程序会自动加入单位。
comparable()函数
comparable() 函数主要是用来判断两个数是否可以进行“加,减”以及“合并”。如果可以返回的值为 true,如果不可以返回的值是 false:
>>
comparable(2px,1px)
true >> comparable(2px,1%) false >> comparable(2px,1em) false >> comparable(2rem,1em) false >> comparable(2px,1cm) true >> comparable(2px,1mm) true >>
comparable(2px,1rem)
false >> comparable(2cm,1mm) true
Miscellaneous函数
在这里把 Miscellaneous 函数称为三元条件函数,主要因为他和 JavaScript 中的三元判断非常的相似。他有两个值,当条件成立返回一种值,当条件不成立时返回另一种值:
if($condition,$if-true,$if-false)
上面表达式的意思是当 $condition 条件成立时,返回的值为 $if-true,否则返回的是 $if-false 值。
>> if(true,1px,2px) 1px >> if(false,1px,2px) 2px
Map
Sass 的 map 常常被称为数据地图,也有人称其为数组,因为他总是以 key:value 成对的出现,但其更像是一个 JSON 数据。
{ "employees": [ { "firstName":"John" , "lastName":"Doe" }, { "firstName":"Anna" , "lastName":"Smith" }, { "firstName":"Peter" , "lastName":"Jones" } ] }
那么 Sass 的 map 长得与 JSON 极其相似:
$map: ( $key1: value1, $key2: value2, $key3: value3 )
首先有一个类似于 Sass 的变量一样,用个 $ 加上命名空间来声明 map。后面紧接是一个小括号 (),将数据以 key:value 的形式赋予,其中 key 和 value 是成对出现,并且每对之间使用逗号 (,) 分隔,其中最后一组后面没有逗号。
其中键 key 是用来查找相关联的值 value。使用 map 可以很容易收集键的值和动态插入。我们来回忆一下,在 Sass 中常用下面的方式定义变量:
$default-color: #fff !default; $primary-color: #22ae39 !default;
我们使用 map 可以更好的进行管理:
$color: ( default: #fff, primary: #22ae39 );
如果哪一天,你需要新增加颜色变量值,在 map 中可以非常随意的添加:
$color: ( default: #fff, primary: #22ae39, negative: #d9534f );
对于 Sass 的 map,还可以让 map 嵌套 map。其实就是 map 的某一个 key 当成 map,里面可以继续放一对或者多对 key:value:
$map: ( key1: value1, key2: ( key-1: value-1, key-2: value-2, ), key3: value3 );
map 的嵌套实用性也非常的强,大家可能有碰到过换皮肤的项目,可能每一套皮肤对应的颜色蛮多的,那么使用此功能来管理颜色的变量就非常的有条理性,便于维护与管理。你可以这样使用:
$theme-color: ( default: ( bgcolor: #fff, text-color: #444, link-color: #39f ), primary:( bgcolor: #000, text-color:#fff, link-color: #93f ), negative: ( bgcolor: #f36, text-color: #fefefe, link-color: #d4e ) );
在一些介绍 map 的老教程中,你会看到这样的方式声明 map:
$map: ( key1 value1, key2 value2, key3 value3 );
或者:
$map:( key1 value1, key2 value2, key3 ( key-1 value-1, key-2 value-2 ), key4 value4 );
虽然也能编译出 CSS,但建议不这样使用。
Sass Maps的函数
前面介绍了使用 map 来管理变量,但要在 Sass 中获取变量,或者对 map 做更多有意义的操作,我们必须借助于 map 的函数功能。在 Sass 中 map 自身带了七个函数:
- map-get($map,$key):根据给定的 key 值,返回 map 中相关的值。
- map-merge($map1,$map2):将两个 map 合并成一个新的 map。
- map-remove($map,$key):从 map 中删除一个 key,返回一个新 map。
- map-keys($map):返回 map 中所有的 key。
- map-values($map):返回 map 中所有的 value。
- map-has-key($map,$key):根据给定的 key 值判断 map 是否有对应的 value 值,如果有返回 true,否则返回 false。
- keywords($args):返回一个函数的参数,这个参数可以动态的设置 key 和 value。
Sass Maps的函数-map-get($map,$key)
map-get($map,$key) 函数的作用是根据 $key 参数,返回 $key 在 $map 中对应的 value 值。如果 $key 不存在 $map中,将返回 null 值。此函数包括两个参数:
- $map:定义好的 map。
- $key:需要遍历的 key。
来看一个简单的示例,假设定义了一个 $social-colors 的 map:
$social-colors: ( dribble: #ea4c89, facebook: #3b5998, github: #171515, google: #db4437, twitter: #55acee );
假设要获取 facebook 键值对应的值 #3b5998,我们就可以使用 map-get() 函数来实现:
.btn-dribble{ color: map-get($social-colors,facebook); }
编译出来的CSS:
.btn-dribble { color: #3b5998; }
我们来看另一种情况,假设 $social-colors 这个 map 没有 $weibo 这个 key:
.btn-weibo{ font-size: 12px; color: map-get($social-colors,weibo); }
此时编译出来的是CSS:
.btn-weibo { font-size: 12px; }
从 编译出来的 CSS 可以得知,如果 $key 不在 $map 中,不会编译出 CSS,其实在 Sass 中,map-get($social- colors,weibo) 返回了一个 null 值。但在编译出来的 CSS 中,你只知道他没有编译出样式,而且在命令终端编译时,也没有任何错误或者警告信息。说实话,你并不知道他为什么编译不出来样式,或者说他已返回了值为 null。体验不强,也不好排错。其实如果我们自定义一个函数,另外加个判断,那就截然不同。
Sass Maps的函数-map-has-key($map,$key)
map-has-key($map,$key) 函数将返回一个布尔值。当 $map 中有这个 $key,则函数返回 true,否则返回 false。
前面的示例,当 $key 不在 $map 中时,使用 map-get($map,$key) 函数将返回一个 null 值。但对于开发人员,并看不到任何提示信息。如果使用 map-has-key($map,$key) 函数就可以改变这一状态。我们来看一个简单的示例。
@if map-has-key($social-colors,facebook){ .btn-facebook { color: map-get($social-colors,facebook); } } @else { @warn "No color found for faceboo in $social-colors map. Property ommitted." }
编译出来:
.btn-fackbook{ color: #3b5998; }
上面看到的示例是 facebook 这个 key 已存在 $social-colors 这个 map 当中。所以能正常编译。如果你手误,将 facebook 输错了:
@if map-has-key($social-colors,faceboo){ .btn-facebook { color: map-get($social-colors,facebook); } } @else { @warn "No color found for faceboo in $social-colors map. Property ommitted." }
这个时候,你编译出来的 CSS 代码中,不会有新代码添加,但在命令终端可以看到提示信息:
WARNING: No color found for faceboo in $social-colors map. Property ommitted. on line 25 of test.scss
是不是非常的友好。但总觉得这样写是傻傻的,总不可能每获取一个 key 都写一个 @if 语句吧。其实不用这么复杂,我们可以自定义一个函数,比如 colors():
@function colors($color){ @if not map-has-key($social-colors,$color){ @warn "No color found for `#{$color}` in $social-colors map. Property omitted."; } @return map-get($social-colors,$color); }
有了这个函数之后,我们就可以这样使用
.btn-dribble { color: colors(dribble); } .btn-facebook { color: colors(facebook); } .btn-github { color: colors(github); } .btn-google { color: colors(google); } .btn-twitter { color: colors(twitter); } .btn-weibo { color: colors(weibo); }
编译出来的 CSS:
.btn-dribble { color: #ea4c89; } .btn-facebook { color: #3b5998; } .btn-github { color: #171515; } .btn-google { color: #db4437; } .btn-twitter { color: #55acee; }
同时你不难发现,命令终端提示信息:
WARNING: No color found for `weibo` in $social-colors map. Property omitted. on line 13 of test.scss
那是在 $social-colors 这个 map 中没有 weibo 这个 key。是不是很有意思。
当然,如果你对 Sass 的指令熟悉的话,上面编译出来的 CSS 可以使用 @each:
@each $social-network,$social-color in $social-colors { .btn-#{$social-network} { color: colors($social-network); } }
Sass Maps的函数-map-keys($map)
map-keys($map) 函数将会返回 $map 中的所有 key。这些值赋予给一个变量,那他就是一个列表。如:
map-keys($social-colors);
其返回的值为:
"dribble","facebook","github","google","twitter"
换句话说:
$list: map-keys($social-colors);
相当于:
$list:"dribble","facebook","github","google","twitter";
这个时候,就可以配合 Sass 的 list 做很多事情。
上面的示例,可以做通过 map-keys($map) 来做一个修改:
@function colors($color){ $names: map-keys($social-colors); @if not index($names,$color){ @warn "Waring: `#{$color} is not a valid color name.`"; } @return map-get($social-colors,$color); }
上面代码中最不同之处,我们使 用map-key s将 $social-colors 这个 map 的所有 key 取出,并赋予给一个名 为 $names 的列表。然后通过 index($names,$color) 返回 $color 在 $names 位置,如果这个位置不存在,将返回提示信息,如果存在将返回正确的值。
.btn-weibo{ color: colors(weibo); }
例如,weibo 不在 $social-color s中,那么不会编译出 CSS,而且在命令终端同样会有提示信息:
WARNING: Waring: `weibo is not a valid color name.` on line 27 of test.scss
同样,也可以通过 @each 或者 @for 遍历出所有值:
@each:
@each $name in map-keys($social-colors){ .btn-#{$name}{ color: colors($name); } }
@for:
@for $i from 1 through length(map-keys($social-colors)){ .btn-#{nth(map-keys($social-colors),$i)} { color: colors(nth(map-keys($social-colors),$i)); } }
虽然使用的方法不一样,但最终得到的 CSS 是一样的:
.btn-dribble { color: #ea4c89; } .btn-facebook { color: #3b5998; } .btn-github { color: #171515; } .btn-google { color: #db4437; } .btn-twitter { color: #55acee; }
Sass Maps的函数-map-values($map)、map-merge($map1,$map2)
map-values($map)
map-values($map) 函数类似于 map-keys($map) 功能,不同的是 map-values($map )获取的是 $map 的所有 value 值,可以说也将是一个列表。而且,map-values($map) 中如果有相同的 value 也将会全部获取出来。
如前面的示例,使用:
map-values($social-colors)
将会返回:
#ea4c89,#3b5998,#171515,#db4437,#55acee
值与值之前同样用逗号分隔。
map-merge($map1,$map2)
map-merge($map1,$map2)
map-merge($map1,$map2) 函数是将 $map1 和 $map2 合并,然后得到一个新的 $map。如果你要快速将新的值插入到 $map 中的话,这种方法是最佳方法。假设我们有两个 $map:
$color: ( text: #f36, link: #f63, border: #ddd, backround: #fff ); $typo:( font-size: 12px, line-height: 1.6 );
如果希望将这两个 $map 合并成一个 map,我们只要这样做:
$newmap: map-merge($color,$typo);
将会生成一个新的 map:
$newmap:( text: #f36, link: #f63, border: #ddd, background: #fff, font-size: 12px, line-height: 1.6 );
这样你就可以借助 map-get( ) 等函数做其他事情了。
不过有一点需要注意,如果 $map1 和 $map2 中有相同的 $key 名,那么将 $map2 中的 $key 会取代 $map1 中的:
$color: ( text: #f36, link: #f63, border: #ddd, backround: #fff ); $typo:( font-size: 12px, line-height: 1.6, border: #ccc, background: #000 );
执行:
$newmap: map-merge($color,$typo);
得到的新 map:
$newmap:( text: #f36, link: #f63, font-size: 12px, line-height: 1.6, border: #ccc, background: #000 );
Sass Maps的函数-map-remove($map,$key)、keywords($args)
map-remove($map,$key)
map-remove($map,$key) 函数是用来删除当前 $map 中的某一个 $key,从而得到一个新的 map。其返回的值还是一个 map。他并不能直接从一个 map 中删除另一个 map,仅能通过删除 map 中的某个 key 得到新 map。如:
$map:map-remove($social-colors,dribble);
返回的是一个新 map:
$map:( facebook: #3b5998, github: #171515, google: #db4437, twitter: #55acee );
如果删除的 key 并不存在于 $map 中,那么 map-remove() 函数返回的新 map 和以前的 map 一样。
$map:map-remove($social-colors,weibo);
返回的值:
$map: ( dribble: #ea4c89, facebook: #3b5998, github: #171515, google: #db4437, twitter: #55acee ); keywords($args)
keywords($args)
keywords($args) 函数可以说是一个动态创建 map 的函数。可以通过混合宏或函数的参数变创建 map。参数也是成对出现,其中 $args 变成 key(会自动去掉$符号),而 $args 对应的值就是value。
@mixin map($args...){ @debug keywords($args); } @include map( $dribble: #ea4c89, $facebook: #3b5998, $github: #171515, $google: #db4437, $twitter: #55acee );
在命令终端可以看到一个输入的 @debug 信息:
DEBUG: (dribble: #ea4c89, facebook: #3b5998, github: #171515, google: #db4437, twitter: #55acee)