SCSS 是 Sass 3 引入新的语法,其语法完全兼容 CSS3,并且继承了 Sass 的强大功能。也就是说,任何标准的 CSS3 样式表都是具有相同语义的有效的 SCSS 文件

SCSS

传统的css文件缺失变量等概念,导致需要书写的重复的代码很多,但css中不存在变量函数等概念,这时发现的一个css的预编译利器——scss

1.使用变量

SCSS中的变量以$开头

1
2
3
4
5
$border-color:#aaa; //声明变量
.container {
$border-width:1px;
border:$border-width solid $border-color; //使用变量
}

上述例子中定义了两个变量,其中$border-color在大括号之外称为全局变量,顾名思义任何地方都可以使用,$border-width是在.container之内声明的,是一个局部变量,只有.container内部才能使用。

编译后:

1
2
3
.container {
border:1px solid #aaa; //使用变量
}

tips:SCSS中变量名使用中划线或下划线都是指向同一变量的,上文中定义了一个变量$border-color,这时再定义一个变量$border_color:#ccc,他们指向同一个变量,.container的值会被第二次定义的变量覆盖。

1
2
3
4
5
6
7
8
9
10
11
$border-color:#aaa; //声明变量
$border_color:#ccc;
.container {
$border-width:1px;
border:$border-width solid $border-color; //使用变量
}
编译后的CSS
.container {
border:1px solid #ccc; //使用变量
}

这个例子中我们要知道

(1)变量名使用中划线或下划线都是指向同一变量的。

(2)先定义的变量声明会被忽略,但赋值会被执行。

2.嵌套规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*css*/
.container ul {
border:1px solid #aaa;
list-style:none;
}

.container ul:after {
display:block;
content:"";
clear:both;
}

.container ul li {
float:left;
}

.container ul li>a {
display:inline-block;
padding:6px 12px;
}

在这个例子中写了很多重复的代码,.container写了很多遍,下面将用SCSS简写上面的例子

2.1嵌套选择器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*scss*/
.container ul {
border:1px solid #aaa;
list-style:none;

li {
float:left;
}

li>a {
display:inline-block;
padding:6px 12px;
}
}

.container ul:after {
display:block;
content:"";
clear:both;
}

这里我们可以将公共的父元素提取出来。

2.2嵌套中的父级选择器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*scss*/
.container ul {
border:1px solid #aaa;
list-style:none;

li {
float:left;
}

li>a {
display:inline-block;
padding:6px 12px;
}

&:after {
display:block;
content:"";
clear:both;
}
}

父级选择器中需要注意,只能在嵌套内部使用父级选择器,否则SCSS找不到父级元素会直接报错

2.3嵌套组合选择器

在嵌套规则中可以写任何css代码,包括群组选择器(,),子代选择器(>),同层相邻组合选择器(+)、同层全体组合选择器(~)等等,下面继续将自带选择器简化掉。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*scss*/
.container ul {
border:1px solid #aaa;
list-style:none;

li {
float:left;

>a {
display:inline-block;
padding:6px 12px;
}
}

&:after {
display:block;
content:"";
clear:both;
}
}

2.4嵌套属性

1
2
3
4
5
6
7
/*css*/
li {
border:1px solid #aaa;
border-left:0;
border-right:0;
}

这个例子中我们只需要两条边框,使用SCSS重写一遍。

1
2
3
4
5
6
7
8
/*scss*/
li {
border:1px solid #aaa {
left:0;
right:0;
}
}

scss识别一个属性以分号结尾时则判断为一个属性,以大括号结尾时则判断为一个嵌套属性,规则是将外部的属性以及内部的属性通过中划线连接起来形成一个新的属性。

3.导入SCSS文件

大型项目中css文件往往不止一个,css提供了@import命令在css内部引入另一个css文件,浏览器只有在执行到@import语句后才会去加载对应的css文件,导致页面性能变差,故基本不使用。

SCSS中的@import命令跟原生的不太一样

3.1导入变量的优先级问题-变量默认值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*App1.scss*/
$border-color:#aaa; //声明变量
@import App2.scss; //引入另一个SCSS文件
.container {
border:1px solid $border-color; //使用变量
}

/*App2.scss*/
$border-color:#ccc; //声明变量




/*生成的css文件*/
.container {
border:1px solid #ccc; //使用变量
}

有时候我们希望引入的某些样式不更改原有的样式,这时我们可以使用变量默认值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*App1.scss*/
$border-color:#aaa; //声明变量
@import App2.scss; //引入另一个SCSS文件
.container {
border:1px solid $border-color; //使用变量
}
/*App2.scss*/
$border-color:#ccc !default; //声明变量



/*生成的css文件*/
.container {
border:1px solid #aaa; //使用变量
}

导入的文件App2.scss只在文件中不存在$border-color时起作用,若App1.scss中已经存在了$border-color变量,则App2.scss中的$border-color不生效。

!default只能使用在变量中。

3.2嵌套导入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*App1.scss*/
$border-color:#aaa; //声明变量
.container {
@import App2.scss; //引入另一个SCSS文件
border:1px solid $border-color; //使用变量
}
/*App2.scss*/
$border-color:#ccc !default; //声明变量
p {
margin:0;
}




/*生成的css文件*/
.container {
border:1px solid #aaa; //使用变量
}
.container p {
margin:0;
}

可以看得出来,就是将App2.scss中的所有内容直接写入到App1.scss的.container选择器中。

3.3 使用原生@import

前面我们说到基本不使用原生@import,但某些情况下我们不得不使用原生@import时了,SCSS也为我们处理了这种情况,直接导入css文件即可。

1
@import 'App.css';

4.注释

SCSS中的注释有两种

(1)/* 注释 */ 这种注释会被保留到编译后的css文件中。

(2)// 注释 这种注释不会被保留到编译后生成的css文件中。

5.混合器(函数)

5.1声明一个函数

使用@mixin指令声明一个函数,看一下自己的css文件,有重复的代码片段都可以考虑使用混合器将他们提取出来复用。

1
2
3
4
5
6
@mixin border-radius{
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
color:red;
}

混合器作用域内的属性都是return的值,除此之外,还可以为函数传参数。

1
2
3
4
5
6
@mixin get-border-radius($border-radius,$color){
-moz-border-radius: $border-radius;
-webkit-border-radius: $border-radius;
border-radius: $border-radius;
color:$color;
}

也可以设置混合器的默认值。

1
2
3
4
5
6
@mixin get-border-radius($border-radius:5px,$color:red){
-moz-border-radius: $border-radius;
-webkit-border-radius: $border-radius;
border-radius: $border-radius;
color:$color;
}

5.2使用函数

使用函数的关键字为@include

1
2
3
4
5
6
7
8
9
10
11
.container {
border:1px solid #aaa;
@include get-border-radius; //不传参则为默认值5px
@include get-border-radius(10px,blue); //传参
}
/*多个参数时,传参指定参数的名字,可以不用考虑传入的顺序*/
.container {
border:1px solid #aaa;
@include get-border-radius; //不传参则为默认值5px
@include get-border-radius($color:blue,$border-radius:10px); //传参
}

我们可能会想到,直接将混合器写成一个class不就行了,但是写成一个class的时候是需要在html文件中使用的,而使用混合器并不需要在html文件中使用class既可达到复用的效果。

tips:混合器中可以写一切scss代码。

6.继承

6.1定义被继承的样式

1
2
3
4
5
6
%border-style {
border:1px solid #aaa;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}

使用%定义一个被继承的样式,类似静态语言中的抽象类,他本身不起作用,只用于被其他人继承。

6.2继承样式

通过关键字@extend即可完成继承。

1
2
3
4
5
6
7
.container {
@extend %border-style;
color:red;
}
.container1 { //继承另一个选择器
@extend .container;
}

上述例子中看不出混合器与继承之间的区别,那么下一个例子可以看出继承与混合器之间的区别。

1
2
3
4
5
6
7
8
.container {
@extend %border-style;
color:red;
}
.container1 { //继承另一个选择器
@extend .container;
}

7.操作符

SCSS提供了标准的算术运算符,例如+、-、*、/、%。

1
2
3
4
/*SCSS*/
width: 600px / 960px * 100%;
/*编译后的CSS*/
width: 62.5%;