Scss进阶篇2

慕课网学习笔记

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(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 函数 -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(if-true,condition 条件成立时,返回的值为 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
  )
);

Sass Maps的函数-map-get(key)

map-get(key) 函数的作用是根据 key 在 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;
}

我们来看另一种情况,假设 weibo 这个 key:

.btn-weibo{
  font-size: 12px;
  color: map-get($social-colors,weibo);
}

此时编译出来的是CSS:

.btn-weibo {
  font-size: 12px;
}

从 编译出来的 CSS 可以得知,如果 map 中,不会编译出 CSS,其实在 Sass 中,map-get($social- colors,weibo) 返回了一个 null 值。但在编译出来的 CSS 中,你只知道他没有编译出样式,而且在命令终端编译时,也没有任何错误或者警告信息。说实话,你并不知道他为什么编译不出来样式,或者说他已返回了值为 null。体验不强,也不好排错。其实如果我们自定义一个函数,另外加个判断,那就截然不同。


Sass Maps的函数-map-has-key(key)

map-has-key(key) 函数将返回一个布尔值。当 key,则函数返回 true,否则返回 false。

前面的示例,当 map 中时,使用 map-get(key) 函数将返回一个 null 值。但对于开发人员,并看不到任何提示信息。如果使用 map-has-key(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 中的所有 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将 names 的列表。然后通过 index(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(map1,$map2)

map-values($map)

map-values(map) 功能,不同的是 map-values(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(map2) 函数是将 map2 合并,然后得到一个新的 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( ) 等函数做其他事情了。

不过有一点需要注意,如果 map2 中有相同的 map2 中的 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(key)、keywords($args)

map-remove(key)

map-remove(key) 函数是用来删除当前 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)

你可能感兴趣的:(Scss进阶篇2)