Sass-学习笔记【进阶篇】

2018-05-17 16:08:30 浏览数 (1)

特别说明:

没有sass基础请移步:【Sass-学习笔记【基础篇】】http://www.cnblogs.com/padding1015/articles/7056323.html

最底部附结构图(实在是结构图太长了没办法)2017-07-07  20:17:17 

正文

一、Sass的控制命令  2017-06-22  09:11:43

1.@if语句

 @if 指令是一个 SassScript,它可以根据条件来处理样式块,如果条件为 true 返回一个样式块,反之 false 返回另一个样式块。
在 Sass 中除了 @if 之,还可以配合 @else if 和 @else 一起使用。

示例::控制一个元素隐藏或显示的代码

原理:定义一个混合宏,通过 @if...@else... 来判断传进参数的值来控制 display 的值。

代码语言:javascript复制
//SCSS

@mixin blockOrHidden($boolean:true) {
  @if $boolean {
      @debug "$boolean is #{$boolean}";
      display: block;
    }
  @else {
      @debug "$boolean is #{$boolean}";
      display: none;
    }
}
.block {
  @include blockOrHidden;
}
.hidden{
  @include blockOrHidden(false);
}

自己写了一个代码:

代码语言:javascript复制
 1 //SCSS
 2 
 3 @mixin bAh($y:ture){
 4 
 5     @if $y{
 6 
 7         @debug "这里显示#{$y}";
 8 
 9         display: block;
11     }
13     @else{
14 
15         @debug "这里显示#{$y}";
16 
17         display: none;
19     }
21 }
25 .block{
26 
27     @include bAh;
29 }
31 .hidden{
33     @include bAh(false);
35 }

有趣的有两点:

  • 首先,@debug这里可以做数学运算(后期学到)甚至sass运算

比如插值,插进来变量“形参”(其实混合宏声明的地方的参数就像js中函数function右边小括号里的形参一样,

而调用时传的参数就好像函数调用的时候的实参一样。),直接就给转换成“实参”了

  • 其次,声明混合宏的参数(形参)处,变量等于true不是用双等号(==),而是用冒号(:)

做了一个实验是,这里还可以不写:true;的设定,)(比如上边的示例第27行,bAh调用混合宏的时候什么也没有传参,

因为声明的时候,参数里就默认让变量先为true了;)

【而下边这个示例,声明宏的时候没有给定他是ture还是false,但是第13行,在调用的时候,我block选择器中传入的参数也不是true而是一个字符串true112,她依旧认成了ture】

代码语言:javascript复制
 1 @mixin bAh($y){
 2     @if $y{
 3         @debug "这里显示#{$y}";
 4         display: block;
 5     }
 6     @else{
 7         @debug "这里显示#{$y}";
 8         display: none;
 9     }
10 }
12 .block{
13     @include bAh(true112);
14 }
15 .hidden{
16     @include bAh(false);
17 }

 可见,在调用的时候,“实参”里随便放点东西,只要不是false,他都认成true,并对应解析@if{}内的样式代码块。

至于其他除了false以外的是不是都适用成true暂时还不太确定,有待实验说明。

2.For循环

在 Sass 的 @for 循环中有两种方式:

@for $i from <start> through <end>
@for $i from <start> to <end>
  • $i 表示变量
  • start 表示起始值
  • end 表示结束值
  • 关键字 through 表示包括 end 这个数
  • to 表示不包括 end 这个数

如下代码,先来个使用 through 关键字的例子:

代码语言:javascript复制
@for $i from 1 through 3 {
  .item-#{$i} { width: 2em * $i; }
}

编译出来的 CSS:

代码语言:javascript复制
.item-1 {
  width: 2em;
}
.item-2 {
  width: 4em;
}
.item-3 {
  width: 6em;
}

再来个 to 关键字的例子:

代码语言:javascript复制
@for $i from 1 to 3 {
  .item-#{$i} { width: 2em * $i; }
}

编译出来的 CSS:

代码语言:javascript复制
.item-1 {
  width: 2em;
}
.item-2 {
  width: 4em;
}

@for应用在网格系统生成各个格子 class 的代码:

2017-06-22 12:52:13

 先看一个错误的代码:图中黄色块的位置,找了半天原因,把字母都换成了英文的重写n遍都没解决问题,最后拿来一个正确的复制过来换了变量名字就对了,

对比才发现$i后边的空格这么大,还是一个,肯定就不是英文半角的空格,换成英文格式重输空格后bug就解决了。看来就是他的问题,即使空格也要用英文半角

$span : span !default; // 准备一个选择器名放到变量中。或者不准备,使用的时候直接写span好了,不用插值#{}插进去了

$sWidth: 60px !default;  //定义一个span的宽度

$sGap: 20px !default;  //定义一个间距的宽度

%grid{  //准备一个占位,放上公用的样式块

  float: left;

  margin-left: $sGap / 2;

  margin-right: $sGap / 2;

}

@for $i from 1 through 12{  //在1-12内循环,包括12。根据之前的学习,这里的 " through 12 " 也可以改成“ to 13”;最后结果一样,都是1-12遍历

  .#{$span}#{$i}{ //给1-12编号的span定义不同、递增的宽度,并调用占位符以引用相同的代码块

width: $sWidth * $i;//宽度这里总是想这么写,最后总是忘记中间间隔的计算

    width: $sWidth * $i sGap * ($i - 1);

@extend %grid; //别忘了引用之前准备好的代码块

  }

}

3.@while循环

@while 指令也需要 SassScript 表达式(像其他指令一样),并且会生成不同的样式块,直到表达式值为 false 时停止循环。

这个和 @for 指令很相似,只要 @while 后面的条件为 true 就会执行

示例:

$nums: 4;   //注意,Sass的变量赋值是用冒号(:)而不是像js那样的等号;

$nums_width: 200px;

@while $nums >= 0{  //条件不用包裹在括号里

  .while#{$nums}{

    width: $nums_width $nums;

  }

  $nums : $nums - 1;   //递减:不用  --  或  -=,而是重新赋值为原值减一。注意用冒号赋值

}

 编译的css

.while1{

  width:204px;}

.while2{

  width:203px;}

.while3{

  width:202px;}

.while4{

  width:201px;}

4.@each循环

 @each循环就是去遍历一个表格,然后从表格中取出对应的值。

语法:

@each $var in <list>

$var : 一个变量名,

<list>一个列表,返回一个列表值,变量$var要在其中循环遍历,

该SassScript表达式返回一个符合$var条件的列表值。遍历出与$var 对应的样式块。

简单示例:用来批量制作icon图标引用或者背景图引用等。

$list3: name11 name22 name33 name44 name55; @mixin hunheh{     @each $i in $list3{         .span#{$i}{             background: url("/images/#{$i}.jpg") no-repeat;         }     } }

.div{     @include hunheh }

获取的css:

.div .spanname11 {  // 如果不需要类名组,直接在全局中调用混合宏就行了。 background: url("/images/name11.jpg") no-repeat; } .div .spanname22 { background: url("/images/name22.jpg") no-repeat; } .div .spanname33 { background: url("/images/name33.jpg") no-repeat; } .div .spanname44 { background: url("/images/name44.jpg") no-repeat; } .div .spanname55 { background: url("/images/name55.jpg") no-repeat; }

 二、Sass函数及其功能

【注意】:属性与函数调用之间的冒号(:)不能省略,而且必须是英文半角格式。

代码语言:javascript复制
1 .footer{
2     width : percentage(.2);
3 }

分类:

  • 字符串函数
  • 数字函数
  • 列表函数
  • 颜色函数
  • Introspection函数
  • 三元函数
  • 自定义函数(根据自己的需求定义函数功能)
  • ...其他一些函数等

前四种最常用

 1.字符串函数

字符串函数顾名思义就是用来处理字符串的函数

A) unquote:删除字符串的引号(单/双引)【去引号】
  • 语法格式:

  :unquote($string);

  • 使用规则:
  1. unquote只能删除字符串最前边和最后边的引号,没法去掉中间的引号。
  2. 不管是双引号还是单引号包裹的字符串,引号皆被去掉;
  3. 如果字符串没有带引号,则返回原字符串;
  4. 若引号中,有半个不成对的引号,不会被去掉,一般是英文中的's用法;【因为unquote只能删除字符串最前边和最后边的引号,没法去掉中间的引号。】
  • 示例:
代码语言:javascript复制
 1 .test1 {
 2     content:  unquote('Hello Sass!') ;
 3 }
 4 .test2 {
 5     content: unquote("'Hello Sass!");
 6 }
 7 .test3 {
 8     content: unquote("I'm Web Designer");
 9 }
10 .test4 {
11     content: unquote("'Hello Sass!'");
12 }
13 .test5 {
14     content: unquote('"Hello Sass!"');
15 }
16 .test6 {
17     content: unquote(Hello Sass);
18 }
代码语言:javascript复制
 1 .test1 {
 2 
 3   content: Hello Sass!; }
 4 
 5 .test2 {
 6 
 7   content: 'Hello Sass!; }
 8 
 9 .test3 {
10 
11   content: I'm Web Designer; }
12 
13 .test4 {
14 
15   content: 'Hello Sass!'; }
16 
17 .test5 {
18 
19   content: "Hello Sass!"; }
20 
21 .test6 {
22 
23   content: Hello Sass; }
B)quote:给字符串添加引号(双引号)【加引号】
  • 语法格式

  :quote($string)

  • 使用规则:
  1. 若字符串本身带有引号,就不添加;
  2. 若字符串带有单引号,则跟换为双引号;
  3. 若双引号中有单引号,则不变,单引号不受影响;
  4. 若字符串中间有空格或者半块的单引号、双引号时,需要用单引号或双引号括起,不然编译会报错【解决方案就是去掉空格,或者加上引号】
  5. 碰到特殊符号,比如: !、?、> 等,除中折号 - 和下划线_ 都需要使用双引号括起,否则编译器在进行编译的时候同样会报错:
  •  示例:
代码语言:javascript复制
1 .test1 {
2     content:  quote('Hello Sass!');
3 }
4 
5 .test3 {
6     content: quote(ImWebDesigner);
7 }
代码语言:javascript复制
1 .test1 {
2 
3   content: "Hello Sass!"; }
4 
5 .test3 {
6 
7   content: "ImWebDesigner"; }
  •  注意:

——单引号变成双引号:如——

.test4 {   content: quote(' '); }

转换后的css

.test4 {   content: quote(" "); }

—— 以下写法会报错:【正如第四条】——

.test3 {   content: quote(ImWebDesigner's); }

代码语言:javascript复制
error style.scss (Line 13: $string: ("Hello""Sass") is not a string for `quote')

 就是类似 ’s 这样的写法。

 ——特殊符号报错——

代码语言:javascript复制
error style.scss (Line 13: Invalid CSS after "...quote(HelloSass": expected ")", was "!);")
C)to-upper-case:将小写字母转换成大写【小——大】
  • 语法格式

  :to-upper-case(string);

D)to-lower-case:将大写字母转换成小写【大——小】
  • 语法格式

  :to-upper-case(string);

to-upper和to-lower:二者综合使用规则

  1. 字符串中有引号也没有关系
  2. 字符串中有特殊字符也没有关系

2.数字函数

A) percentage($value):将一个不带单位的数转换成百分比值

  • 结果/公式:  $value * 100%

  三种写法:

代码语言:javascript复制
1 .footer{
2     width : percentage(.2);
3     height: percentage(2px / 10px);
4     margin: percentage(2em / 10em);
5 }

三种写法返回的结果值均为:20%——

代码语言:javascript复制
.footer {
  width: 20%;
  height: 20%;
  margin: 20%; 
}

B)round($value):四舍五入

  • 4舍:小数点后一位"<=4",(0-4)直接去掉小数点及后边的数;
  •   5入:小数点后一位">=5",(5-9)整数部分加1并去掉小数点及后边的数;
  •   无关正负号;
  •   无关单位,任何单位都可以进行四舍五入计算;
  •   括号内可以放数字运算公式,而且公式能成立函数才有作用;
  • 注意式子两边单位统不统一,若不统一会报错。如round(2em / 10px)。
代码语言:javascript复制
1 .footer1 {
2    width:round(-15.54px)
3 }
代码语言:javascript复制
1 .footer1 {
2   width: -16px; }

其他情景模拟:

代码语言:javascript复制
 1 >> round(12.3)
 2 12
 3 >> round(12.5)
 4 13
 5 >> round(1.49999)
 6 1
 7 >> round(2.0)
 8 2
 9 >> round(20%)
10 20%
11 >> round(2.2%)
12 2%
13 >> round(3.9em)
14 4em
15 >> round(2.3px)
16 2px
17 >> round(2px / 3px)
18 1
19 >> round(1px / 3px)
20 0
21 >> round(3px / 2em)
22 2px/em【这个写法会报错】

【注】最后一个写法中,两个不同的单位来计算是不行的,但是其中一个有单位另一个没单位倒是可以的,

其实根本原因是,他里边的式子能计算,外部的函数就可以计算。里边式子都是错的,结果不是一个$value,自然函数不能用。

C)ceil($value):向上取整

  • 数值为正,整数部分加一并去掉小数点及后边的数;1.4—>2
  •   数值为负,整数部分不变并去掉小数点及后边的数。-1.4—>-1【相当于floor了】
  •   这里做运算,单位就不能用了,

示例:

代码语言:javascript复制
 1 >> ceil(2.0)
 2 2
 3 >> ceil(2.1)
 4 3
 5 >> ceil(2.6)
 6 3
 7 >> ceil(2.3%)
 8 3%
 9 >> ceil(2.3px)
10 3px
11 >> ceil(2.5px)
12 3px
13 >> ceil(2 / 8)  // 注意这里,做除法时,要把单位都去掉,要不都加单位、要不都不加单位。但是只有其中一个有单位就不能编译 。
14 1
15 >> ceil(2 * 8px)  //乘法中, 这个单位可以有一个,可以两个都没有单位,但是两个都有就不行,
16 16 

D)floor($value):向下取整

  • 就是直接去掉小数点及以后的数而已。
代码语言:javascript复制
 1 >> floor(2.1)
 2 2
 3 >> floor(2.5)
 4 2
 5 >> floor(3.5%)
 6 3%
 7 >> floor(10.2px)
 8 10px
 9 >> floor(10.8em)
10 10em 
11 >> floor(45px / 10px)
12 4
13 >> floor(3px * 1)
14 3em

总是总结一句话:函数内部可以用数字运算,但是运算公式要尊重加减乘除公式的运算法则。

比如乘法不能两边都有单位,除法不能只有一个有单位。

E)abs($value):取绝对值

  • 负数变正的;
  •   正数还是正。
代码语言:javascript复制
 1 >> abs(10)
 2 10
 3 >> abs(-10)
 4 10
 5 >> abs(-10px)
 6 10px
 7 >> abs(-2em)
 8 2em
 9 >> abs(-.5%)
10 0.5%
11 >> abs(-1px / 2px)
12 0.5
13 >> abs(-3 / 2)
14 1.5

F)min($number...):在一堆数中找出最小值

  •   这个函数可以设置任意多个参数,多个参数之间用逗号隔开。
  •   若小数点的是最小的,则保留带小数点的数,原样返回。
  •   多个参数可以带单位,有几个带的有几个不带的。
  •   但是在 min() 函数中同时出现两种不同类型的单位,不然会报错。
代码语言:javascript复制
2 >> min(1,2,1%,3,300%)
3 1%
4 >> min(1px,2,3px)
5 1px
6 >> min(1em,2em,6em)
7 1em

G)max($number...):在一堆数中找出最大值

  • 这一堆数用逗号隔开。
  •   若小数点的是最大的,则保留带小数点的数,原样返回。
  •  多个参数可以带单位,有几个带的有几个不带的。
  •   但是在 min() 函数中同时出现两种不同类型的单位,不然会报错。
代码语言:javascript复制
1 >> max(1,5)
2 5
3 >> max(1px,5px)
4 5px

H)random():取0-1之间的随机数

  • 获取的是0-1之间的数,集合(0,1)。
代码语言:javascript复制
 1 >> random()
 2 0.03886
 3 >> random()
 4 0.66527
 5 >> random()
 6 0.8125
 7 >> random()
 8 0.26839
 9 >> random()
10 0.85063

  所有函数做个范例

代码语言:javascript复制

3.列表函数

length(); nth(); join(); append(); zip(); index(); Introspection();{

unit();         unitless();         comparable();

} Miscellaneous();

A) length($list):返回一个列表的长度值

  • 列表中的数值之间用空格隔开,千万别用逗号会报错;
  •   用小括号括起来的几个值算成一个值;
  •   同一个列表里边不同值可以是不同类型、不同单位的值
代码语言:javascript复制
1 >> length(10px)
2 1
3 >> length(10px 20px (border 1px solid) 2em)
4 4
5 >> length(border 1px solid)
6 3

B) nth($list, $n):找出一个列表中指定的某个标签值

  • 列表中值得编号从1开始:1 是指列表中的第一个标签值,2 是指列给中的第二个标签值,依此类推。
  •   在 nth($list,$n) 函数中的 $n 必须是大于 0 的整数!若为0会报错:如 SyntaxError: List index 0 must be a non-zero integer for `nth'
代码语言:javascript复制
1 >> nth(10px 20px 30px,1)
2 10px
3 >> nth((Helvetica,Arial,sans-serif),2)
4 "Arial"
5 >> nth((1px solid red) border-top green,1)
6 (1px "solid" #ff0000)

C) join($list1,$list2,[$separator]):将两个列连起来变成一个

  • 功能:链接两个列表为1个列表,不同列表之间用逗号隔开
代码语言:javascript复制
1 >> join(10px 20px, 30px 40px)
2 (10px 20px 30px 40px)
  •  注意:一次只能链接两个,若待链接的列表多于两个,则两个之后的就连不进来了

如下,链接了三个列表,第三个就没进来

代码语言:javascript复制
1 >>join(blue,(red orange),space);//三个列表
2 (blue red orange)
  •   想要链接多个值列表,使用多个join

示例:看height处的写法,有多个列表值时,用join将之两两合并;

代码语言:javascript复制
 1 div{
 2     width: join(blue,(red orange),space);
 3     height: join(blue,join((red orange),space));
 4 }
 5 >>结果
 6 div {
 7 
 8   width: blue red orange;
 9 
10   height: blue red orange space; }
  •   若需要链接的列表中,项是颜色值,不管原列表中值是什么格式,连接后都会转变成#号加16进制的RGB写法【这个也不缺定,在慕课的在线编辑器上,还是会和原列表中的值一模一样的额写法,比如blue并没有改变成rgb,而还是英语单词】
代码语言:javascript复制
1 >> join((blue,red),(#abc,#def))
2 (#0000ff, #ff0000, #aabbcc, #ddeeff)
3 >> join((blue,red),(#abc #def))
4 (#0000ff, #ff0000, #aabbcc, #ddeeff)
  • separator参数可以设置链接后的列表中各个列表项值之间用什么分隔。
    • auto是空格(  )分隔
    • comma是逗号(,)分隔
    • space是使用空格(  )分隔
  •   链接后的列表分隔准则:
    • 若不指定separator,
      • 当待合并的第一个列表中只有一个列表项,合并后的列表项目中每个列表项目之间使用的分隔符号会根据第二个列表项中使用的来决定。若第二个列表项中用的逗号(,)分隔,合并后的列表项就会是用逗号分割的;如果第二项用的空格,则最后也用空格
      • 第一个列表中值大于两个,且每个值之间用的是空格分隔,那么合并后的列表中的每个列表项之间也是用空格分隔,也就是说按照第一个列表中的分隔方式俩决定
      • 若两个待合并的列表项中的值均小于1时,将会以空格分隔
    • 由于繁琐,建议特别指定separator的值
代码语言:javascript复制
1 >> join((blue green),(red,orange),comma)
2 (#0000ff, #008000, #ff0000, #ffa500)
3 >> join((blue green),(red,orange),space)
4 (#0000ff #008000 #ff0000 #ffa500)
5 >> join((blue, green),(red,orange),comma)
6 (#0000ff, #008000, #ff0000, #ffa500)
7 >> join((blue, green),(red,orange),space)
8 (#0000ff #008000 #ff0000 #ffa500)

D) append($list, $val, [$separator]):将某个值放在列表的最后

  •   append() 函数是用来将某个值插入到列表中,并且处于最末位。
代码语言:javascript复制
1 >> append(10px 20px ,30px)
2 (10px 20px 30px)
3 >> append((10px,20px),30px)
4 (10px, 20px, 30px)
5 >> append(green,red)
6 (#008000 #ff0000)
7 >> append(red,(green,blue))
8 (#ff0000 (#008000, #0000ff))
  • 在 append() 函数中,可以显示的设置 $separator 参数,
    • comma:逗号分隔
    • space : 空格分隔
  •   如果没有明确的指定 $separator 参数值,其默认值是 auto。
    •   如果列表只有一个列表项时,那么插入进来的值将和原来的值会以空格的方式分隔;
    •   如果列表中列表项是以空格分隔列表项,那么插入进来的列表项也将以空格分隔;
    •   如果列表中列表项是以逗号分隔列表项,那么插入进来的列表项也将以逗号分隔。
代码语言:javascript复制
 1 >> append((blue green),red,comma)
 2 (#0000ff, #008000, #ff0000)
 3 >> append((blue green),red,space)
 4 (#0000ff #008000 #ff0000)
 5 >> append((blue, green),red,comma)
 6 (#0000ff, #008000, #ff0000)
 7 >> append((blue, green),red,space)
 8 (#0000ff #008000 #ff0000)
 9 >> append(blue,red,comma)
10 (#0000ff, #ff0000)
11 >> append(blue,red,space)
12 (#0000ff #ff0000)

E) zip($lists...):将几个列表合并成一个多维列表

  •   将多个列表值转成一个多维的列表
代码语言:javascript复制
>> zip(1px 2px 3px,solid dashed dotted,green blue red)
((1px "solid" #008000), (2px "dashed" #0000ff), (3px "dotted" #ff0000))
示例:
div{width:zip(solid dashed dotted,1px 2px 3px,green blue red);
    width:zip((1px "solid" #008000), (2px "dashed" #0000ff), (3px "dotted" #ff0000))
}
编译的css
div {
  width: solid 1px green, dashed 2px blue, dotted 3px red;
  width: 1px 2px 3px, "solid" "dashed" "dotted", #008000 #0000ff #ff0000; }
  •   有特殊的组合规则

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
  •   因为规则,所以:在使用zip()函数时,每个单一的列表个数值必须是相同的——
代码语言:javascript复制
1 >> zip(1px 2px 3px, solid , green blue red)
2 NoMethodError: undefined method `options=' for nil:NilClass
3   Use --trace for backtrace.

F) index($list,$value):返回一个值在列表中的位置值

  •   index() 函数类似于索引一样,主要让你找到某个值在列表中所处的位置。
  •   在 Sass 中,第一个值就是1,第二个值就是 2,依此类推:
  • ??没有空格的时候,还会占位吗?
  •   如果指定的值不在列表中(没有找到相应的值),那么返回的值将是 false;
  •   返回对应的值在列表中所处的位置
代码语言:javascript复制
 1 >> index(1px solid red, 1px)
 2 1
 3 >> index(1px solid red, solid)
 4 2
 5 >> index(1px solid red, red)
 6 3
 7 >> index(1px solid red,dotted) //列表中没有找到 dotted
 8 false
 9 >> index(1px solid red,solid) //列表中找到 solid 值,并且返回他的位置值 2
10 2
代码语言:javascript复制
 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="UTF-8">
 5         <meta name="author" content="郭菊锋 702004176@qq.com"/>
 6         <title>Sass进阶篇知识汇总</title>
 7     </head>
 8     <body>
 9     </body>
10 </html>

2017-07-03  20:07:53 

G) Introspection函数

  1、type-of($value):返回一个值得类型

代码语言:javascript复制
 1 div{
 2     width:type-of(false)
 3 }
 4 >> type-of(100)
 5 "number"
 6 >> type-of(100px)
 7 "number"
 8 >> type-of("asdf")
 9 "string"
10 >> type-of(asdf)
11 "string"
12 >> type-of(true)
13 "bool"
14 >> type-of(false)
15 "bool"
16 >> type-of(#fff)
17 "color"
18 >> type-of(blue)
19 "color"
20 >> type-of(1 / 2 = 1)
21 "string"
22 
23 
24 返回值:
25 number 为数值型。
26 string 为字符串型。
27 bool 为布尔型。
28 color 为颜色型。

  2、unit($number):返回一个值得单位、获取一个值所使用的单位,

!!!用于复杂的计算,能根据运算得到一个“多单位组合”的值,不过只允许乘除运算

计算加、减碰到不同单位时,unit函数将会报错。px、cm、mm运算之外

代码语言:javascript复制
1 div{
2    width: unit(100px);
3 
4     height: unit(10px / 3em);
5 }
代码语言:javascript复制
1 div {
2 
3   width: "px";
4 
5   height: "px/em"; }

看上边的代码,高度那里计算出来的是错误的没有什么实际用处的单位值

  3、unitless($number):判断一个值 是否带有单位

  如果不带单位返回的值为 true【注意】,带单位返回的值为 false:

如下代码:

调用混合宏时,如果用户没有给参数值加上单位,程序会自动加入单位。

代码语言:javascript复制
@mixin adjust-test($x,$y){
    @if unitless($x){
      $x: 1px * $x;      
     }
  @if unitless($y){
  $y: 1px *$y;  
}          
  position: relative;
left: $x;
top: $y;  
}
.botton{
@include adjust-test(20px,30);
}

  4、comparable($number-1,$number-2):判断两个值是否可以做加、减和合并。

如果可以相加,返回的是true,如果不能相加,返回的是false;

div{

width: comparable(2px,1px);

height: comparable(2px,1em);

border: comparable(2rem,1em);

color: comparable(2px,1cm);

line-height: comparable(2px,1cm);

padding: comparable(1px,2mm);

}

特别说明:并不是这种写法是对的,这样写只是为了在线的编辑器可以及时的返回结果,但是代码这么用是不对的额。

 运算结果:

代码语言:javascript复制
 1 div {
 2 
 3   width: true;
 4 
 5   height: false;
 6 
 7   border: false;
 8 
 9   color: true;
10 
11   line-height: true;
12 
13   padding: true; }

4.Miscellaneous函数——三元条件函数:

if($condition,$if-true,$if-false);

判断$condition,如果条件成立,则返回$if-true的结果,如果条件不成立,则返回$if-false的结果。

代码语言:javascript复制
1 div{width:if(true,8em,20em)}
2 
3 a{height:if(false,8em,20em)}
代码语言:javascript复制
1 div {
3   width: 8em; }
7 a {
9   height: 20em; }

5.Map——数据地图,数组

 Sass 的 map 长得与 JSON 极其相似

代码语言:javascript复制
json的写法:
代码语言:javascript复制
{
  "employees": [
    { "firstName":"John" , "lastName":"Doe" },
    { "firstName":"Anna" , "lastName":"Smith" },
    { "firstName":"Peter" , "lastName":"Jones" }
  ]
}
如map的写法:
代码语言:javascript复制
$map: (
    $key1: value1,
    $key2: value2,
    $key3: value3
)

首先有一个类似于 Sass 的变量一样,用个 $ 加上命名空间来声明 map。

后面紧接是一个小括号 (),将数据以 key:value 的形式赋予,

其中 key 和 value 是成对出现,并且每对之间使用逗号 (,) 分隔,其中最后一组、最后一对后面没有逗号

 其中,键key是用来查找相关联的值value。使用map可以很容易的收集键的值和动态的插入新的键值对。

a) map集合

原来的时候,在sass中声明定义变量的方法如下:

$default-color: #fff !default;

$primary-color: #22e2e2 !default;

这种的,可以用map来管理起来,就像用json把js中的多个变量值对集合起来一样。

$color:(//这里用小括号,不是大括号,区别于json

  default #fff,//用逗号隔开每个键值对。键和值之间用冒号

  primary: #22e2e2   //最后一组键值对不用逗号

这样组合的好处是:

日后可以随意的动态の增、改、删、查

b) 二维、多维map

就像数组里有二维数组、json里有二维json一样,map里也有"二维数据、多维数据"来嵌套

一个key值可以做另一组map的名字

$map: (

  $key1 : $value1,

  $key2: (//同样用小括号包裹

    $key-1 :$value-1,

    $key-2 :$value-2

),//map中的map,除了用括号包裹,也用逗号分隔,反正就记住,内部没有分号、没有大括号

  $key3 :$value3

);//最后用分号,是和其他的sass代码切割用的。

这种嵌套的写法,可以用来写换肤项目的代码。

“可能每一套的皮肤对应的代码挺多的,那么使用此功能来管理颜色的变量就非常的有条理性,便于维护和管理”

 c) map应用——换肤项目案例

使用方法如下:(注:是个二维map)

代码语言:javascript复制
 1 $theme-color : (
 2 
 3   default :(
 4 
 5     bgcolor:#fff , 
 6 
 7     text-color : #444,
 8 
 9     link-color: #333
10 
11   ),
12 
13   primary :(
14 
15     bgcolor : #000 ,
16 
17     text-color : #211,
18 
19     link-color : #212
20 
21   ),
22 
23   negative :(
24 
25     bgcolor : #090 ,
26 
27     text-color : #598 ,
28 
29     link-color : #586 ,
30 
31   )
32 
33 );

 d) map调用

就像json会有for in来遍历一样,map的数据组也可以用sass的@each in 来遍历来调用:

@each $keys,$values  in $theme-color{

  .theme-color-#{$keys}{

    @each $key,$value in $values{

      #{$key}: #{$value}

    }

  }

}

代码语言:javascript复制
 1 .theme-color-default {
 2 
 3   bgcolor: #fff;
 4 
 5   text-color: #444;
 6 
 7   link-color: #39f; }
 8 
 9 .theme-color-primary {
10 
11   bgcolor: #000;
12 
13   text-color: #fff;
14 
15   link-color: #93f; }
16 
17 .theme-color-negative {
18 
19   bgcolor: #f36;
20 
21   text-color: #fefefe;
22 
23   link-color: #d4e; }

e)最后注意:

键和值之间的冒号千万不要省略,有些老版本的sass中有这么写的,但是现在不能这么写了,不然,死都不知道怎么死;

我以上的代码中,为了突出重点、为了代码名了,多出用了中文的符号来强调,但是复制到自己的文件中,一定要改成英文半角状态的符号才不会报错。

有时候中文的空格都会报错。

2017-07-04  14:41:18

 6.Maps函数

  • 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。

A).map-get($map,$key)

根据 $key 参数,返回 $key 在 $map 中对应的 value 值。

如果 $key 不存在 $map中,将返回 null 值。

两个参数:

  • $map:定义好的 map。
  • $key:需要遍历的 key。

示例:

代码语言:javascript复制
 1 $social-colors: (
 2     dribble: #ea4c89,
 3     facebook: #3b5998,
 4     github: #171515,
 5     google: #db4437,
 6     twitter: #55acee
 7 );
 8 .btn-dribble{
 9   color: map-get($social-colors,facebook);
10   color: map-get($social-colors,dribble)
11 }
代码语言:javascript复制
1 .btn-dribble {
2 
3   color: #3b5998;
4 
5   color: #ea4c89; }

特别注意:

我们来看另一种情况,假设 $social-colors 这个 map 没有 $weibo 这个 key:

代码语言:javascript复制
.btn-weibo{
  font-size: 12px;
  color: map-get($social-colors,weibo);
}

此时编译出来的是CSS:

代码语言:javascript复制
.btn-weibo {
  font-size: 12px;
}

如果map没有$key对应的$value值,他不会把css编译出来(其实他返回一个null,但在编译出来的 CSS 中,你只知道他没有编译出样式,而且在命令终端编译时,也没有任何错误或者警告信息。体验不强,也不好排错。其实如果我们自定义一个函数,另外加个判断,那就截然不同。)

如果使用 map-has-key($map,$key) 函数就可以改变这一状态。如下:

B).map-has-key($map,$key)

函数将返回一个布尔值。当 $map 中有这个 $key,则函数返回 true,否则返回 false。

判断的原理和结构代码如下:

首先为了需要,我先贮备一个map集合——

代码语言:javascript复制
1 $map:(//map与括号之间有冒号
2     facebook : #111,
3     twiter : #222,
4     qq : #333,
5     weixin: #444
6 );

然后判断,如果map中有我们需要的key,且其有对应值,则执行代码利用map-get调用map中的值,否则弹出报错

结构:

代码语言:javascript复制
 1 @if map-has-key($map,$key){
 2 
 3   //执行条件成立的代码,如让某个选择器调用代码等。
 4 
 5 }@else{
 6 
 7   //执行条件不成立的代码,手动报错错误
 8 
 9   @warn "出错了。";
10 
11 }

分析:

@if map-has-key($map,qq){//如果在map中有qq这个键,且其有对应的值

  div{

    color: map-get($map,qq);//在map中取出qq对应的值,给了div的color

  } @else{

    #warn "no color found";

  }  

}

总觉得这样写是傻傻的,总不可能每获取一个 key 都写一个 @if 语句吧。其实不用这么复杂,我们可以

封装——自定义一个函数,比如 colors():

代码语言:javascript复制
 1 @function colors($color){
 2 
 3   @if not map-has-key($mapName,$color){
 4 
 5     @warn "Error prompt"
 6 
 7 
 8   }
 9 
10   @return map-get($mapName,$color);
11 
12 }
13 
14 div{
15 
16   color : colors($keyName)
17 
18 }

代码解释:

行1:定义一个名字为colors的函数;

  里边一个形参变量,名字随便起

3:@if not,注意这里是反向判断,如果没有的话才会执行后边大括号内部的代码;

  mpa-has-key的名字别写错;

  $mapName就是上边你定义的map的名字,$color:对应声明函数的时候,括号里的形参

5:@warn,总是a、r写反,注意单词的写法;

  错误提示信息随意发挥

10: 函数返回值:是在@if not不成立的时候,也就是map中键有对应值得时候;

  利用map-get,在map中获取需要的key值;

  $mapName就是上边的map的名字、$color就是和上边的形参一样即可

14:需要获取相关信息的选择器开始调用,

16:调用的方法与js无异,直接函数名调用,里边放的是具体的键值的名字,是你需要的键的名字。

实例如下:

代码语言:javascript复制
$map:(//map与括号之间有冒号
    facebook : #111,
    twiter : #222,
    qq : #333,
    weixin: #444
);

@function colors($color){
    @if not map-has-key($map , $color){//map-has-key的函数名字别写错了
        @warn "错误了";
    }
        @return map-get($map, $color);
    
}

div{
    color: colors(qq);
}

相比原来的判断语句来说,这次代码的重用率更高了。

C).map-keys($map)

 函数将会返回 $map 中的所有 key。这些值赋予给一个变量,那他就是一个列表。如:

代码语言:javascript复制
map-keys($social-colors);

其返回的值为:

代码语言:javascript复制
"dribble","facebook","github","google","twitter"

换句话说:

代码语言:javascript复制
$list: map-keys($social-colors);

相当于:

代码语言:javascript复制
$list:"dribble","facebook","github","google","twitter";

可以配合 Sass 的 list 做很多事情。

上面的示例,可以做通过 map-keys($map) 来做一个修改:

代码语言:javascript复制
1 @function colors($color){
2     $names: map-keys($social-colors);
3     @if not index($names,$color){
4         @warn "Waring: `#{$color} is not a valid color name.`";
5     }
6     @return map-get($social-colors,$color);
7 }

上面代码中最不同之处,我们使 用map-key s将 $social-colors 这个 map 的所有 key 取出,并赋予给一个名 为 $names 的列表。然后通过 index($names,$color) 返回 $color 在 $names 位置,如果这个位置不存在,将返回提示信息,如果存在将返回正确的值。

实例:

代码语言:javascript复制
 1 $map:(
 2     a:1,
 3     b:2,
 4     s:3,
 5     k:4
 6 );
 7 @function colors($colors){
 8      $colorNames: map-keys($map);
 9      @if not index($colorNames,$colors){
10          @warn "!";
11      }
12      @return map-get($map,$colors);
13 }
14 div{
15     z-index: colors(a)
16 }

css:

代码语言:javascript复制
div {

  z-index: 1; }

也可以通过 @each 或者 @for 遍历出所有值:

@each方法

代码语言:javascript复制
@each $name in map-keys($social-colors){
    .btn-#{$name}{
        color: colors($name);
    }
}

实例及css

代码语言:javascript复制
 1  $map:(
 2     a:1,
 3     b:2,
 4     s:3,
 5     k:4
 6 );
 7 @function colors($colors){
 8      $colorNames: map-keys($map);
 9      @if not index($colorNames,$colors){
10          @warn "!";
11      }
12      @return map-get($map,$colors);
13 }
14 $colorsName: map-keys($map);
15 @each $name in map-keys($map){
16      .btn-#{$name}{
17          z-index: colors($name); 
18      }
19 }

@for方法

代码语言:javascript复制
@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

代码语言:javascript复制
 1 $map:(
 2     a:1,
 3     b:2,
 4     s:3,
 5     k:4
 6 );
 7 @function colors($colors){
 8      $colorNames: map-keys($map);
 9      @if not index($colorNames,$colors){
10          @warn "!";
11      }
12      @return map-get($map,$colors);
13 }
14 $colorsName: map-keys($map); 
15 @for $i from 1 through length($colorsName){
16     .div-#{nth($colorsName,1)}{
17         color: colors(nth($colorsName,$i));
18     }
19 }

虽然使用的方法不一样,但最终得到的 CSS 是一样的:

D).map-values($map)

 map-values($map) 函数类似于 map-keys($map) 功能

不同的是 map-values($map )获取的是 $map 的所有 value 值,可以说也将是一个列表。

而且,map-values($map) 中如果有相同的 value 也将会全部获取出来。

如前面的示例,使用:

代码语言:javascript复制
map-values($social-colors)

将会返回:

代码语言:javascript复制
#ea4c89,#3b5998,#171515,#db4437,#55acee

值与值之前同样用逗号分隔。

E).map-merge($map1,$map2)

map-merge($map1,$map2) 函数是将 $map1 和 $map2 合并,然后得到一个新的 $map。

如果你要快速将新的值插入到 $map 中的话,这种方法是最佳方法。假设我们有两个 $map:

代码语言:javascript复制
 1 $color: (
 2     text: #f36,
 3     link: #f63,
 4     border: #ddd,
 5     backround: #fff
 6 );
 7 $typo:(
 8     font-size: 12px,
 9     line-height: 1.6,
10     border: #ccc,
11     background: #000
12 );

合并成一个的方法

$newmap : map-merge($color,$typo);

将会生成一个新的map:

代码语言:javascript复制
1 $newmap:(
2     text: #f36,
3     link: #f63,
4     font-size: 12px,
5     line-height: 1.6,
6     border: #ccc,
7     background: #000
8 );

这样你就可以借助 map-get( ) 等函数做其他事情了。

不过有一点需要注意,如果 $map1 和 $map2 中有相同的 $key 名,那么将 $map2 中的 $key 会取代 $map1 中的:

 比如,把合并的map放到一个标签中:利用@each方法遍历:

代码语言:javascript复制
 1 $div1(
 2   text: #f36,
 3   link: #f35,
 4   border: #384          
 5 )
 6 $div2(
 7   width: 300px,
 8   height: 100px,
 9   z-index: 3      
10 )
11 $newmap: map-merge($div1,$div2);
12 div{
13   @each $x,$y in $newmap{
14      #{$x}: #{$y};      
15     }  
16 }
代码语言:javascript复制
1 div{
2   text: #f36;
3     link: #f35;
4     border: #384;
5     width: 300px;  
6     height: 100px;
7     z-index:3;
8 }

F).map-remove($map,$key)

map-remove($map,$key) 函数是用来删除当前 $map 中的某一个 $key,从而得到一个新的 map。其返回的值还是一个 map。

他并不能直接从一个 map 中删除另一个 map,仅能通过删除 map 中的某个 key 得到新 map。

代码语言:javascript复制
 1 $map:(
 2 a:1,
 3 b:2,
 4 c:3,
 5 d:4
 6 );//少一个分号都会报错
 7 $newmap:map-remove($map,f);// 删除的key并不存在的时候,那么返回的新map和之前的旧map是一样的。
 8 div{
 9     @each $x,$y in $newmap{
10         #{$x}:#{$y};
11     }
12 }
13 
14 $newmap2:map-remove($map,d);//删除map的某个值,返回一个新的map
15 .div2{
16     
17     @each $x,$y in $newmap2{
18         #{$x}:#{$y};
19     }
20 }

G).keywords($args)

 定义上说:这个函数可以动态的创建map函数,但是我自己思考,若要动态的添加key和value值,在map函数中也是可以的额。

但是他的一个特色用法是:可以通过混合宏或函数的参数动态创建map。

函数传的参数也是成对的出现的。函数的参数形式就相当于一个map里边的键值对的形式,区别是:map里边的key没有$符号,但是参数里的有

形参$args变成key(key会自动去掉$符号),$args对应的值就是value。

比如示例函数:

代码语言:javascript复制
 1 @mixin map($args){
 2 
 3   @debug keywords($args);
 4 
 5 }
 6 
 7 @include map(
 8 
 9   $a: 1,
10 
11   $b: 2,
12 
13   $c: 3
14 
15 )

这样,在命令终端,就会得到一个@debug的信息:

代码语言:javascript复制
./8460/F9mR/index.scss:23 DEBUG: (a: 1, b: 2, c: 3)

你也会发现,debug出来的key值没有带着$符号了

我的理解是:在debug前,有$符号的key是参数,他就是一个变量,所以有

debug出来后,或者说keywords动态的一个一个把他们转变成map键值对后,他们就成了map里的KEY,也就不需要符号了。

实际用途:

批量的给小图标改颜色(多皮肤设置也可以)

代码语言:javascript复制
 1 @mixin bgColors($args...){//表示传入多个参数,用了“...”符号
 2 
 3   $list: keywords($args);
 4 
 5   @each $x,$y in $list{//用一个each,循环变量colors列表里的键值对
 6 
 7     .bg_#{$x}{
 8 
 9       background-color:#{$y};
10     }
11   }
12 
13 }
14 
15 @include bgColors(//调用函数,并传入需要设置值得参数
16 
17   $weibo: #f00,
18 
19   $QQ : #0f0,
20 
21   $weixin: #00f,
22 
23   $github: #000
24 
25 )

最后编译后的style:

代码语言:javascript复制
 1 .bg_weibo {
 2 
 3   background-color: #f00; }
 4 
 5 .bg_QQ {
 6 
 7   background-color: #0f0; }
 8 
 9 .bg_weixin {
10 
11   background-color: #00f; }
12 
13 .bg_github {
14 
15   background-color: #000; }

日后,如果需要,还可以多次插入,也就是前文提到的动态的创建。

7.颜色函数

  1).RGB()函数

A).rgb($red,$green,$blue):根据红、绿、蓝三个值创建一个颜色,

  输入的是三个0-255之间的数字值,分别是红绿蓝三个颜色的值,然后得到一个16进制的颜色值,比如#293849

B).rgba($red,$green,$blue,$alpha):根据红、绿、蓝和透明度值创建一个颜色

  函数主要用来将一个颜色根据透明度转换成rgba颜色。

语法格式:

C).rgba($red,$green,$blue,$alpha):将一个rgba颜色转译出来,和未转译的值一样。

D).rgba($color,$alpha):一个Hex(16进制)颜色值转换成rgba颜色!!这种写法在css中不被允许,但是在sass中却可以这么写。

语法:

在括号是函数的参数,第一个参数是需要转换的颜色,他可以是任何颜色的表达方式,也可以是一个颜色变量;第二个参数是颜色的透明度,其值是 0~1 之间。

例子,假设在变量中定义了一个基本的变量:

代码语言:javascript复制
1 $color: #f36;
2 $bgColor: orange;
3 $borderColor:green;

调用定义的变量

同时给他们加上 .5 的透明度:

代码语言:javascript复制
1 //SCSS
2 .rgba {
3     color: rgba($color,.5);
4     background: rgba($bgColor,.5);
5     border-color: rgba($borderColor,.5);
6 }

或者直接把颜色值替换掉变量的写法:

代码语言:javascript复制
1 //SCSS
2 .rgba {
3     color: rgba(#f36,.5);
4     background: rgba(orange,.5);
5     border-color: rgba(green,.5);
6 }
代码语言:javascript复制
1 .rgba {
2   color: rgba(255, 51, 102, 0.5);
3   background: rgba(255, 165, 0, 0.5);
4   border-color: rgba(0, 128, 0, 0.5);
5 }

E).red($color):从一个颜色中获取其红色值 F).green($color):从一个颜色中获取其绿色值 G).blue($color):从一个颜色中获取其蓝色值

以上三个函数用法一致,挑一个做案例:

Red()函数:

在命令终端要先输入sass -i 命令

假设有一个 #f36 的颜色,如果你想得到 #f36 中的 red 值是多少,这个时候使用 red() 函数就能很简单获取。

代码语言:javascript复制
1 >> red(#f36)
2 255

实际用法:

当颜色的红色值大于50使用白色,当红色值小于50使用黑色

代码语言:javascript复制
 1 $color: #f36;
 2 
 3 .body {
 4     @if red($color) > 50 {
 5         color: #fff;
 6     }
 7     @else if red($color) < 50 {
 8         color:#000;
 9     }
10 }
代码语言:javascript复制
1 .body {
2 
3   color: #fff; }

H).mix($color-1,$color-2,[#weight]):把两种颜色按照一定的比例混合在一起,

$color-1、$color-2:指的是你需要合并的颜色,颜色可以是任何表达式,也可以是颜色变量,还可以是颜色函数如rgba();

$weight是权重值,也就是混合比例,表示第一种颜色的比例值——默认是50%。取值范围0-1之间

他是每个rgb的百分比来衡量,(透明度也会有一定的权重)

若指定比例是25%:则表示第一个颜色所占的比例是25%,第二个颜色所占的比例是75%。

使用方法入下:

代码语言:javascript复制
1 mix(#f00, #00f) => #7f007f
2 mix(#f00, #00f, 25%) => #3f00bf
3 mix(rgba(255, 0, 0, 0.5), #00f) => rgba(63, 0, 191, 0.75)

案例:$color-1与$color-2用变量来表示:

代码语言:javascript复制
 1 $color1: #a63;
 2 $color2: #fff;
 3 $bgColor1: #f36;
 4 $bgColor2: #e36;
 5 $borderColor1:#c36;
 6 $borderColor2:#b36;
 7 
 8 .mix {
 9     background: mix($bgColor1,$bgColor2,.75);
10     color: mix($color1,$color2,.25);
11     border-color: mix($borderColor1,$bgColor2,.05);
12 }
代码语言:javascript复制
1 .mix {
2     background: #ee3366;
3     color: #fefefe;
4     border-color: #ed33
5 }

  2).HSL()函数

A).hsl($hue,$saturation,$lightness)   用色相、饱和度、亮度值创建一个颜色

代码语言:javascript复制
 div{
    color: hsla(200,30%,60%,.8)
}
代码语言:javascript复制
1  hsl(200,30%,60%) >>#7aa3b8
2 //通过h200,s30%,l60%创建一个颜色#7aa3b8

B).hsla($hue,$saturation,$lightness,$alpha)   用色、饱、亮、透明度创建一个颜色

代码语言:javascript复制
 hsla(200,30%,60%,.8)>>rgba(122, 163, 184, 0.8)
//通过h200,s30%,l60%,a80%创建一个颜色rgba(122, 163, 184, 0.8)

C).hue($color) 从一个颜色中获取色相(hue)值

代码语言:javascript复制
hue(#7ab)>> 195deg
//得到#7ab颜色的色相值195deg

D).saturation($color) 从一个颜色中获取饱和度(saturation)值

代码语言:javascript复制
1  saturation(#7ab)>>33.33333%
2 //得到#7ab颜色的饱和度值33.33333%

E).lightness($color) 从一个颜色中获取亮度(lightness)值

代码语言:javascript复制
1 lightness(#7ab)>> 60%
2 //得到#7ab颜色的亮度值60%

F).adjust-hue($color,$degrees)

这个是通过调整颜色的色相换算一个新颜色。

他需要一个颜色和色相度数值。通常这个度数值是在 -360deg 至 360deg 之间,当然了可以是百分数.

按照美术的色彩轮盘来推测:如果度数值设置为360%/-360%,那么结果都将是$color颜色本身。

代码语言:javascript复制
1 $bgcolor: #f46;
2 
3 .btn{
4     background-color: $bgcolor;
5     border-color: adjust-hue($bgcolor, 360%);
6 }

css:

代码语言:javascript复制
1 .btn {
2 
3   background-color: #f46;
4 
5   border-color: #ff4466; }

这里有一个很有意思的地方,在 HSL 颜色表达方式上,色相是从 -360 和 360 之间,负值逆时针转,正值顺时针转。在这个实例中,原色的色相值约 356deg,加上 30deg 后,新颜色变成了 386deg,但我们的色盘中并没有比 360deg 更大的值,此时新颜色的值也并不会是386deg,那将怎么办呢?

其实很简单,当值大于 360deg时,表示色盘转完了一圈,继续顺时针转余下的值(这里是 26deg),那么这个继续转的值就是新颜色的色相值。反之,得到的负数值也是一样的道理。

G).lighten($color,$amount) 提亮亮度,让颜色变亮得到新颜色

代码语言:javascript复制
1  lighten(#f36,50%)>>#ffffff
2  //把#f36颜色亮度提高50% 十六进制即为 #ffffff

这个其实结果是white,编译成英文的颜色单词

实例:

首先定义一个颜色变量:

代码语言:javascript复制
1 $baseColor: #ad141e;

使用 lighten() 和 darken() 函数来修改 10% 的亮度值:

代码语言:javascript复制
//SCSS
代码语言:javascript复制
1 .lighten {
2     background: lighten($baseColor,10%);
3 }
4 .darken{
5     background: darken($baseColor,10%);
6 }

编译出来的 css 代码:

代码语言:javascript复制
//CSS
代码语言:javascript复制
1 .lighten {
2   background: #db1926;
3 }
4 
5 .darken {
6   background: #7f0f16;
7 }

H).darken($color,$amount) 降低亮度,让颜色变暗得到新颜色

代码语言:javascript复制
1 darken(#f36,50%)>> #33000d
2  //把#f36颜色亮度降低50%#33000d

lighten() 和 darken() 函数只是在原始颜色的基础上对亮度值进行运算操作,但是生成出来的新颜色在色相和饱和度会有略微的变化,

不管什么颜色当其亮度值 趋近于0时,颜色会越来越暗,直到变成了黑色;反之,当其亮度值趋近于 100% 时,颜色会越来越亮,直到变成了白色。

但当使用 lighten() 和 darken() 函数对一个颜色的亮度值计算时,会碰到两个极端,lighten() 函数会让新颜色的亮度值超过 100%,而 darken() 函数会让新颜色的亮度值低于 0 变成负数。

可实际上任何颜色的亮度值都在 0~100% 之间,如此一来,Sass 的 lighten() 和 darken() 函数又将会如何处理呢?

上面的例子说明了一切问题。当颜色的亮度值接近或大于 100%,颜色会变成白色;反之颜色的亮度值接近或小于 0 时,颜色会变成黑色。

I).saturate($color,$amount) 增加颜色饱和度,返回新颜色

代码语言:javascript复制
1 saturate(#f36,50%) >> #ff3366
2 //把#f36颜色饱和度提高50%#ff3366

J).desaturate($color,$amount) 降低颜色饱和度,返回新颜色

代码语言:javascript复制
1  desaturate(#f36,50%)>>#cc667f
2  //把#f36颜色饱和度降低50%#cc667f

saturate()、desaturate()这两个函数是通过改变颜色的饱和度来得到一个新的颜色

代码语言:javascript复制
//SCSS
代码语言:javascript复制
1 $baseColor: #ad141e;
2 .saturate {
3   background: saturate($baseColor,30%); //在原色饱和度基础上增加饱和度
4 }
5 .desaturate {
6   background: desaturate($baseColor,30%);//在原色饱和度基础上减少饱和度
7 }

编译出来的 css 代码:

代码语言:javascript复制
//CSS
代码语言:javascript复制
1 .saturate {
2   background: #c1000d;
3 }
4 
5 .desaturate {
6   background: #903137;
7 }

用 saturation() 函数在终端中进行计算一下

代码语言:javascript复制
>> saturation(#ad141e) //原色的饱和度
79.27461%
>> saturation(#c1000d)  //在原色饱和度基础上增加30%,超过100%时按100%计算
100%
>> saturation(#903137) //在原色饱和度基础上减少30%,小于0时按0计算
49.2228%

K).grayscale($color) 将颜色变灰色,即将颜色的饱和度值直接调至 0%  === desaturate($color:100%);

grayscale() 函数处理过的颜色,其最大的特征就是颜色的饱和度为 0。

代码语言:javascript复制
1 grayscale(#f36)>> #999999
2  //把#f36颜色变成灰色#999999

这个函数能将彩色颜色转换成不同程度的灰色。

代码语言:javascript复制
//SCSS
代码语言:javascript复制
1 $baseColor: #ad141e;
2 .grayscale {
3   background: grayscale($baseColor);
4 }
5 .desaturate {
6   background: desaturate($baseColor,100%);
7 }

编译出来的 css 代码:

代码语言:javascript复制
//CSS
代码语言:javascript复制
1 .grayscale {
2   background: #616161;
3 }
4 .desaturate {
5   background: #616161;
6 }

L).complement($color) 返回一个补充色,相当于adjust-hue($color,180deg)

代码语言:javascript复制
1  complement(#f36)>>#33ffcc

M).invert($color) 返回反相色,红绿蓝色值倒过来,而透明度不变。

代码语言:javascript复制
1  invert(#f36)>>#00cc99

如图,把红色变成了绿色,也就是常说的对比色。

   3).Opacity函数

A).alpha($color)/opacity($color):获取颜色的透明度值

与 red(),green() 等函数很类似。这个函数的主要功能是用来获取一个颜色的透明度值。值在0-1之间

如果颜色没有特别指定透明度,那么这两个函数得到的值都会是 1:

代码语言:javascript复制
1 >> alpha(red)
2 1
3 >> alpha(rgba(red,.8))
4 0.8
5 >> opacity(red)
6 1
7 >> opacity(rgba(red,.8))
8 0.8

$color也可以用变量代替

代码语言:javascript复制
 1 $color: blue;
 2 $color2:rgba(blue,.5);
 3 $color3:blue;
 4 $color4:rgba(blue,.5);
 5 div{
 6     color: alpha($color);
 7     color: alpha($color2);
 8     color: opacity($color3);
 9     color: opacity($color4);
10 }
代码语言:javascript复制
1 div {
2   color: 1;
3   color: 0.5;
4   color: 1;
5   color: 0.5; }

B).rgba($color,$alpha):改变颜色的透明度值

同前面介绍 RGB 函数中,rgba() 函数

其可以创建一个颜色,同时还可以对颜色修改其透明度。

其可以接受两个参数,第一个参数为颜色,第二个参数是你需要设置的颜色透明值。

代码语言:javascript复制
 1 >> rgba(red,.5)
 2 rgba(255, 0, 0, 0.5)
 3 >> rgba(#dedede,.5)
 4 rgba(222, 222, 222, 0.5)
 5 >> rgba(rgb(34,45,44),.5)
 6 rgba(34, 45, 44, 0.5)
 7 >> rgba(rgba(33,45,123,.2),.5)
 8 rgba(33, 45, 123, 0.5)
 9 >> rgba(hsl(33,7%,21%),.5)
10 rgba(57, 54, 50, 0.5)
11 >> rgba(hsla(33,7%,21%,.9),.5)
12 rgba(57, 54, 50, 0.5)

C).opacify($color,$amount)/fade-in($color,$amount):使颜色更不透明;

两个函数会让透明值做加法运算,(所以最后透明度的值,要看原颜色值的透明度加上这个函数的透明度参数值之后的结果)

两个参数,第一个参数是原始颜色,第二个参数是你需要增加的透明度值

其取值范围主要是在 0~1 之间。

当透明度值增加到大于 1 时,会以 1 计算,表示颜色不具有任何透明度。

几种不同的写法如下($color值这里,可以传入不同的颜色值rgb、hsl、16进制等)

代码语言:javascript复制
 1 >> opacify(rgba(22,34,235,.6),.2)
 2 rgba(22, 34, 235, 0.8)
 3 >> opacify(rgba(22,34,235,.6),.5)
 4 #1622eb
 5 >> opacify(hsla(22,34%,23%,.6),.15)
 6 rgba(79, 53, 39, 0.75)
 7 >> opacify(hsla(22,34%,23%,.6),.415)
 8 #4f3527
 9 >> opacify(red,.15)
10 #ff0000
11 >> opacify(#89adde,.15)
12 #89adde
13 >> fade-in(rgba(23,34,34,.5),.15)
14 rgba(23, 34, 34, 0.65)
15 >> fade-in(rgba(23,34,34,.5),.615)
16 #172222

其中 fade-in( ) 函数又名 fade_in() 函数。其所起作用等效。

D).transparentize($color,$amount)/fade-out($color,$amount):使颜色更加透明

让颜色更加的透明。这两个函数会让透明值做减法运算,(所以最后透明度的值,要看原颜色值的透明度减去这个函数的透明度参数值之后的结果)

当计算出来的结果小于 0 时会以 0 计算,表示全透明

代码语言:javascript复制
 1 >> transparentize(red,.5)
 2 rgba(255, 0, 0, 0.5)
 3 >> transparentize(#fde,.9)
 4 rgba(255, 221, 238, 0.1)
 5 >> transparentize(rgba(98,233,124,.3),.11)
 6 rgba(98, 233, 124, 0.19)
 7 >> transparentize(rgba(98,233,124,.3),.51)
 8 rgba(98, 233, 124, 0)
 9 >> fade-out(red,.9)
10 rgba(255, 0, 0, 0.1)
11 >> fade-out(hsla(98,6%,23%,.5),.1)
12 rgba(58, 62, 55, 0.4)
13 >> fade-out(hsla(98,6%,23%,.5),.6)
14 rgba(58, 62, 55, 0)

 三、@规则

Sass支持css3的所有@则

代码语言:javascript复制
1.@import

2.@media

3.@extend

4.@at-root

5.@debug

6.@warn

7.@error

1.@import

1).  css中的@import规则延展

A).两大作用:

  a.引入外部css文件;(注意与link的区别:http://www.cnblogs.com/zbo/archive/2010/11/17/1879590.html)
  b.根据媒体查询,判断屏幕分辨率以视情况的引入对应的css文件
  c.在css中的@import语法:http://caibaojian.com/css3/rules/@import.htm

@import <url> <media_query_list>

<media_query_list>:[<media_query>[',' <media_query>]*]?

<media_query>:[only | not]? <media_type> [and <expression>]* | <expression> [and <expression>]*

<expression>:'('<media_feature>[:<value>]?')'

<url>:使用绝对或相对地址指定导入的外部样式表文件。可以是url(url)或者直接是一个url

<media_query_list>:指定媒体类型和查询条件。

B).指定导入的外部样式表及目标媒体。

  • 该规则必须在样式表头部最先声明。并且其后的分号是必需的,如果省略了此分号,外部样式表将无法正确导入,并会生成错误信息。
  • IE使用@import无法引入超过35条的样式表。
  • 当使用url(url)的方式时,包住路径的引号可有可无;当直接使用url时,包住路径的引号必须保留。
代码语言:javascript复制
1 @import url("global.css");
2 @import url(global.css);
3 @import "global.css";

C).兼容性:

  1. IE7及更早浏览器不支持@import指定媒体类型和媒体查询。
  2. IE8不支持@import指定媒体查询。

D)html中的使用示例:

代码语言:javascript复制
1 <html lang="zh-cn">
2 <head>
3 <meta charset="utf-8" />
4 <title>CSS @import详解-CSS教程</title>
5 <meta name="author" content="Joy Du(飘零雾雨), dooyoe@gmail.com, www.doyoe.com" />
6 <style>
7 @import url("style.css") screen, print;
8 </style>
9 </head>

@import url(style.css) 和@import url("style.css")是最优的选择,兼容的浏览器最多。从字节优化的角度来看@import url(style.css)最值得推荐

2).  sass中的@import

  a.可以用来引入SCSS和Sass文件

  所有引入的 SCSS 和 Sass 文件都会被合并并输出一个单一的 CSS 文件。

  另外,被导入的文件中所定义的变量或 mixins 都可以在主文件中使用

  Sass会在当前目录下寻找其他Sass文件

但是,有些情况下,@import会被误导并编译成css代码

  b.以下是@import会被编译成css代码的情况:(使用css原生@import的既定规则)

  • 如果文件的扩展名是 .css。
    •   (当@import后边跟的文件名是以.css结尾的时候)【类似示例代码第一条】
  • 如果文件名以 http:// 开头。
    •   (当@import后边跟的是http://开头的字符串的时候)【类似示例代码第三条】
  • 如果文件名是 url()。
    •   (当@import后边跟的是一个url()函数的时候)【类似示例代码第四条】
  • 如果 @import 包含了任何媒体查询(media queries)。
    •   (当@import后边带有media queries的时候)【类似示例代码第二条】

比如:

代码语言:javascript复制
1 @import "foo.css";
2 @import "foo" screen;
3 @import "http://foo.com/bar";
4 @import url(foo);
代码语言:javascript复制
1 //将被编译为:
2 @import "foo.css";
3 @import "foo" screen;
4 @import "http://foo.com/bar";
5 @import url(foo);

如果没有出现上述情况,就可以用来做“引入”功能

  c.@import根据文件名引入,一定要分号结尾

  •   默认,他寻找Sass文件并引入,也可以一个import引入多个文件
  •   条件是:文件的扩展名是.sass或者.scss;
  •   如果没有扩展名,Sass将试着找出具有.sass或.scss扩展名的同名文件并将其引入:
  • 所以,同一目录下(文件夹中),局部文件(带下划线的文件名)和非局部文件不能重名。
代码语言:javascript复制
1 @import "foo.scss";

代码语言:javascript复制
1 @import "foo";

都将引入foo.scss文件。

  •   一个 @import 引入多个文件。逗号隔开。例如:
代码语言:javascript复制
1 @import "rounded-corners", "text-shadow";

将引入 rounded-corners 和 text-shadow 两个文件。

  •   文件名前面加一个下划线,就能避免被编译

如果你有一个 SCSS 或 Sass 文件需要引入, 但是你又不希望它被编译为一个 CSS 文件,

这时,你就可以在文件名前面加一个下划线,就能避免被编译。 这将告诉 Sass 不要把它编译成 CSS 文件。

然后,你就可以像往常一样引入这个文件了,而且还可以省略掉文件名前面的下划线。

例如,你有一个文件叫做 _colors.scss。 这样就不会生成 _colors.css 文件了, 而且你还可以这样做:

代码语言:javascript复制
1 @import "colors";//不用加下划线

来引入 _colors.scss 文件。

  •   注意,在同一个目录不能同时存在带下划线和不带下划线的同名文件

。 例如, _colors.scss 不能与 colors.scss 并存。

  d.嵌套@import

虽然大部分时间只需在顶层文件使用 @import 就行了, 但是,你还可以把他们包含在 CSS 规则 和 @media 规则中。

示例:

假设要引入的样式文件`example.scss`文件中包含这样的代码:

代码语言:javascript复制
1 .example {
2   color: red;
3 }

然后这样引用:

代码语言:javascript复制
1 #main {
2   @import "example";
3 }

编译出来的 CSS:

代码语言:javascript复制
1 #main .example {
2   color: red;
3 }

 2.@media

Sass 中的 @media 指令和 CSS 的使用规则一样的简单,

但它有另外一个功能,可以嵌套在 CSS 规则中。

嵌套功能有点类似 JS 的冒泡功能一样,如果在样式中使用 @media 指令,它将冒泡到外面(跑到样式的最外层,不再被嵌套)

这也是sass中的@media和css中的区别:

sass中的@media query可以内嵌在css规则(代码、选择器)中,

不过在编译输出最后的css文件

他会被提出来,从选择器的嵌套中提到样式的最高层级。、

如示例:

a.嵌套选择器

代码语言:javascript复制
1 .sidebar {
2   width: 300px;
3   @media screen and (orientation: landscape) {
4     width: 500px;
5   }
6 }

编译出来:不再嵌套在.sidebar中,而是自己作为做高级别的选择器放在了外边。.sliderbar选择器自动放进@media设定的条件限制里边。

代码语言:javascript复制
1 .sidebar {
2   width: 300px; }
3 @media screen and (orientation: landscape) {
4    .sidebar {
5       width: 500px; } }

好处:避免了重复书写选择器,避免了打乱样式表的流程。

b.嵌套@media

代码语言:javascript复制
1 @media screen {
2   .sidebar {
3     @media (orientation: landscape) {
4       width: 500px;
5     }
6   }
7 }

此时编译出来:

代码语言:javascript复制
1 @media screen and (orientation: landscape) {
2   .sidebar {
3     width: 500px; } }

c. 使用插值#{}来插入变量

代码语言:javascript复制
1 $media: screen;
2 $feature: -webkit-min-device-pixel-ratio;
3 $value: 1.5;
4 
5 @media #{$media} and ($feature: $value) {
6   .sidebar {
7     width: 500px;
8   }
9 }

编译出来的 CSS:

代码语言:javascript复制
@media screen and (-webkit-min-device-pixel-ratio: 1.5) {
  .sidebar {
    width: 500px; } }

d. 嵌套到@mixin中

然后调用:

代码语言:javascript复制
.cont{

  @include col-sm();

}

生成结果:

代码语言:javascript复制
1 @media (min-width: 768px){
2 
3   .cont{
4 
5     width: 50%;
6     float: left;
7   }
8 
9 }

  3.@extend

@extend用来扩展/继承 选择器占位符

代码语言:javascript复制
 1 .error {
 2   border: 1px #f00;
 3   background-color: #fdd;
 4 }
 5 .error.intrusion {
 6   background-image: url("/image/hacked.png");
 7 }
 8 .seriousError {
 9   @extend .error;
10   border-width: 3px;
11 }
代码语言:javascript复制
1 .error, .seriousError {
2   border: 1px #f00;
3   background-color: #fdd; }
4 
5 .error.intrusion, .seriousError.intrusion {
6   background-image: url("/image/hacked.png"); }
7 
8 .seriousError {
9   border-width: 3px; }
代码语言:javascript复制
.seriousError得到的样式之所以是加了如下三个:
代码语言:javascript复制
 border: 1px #f00;background-color: #fdd;background-image: url("/image/hacked.png");
但是鉴于和.error与.error.intrusion的一致。所以到了css里就都一样了。
代码语言:javascript复制
扩展选择器:
代码语言:javascript复制
@extend不仅扩展类选择器,还可以扩展任何选择器,比如.spechial.cool,a.hover,a.user[href^="http://"],
代码语言:javascript复制
.hoverlink {
  @extend a:hover;
}
a:hover {
  text-decoration: underline;
}
代码语言:javascript复制
1 a:hover, .hoverlink {
2   text-decoration: underline; }

再来看一个类名复杂点的:

代码语言:javascript复制
1 .hoverlink {
2   @extend a:hover;
3 }
4 .comment a.user:hover {
5   font-weight: bold;
6 }

编译出来的CSS

代码语言:javascript复制
1 .comment a.user:hover, .comment .user.hoverlink {
2   font-weight: bold; }
代码语言:javascript复制
这种会突然想不明白为什么结果是这样,你可以先想一下如果没用sass这样的代码你要怎么写选择器。然后慢慢就想通了
实在想不通就用实验说明问题吧

多个扩展:多次使用@extend来调用

 所设某个样式要继承多个地方的样式,那么可以使用 @extend 来继承多个选择器或占位符的样式

代码语言:javascript复制
 1 .a{
 2     width: 200px;
 3 }
 4 .b{
 5     height: 300px;
 6 }
 7 .c{
 8     @extend .a;
 9     @extend .b;
10 }
代码语言:javascript复制
1 .a, .c {
2   width: 200px; }
3 .b, .c {
4   height: 300px; }

扩展单一选择器

代码语言:javascript复制
1 .c %no{
2     width: 1000px;
3 }
4 .b{
5     @extend %no
6 }
代码语言:javascript复制
.c .b, .c .c {

  width: 1000px; }

但是,@extend有两个不可以:

1.不可以继承选择器序列

如.a .b{}就不能继承

.c{

  @extend .a .b;//这种写法是错误的

}

类似的报错:

2.继承并使用单一选择器%(占位符)

%选择器——仅用来继承的选择器,若不用,他不会被编译出现在css文件中

  4.@at-root

@at-root 从字面上解释就是跳出根元素。

当你选择器嵌套多层之后,想让某个选择器跳出,此时就可以使用 @at-root。来看一个简单的示例:(自我感觉多余这一步,要跳出直接重新开一个选择器不得了。。)

代码语言:javascript复制
 1 .a {
 2   color: red;
 3 
 4   .b {
 5     color: orange;
 6 
 7     .c {
 8       color: yellow;
 9 
10       @at-root .d {
11         color: green;
12       }
13     }
14   }  
15 }
代码语言:javascript复制
.a {
  color: red;
}

.a .b {
  color: orange;
}

.a .b .c {
  color: yellow;
}

.d {
  color: green;
}

  5.@debug

@debug 在 Sass 中是用来调试的,

当你的在 Sass 的源码中使用了 @debug 指令之后,Sass 代码在编译出错时,在命令终端会输出你设置的提示 Bug

//@debug还可以做数学运算

指的是,你在@debug中设置sass的数学运算,最后编译出错时,得到的是运算的结果:

代码语言:javascript复制
1 @debug 10em   12em;
2 
3 @debug 54px   86px;
代码语言:javascript复制
1 ./8804/F9mR/index.scss:1 DEBUG: 22em
2 
3 ./8804/F9mR/index.scss:3 DEBUG: 140px

  6.@warn

@warn 和 @debug 功能类似,用来帮助我们更好的调试 Sass。如:

在sass中,有时候编译不出来东西他也不报错,你自己就很难纠错。那么可以借助@if和@warn来挑错

代码语言:javascript复制
 1 @mixin adjust-location($x, $y) {
 2   @if unitless($x) {//unitless是内置函数,判断数值是否有“单位”
 3     @warn "Assuming #{$x} to be in pixels";
 4     $x: 1px * $x;
 5   }
 6   @if unitless($y) {
 7     @warn "Assuming #{$y} to be in pixels";
 8     $y: 1px * $y;
 9   }
10   position: relative; left: $x; top: $y;
11 }
12 .botton{
13     @include adjust-location(20px, 30);
14 }
代码语言:javascript复制
 1 WARNING: Assuming 30 to be in pixels
 2 
 3          on line 7 of ./8805/F9mR/index.scss, in `adjust-location'
 4 
 5          from line 16 of ./8805/F9mR/index.scss
 6 
 7 
 8 
 9 .botton {
10 
11   position: relative;
12 
13   left: 20px;
14 
15   top: 30px; }

  7.@error

同@warn和@debug,同样用来提示开发者错误的

代码语言:javascript复制
 1 @mixin error($x){
 2   @if $x < 10 {
 3     width: $x * 10px;
 4   } @else if $x == 10 {
 5     width: $x;
 6   } @else {
 7     @error "你需要将#{$x}值设置在10以内的数";
 8   }
 9 
10 }
11 
12 .test {
13   @include error(15);
14 }
代码语言:javascript复制
1 Error: 你需要将15值设置在10以内的数
2 
3         on line 7 of ./8806/F9mR/index.scss, in `error'
4 
5         from line 13 of ./8806/F9mR/index.scss
6 
7   Use --trace for backtrace.

更多sass教程

 W3c教程网:http://www.w3cplus.com/sassguide/syntax.html

github:https://github.com/sass/sass

sass官网:http://sass-lang.com/

慕课网:http://www.imooc.com/learn/436

。。。

sass部分函数及其功能结构图

右击“在新标签页打开图片”——来查看大图。。。

0 人点赞