# SCSS 简明上手
# 1. 关于 SCSS
众所周知,CSS 并不是编程语言,用它开发网页的样式是比较麻烦的,因为它没有变量,也没有语句,只有一条条单纯的描述。为了方便开发,『CSS 预处理器』被设计出来,它的思想是使用一种编程语言进行样式的开发,之后再转换成 CSS,以供使用。
Sass 就是一种 CSS 预处理器,而 Scss 则是它的进阶版。
使用 Sass/Scss 可以轻松地编写出清晰、无冗余、语义化的 CSS ,这是因为:
Sass/Scss 提供了变量。通过变量可以让 CSS 的值变得可复用;
Sass/Scss 支持嵌套。嵌套规则让 CSS 内可以继续嵌套 CSS,减少 CSS 重复的选择器,同样使得样式表的结构更加清晰;
Sass/Scss 还提供了样式导入。可以将分散在多个 Sass 文件中的内容合并到一个 CSS 文件中,避免了大量使用原生 CSS 中 @import 性能问题,保持了 CSS 的整洁和可维护性。
在 Sass 之后,出了名为 Less 的预处理器,它更加简单且兼容 CSS,在 Ruby 社区之外的支持者远超过 Sass,不过,它的编程功能要弱于 Sass 。就是受 Less 的影响和挑战,Sass 才推出了 Scss,也全面兼容 CSS 。
无论是 Sass 还是 Scss ,在 vue-cli 中都是 node-sass 和 sass-loader 在进行编译处理。
# 2. 变量
变量用来存储需要在 CSS 中复用的信息,例如颜色和字体。Sass/Scss 通过 $
符号去声明一个变量。
$active-color: #F90; // 定义 $active-color 变量
$active-border: 1px solid $active-color; // 定义 $active-border 变量
.active {
color: $active-color; // 使用 $active-color 变量
border: $active-border; // 使用 $active-border 变量
};
编译后,上述例子中变量的变量将会被它们的值替换:
.active {
color: #F90;
border: 1px solid #F90;
}
在上述代码中,Scss 使用 $
来定义变量,使用 :
连接变量的值,变量的值也可以是一连串的属性,像上面的 $active-border
变量一样,使用时直接在属性后接上变量名即可,经过转译就会变成标准的 CSS 样式。
注意,变量名使用『串型命名法』和『下划线命名法』都可以,而且两者通用,即,可以使用 $active_color
和 $active_border
来调用变量。不过,根据 CSS 默认规则,推荐使用串型命名法。
# 3. @mixin
变量还有一个进阶版规则:混合器(mixin)。简单来说,就是一个包含着很多属性的变量。
@mixin rounded-corners { // 构建 rounded-corners 圆角混合器
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}
.notice {
background-color: pink;
border: 4px solid #00aa00;
@include rounded-corners; // 调用 rounded-corners 圆角混合器
}
编译后,上述 scss 代码将会变为:
.notice {
background-color: pink;
border: 4px solid #00aa00;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
}
使用 @mixin 来给混合器命名,使用 @include 加混合器名来调用混合器。
# 4. 嵌套
Sass/Scss 允许开发人员以嵌套的方式使用 CSS,这样可以减少重复的 CSS 选择器的书写。
下面的例子表达了一个典型的网站导航样式:
nav {
ul {
margin: 0;
padding: 0;
list-style: none;
}
li {
display: inline-block;
}
a {
display: block;
padding: 6px 12px;
text-decoration: none;
}
}
大家注意上面代码中的 ul
、li
、a
选择器都被嵌套在 nav
选择器当中使用,这是一种书写更高可读性 CSS 的良好方式,编译后产生的 CSS 代码如下:
nav ul {
margin: 0;
padding: 0;
list-style: none;
}
nav li {
display: inline-block;
}
nav a {
display: block;
padding: 6px 12px;
text-decoration: none;
}
Scss 允许 CSS 规则嵌套使用,父子规则将会呈现包含选择器的关系,例如:
/*===== SCSS =====*/
#main p {
color: #00ff00;
width: 97%;
.redbox {
background-color: #ff0000;
color: #000000;
}
}
上述代码会被编译成如下形式:
/*===== CSS =====*/
#main p {
color: #00ff00;
width: 97%;
}
#main p .redbox {
background-color: #ff0000;
color: #000000;
}
这样可以避免重复的使用父级选择器,从而达到简化 CSS 代码结构的目的,例如:
/*===== SCSS =====*/
#main {
width: 97%;
p, div {
font-size: 2em;
a { font-weight: bold; }
}
pre { font-size: 3em; }
}
上述代码会被编译成如下形式:
/*===== CSS =====*/
#main {
width: 97%;
}
#main p, #main div {
font-size: 2em;
}
#main p a, #main div a {
font-weight: bold;
}
#main pre {
font-size: 3em;
}
# 5. 引用父级选择器 &
Scss 使用 &
关键字在 CSS 规则中引用父级选择器,例如在嵌套使用伪类选择器的场景下:
/*===== SCSS =====*/
a {
font-weight: bold;
text-decoration: none;
&:hover { text-decoration: underline; }
body.firefox & { font-weight: normal; }
}
/*===== CSS =====*/
a {
font-weight: bold;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
body.firefox a {
font-weight: normal;
}
无论 CSS 规则嵌套的深度怎样,关键字 &
都会使用父级选择器级联替换全部其出现的位置:
#main {
color: black;
a {
font-weight: bold;
&:hover { color: red; }
}
}
/*===== CSS =====*/
#main {
color: black;
}
#main a {
font-weight: bold;
}
#main a:hover {
color: red;
}
&
必须出现在复合选择器开头的位置,后面再连接自定义的后缀,例如:
/*===== SCSS =====*/
#main {
color: black;
&-sidebar { border: 1px solid; }
}
/*===== CSS =====*/
#main {
color: black;
}
#main-sidebar {
border: 1px solid;
}
如果在父级选择器不存在的场景使用 &
,Scss 预处理器会报出错误信息。
# 6. @import 文件导入
与 CSS 自带的 @import 不同,Sass/Scss 的 @import 会在生成 CSS 时将引入的文件直接打包成一个 CSS 文件,无须发起额外的请求。所以,一般可以将不同作用的 .sass/.scss 文件分开写,最后引入一个文件中,在项目中只需调用最后引入所组建的文件即可:
// main.scss 文件内容
@import "./others/xxx.scss"; // 引入不同功能的 .scss 文件
@import "./others/yyy.scss";
@import "./others/zzz.scss";
如果不同文件中有同名的变量,Sass/Scss 会取最后一个变量使用。
← 组件通信