Sass的使用
1、在Vue项目中使用Sass
用 vue-cli 生成的 Vue 项目,在项目中使用 Sass 需要安装两个依赖包:
//安装下面的包时可能会报错,此时可以使用 cnpm 淘宝镜像进行安装 cnpm install node-sass --save-dev cnpm install sass-loader --save-dev //node-sass和sass-loader的版本过高可能会有各种奇奇怪怪的问题。亲测,以下版本可配合 node8.11.1使用 //最好先装node-sass,否则可能会有问题 cnpm install node-sass@4.14.1 --save-dev cnpm install sass-loader@7.3.1 --save-dev
然后修改 webpack.base.config.js 文件,修改 module 下的 rules :
module: { rules: [ ... { test: /\.scss$/, loaders: ["style", "css", "sass"] } ... ] }
在 vscode 中使用 sass 语法可能会提示语法错误,但是编译运行都没问题,此时修改 vscode 的设置:先安装vetur插件,在vscode的设置中添加: "files.associations": { "*.vue": "vue" }
1.2、sass 的特性介绍
sass
的语法完全兼容css
,所以我们可以把css
文件直接改名为.scss
后缀,并且可以用来直接导入。
2、Sass 的基本语法
2.1、变量
在sass中
你可以把反复使用的css
属性值定义成变量,然后通过变量名来引用它们,而无需重复书写这一属性值。
2.1.1、变量声明及使用
sass
使用 $ 符号来标识变量。任何可以用作css
属性值的赋值都可以用作sass
的变量值,甚至是以空格分割的多个属性值,如$basic-border: 1px solid black;
,或以逗号分割的多个属性值。
变量可以在css
规则块定义之外声明,也可以在规则块之内声明。当变量定义在css
规则块内,那么该变量只能在此规则块内使用。
$nav-color: #F90; $plain-font: "Myriad Pro"、Myriad、"Helvetica Neue"、Helvetica、"Liberation Sans"、Arial和sans-serif; sans-serif; nav { $width: 100px; //此时的width 变量只能在这个规则块内使用 width: $width; color: $nav-color; }
在声明变量时,变量值也可以引用其他变量。
$highlight-color: #F90; $highlight-border: 1px solid $highlight-color; .selected { border: $highlight-border; }
sass 的变量名可以使用中划线 - 或者下划线 _ 命名,sass
并不强迫一定要使用中划线或下划线,所以这两种用法都相互兼容。甚至用中划线声明的变量可以使用下划线的方式引用,反之亦然。
2.2、嵌套规则
在sass中可以不用重复写选择器,sass允许在规则块中嵌套规则块
#content { background-color: #f5f5f5; article { h1 { color: #333 } p { margin-bottom: 1.4em } } aside { background-color: #EEE } } /* 编译后 */ #content {background-color: #f5f5f5;} #content article h1 { color: #333 } #content article p { margin-bottom: 1.4em } #content aside { background-color: #EEE }
2.2.1、父选择器标识符(&)
用 & 符号放在嵌套规则中可以表示嵌套规则的父选择器
article h1 { color: blue; &:hover { color: red } } /*编译后*/ article a { color: blue } article h1:hover { color: red } /* 表示 h1 hover变红色 */ /* 如果不使用&符号则可能表示的会是另一种意思 */ /* 下面的sass代码表示article元素内 h1 的所有子元素被hover时都会变成红色,而不是h1元素 */ article h1 { color: blue; :hover { color: red } }
在嵌套规则中,& 符号表示的就是父选择器,在 & 选择器之前也可以添加选择器。
#content aside { color: red; body.ie & { color: green } } /*编译后*/ #content aside {color: red}; body.ie #content aside { color: green }
2.2.2、群组选择器的嵌套
.container { h1, h2, h3 {margin-bottom: .8em} } /* 编译后 */ .container h1, .container h2, .container h3 { margin-bottom: .8em }
你需要特别注意群组选择器的规则嵌套生成的css,
虽然sass
让你的样式表看上去很小,但实际生成的css
却可能非常大,这会降低网站的速度。
2.2.3、子组合选择器和同层组合选择器:>、+ 和 ~
article { ~ article { border-top: 1px dashed #ccc } > section { background: #eee } dl > { dt { color: #333 } dd { color: #555 } } nav + & { margin-top: 0 } } /* 编译后 */ article ~ article { border-top: 1px dashed #ccc } article > footer { background: #eee } article dl > dt { color: #333 } article dl > dd { color: #555 } nav + article { margin-top: 0 }
2.2.4、属性嵌套
属性嵌套指的是在CSS规则中把属性名从中划线 - 的地方断开,在根属性后边添加一个冒号:,紧跟一个{ }
块,把子属性部分写在这个{ }
块中。
nav { border: { style: solid; width: 1px; color: #ccc; } } /* 编译后 */ nav { border-style: solid; border-width: 1px; border-color: #ccc; }
对于属性的缩写形式,你甚至可以像下边这样来嵌套,指明例外规则:
nav { border: 1px solid #ccc { left: 0px; right: 0px; } } /* 编译后 */ nav { border: 1px solid #ccc; border-left: 0px; border-right: 0px; }
3、如何导入SASS文件
css
有一个特性,即@import
规则(非常不常用),它允许在一个css
文件中导入其他css
文件。然而,在只有执行到@import
时,浏览器才会去下载其他css
文件,这会导致页面加载起来变慢,因为这样你会需要加载几个css文件。
sass
也有一个@import
规则,但不同的是,sass
的@import
规则在生成css
文件时就把相关文件导入进来。这意味着所有相关的样式被归纳到了同一个css
文件中,而无需发起额外的下载请求。并且被导入文件中定义的所有变量和混合器均可在导入文件中使用。
使用sass
的@import
规则并不需要指明被导入文件的全名。你可以省略.sass
或.scss
文件后缀,比如:
/* index.scss文件 */ h1 { color: red; } /* 导入语句不要漏了后面的分号';' ,否则有可能会报错 */ @import './index'; /* 导入index.scss文件 */ .hello h1{ &:hover { color: red; } }
3.1、导入sass局部文件
用下划线开头 _ 命名的 scss 文件,代码在编译时并不会将这些文件编译为单独的 css 文件,我们把这样的 scss 文件称之为局部文件。其他的 scss 文件在编译时应该每个都会被编译成单独的 css 文件(未验证过)。
我们可以在局部文件中写入一些用来给其他文件导入的样式及变量等,而且它们并不会被编译成单独的 css 文件。在@import
一个 scss 局部文件时,可以省略文件名开头的下划线。比如想导入 '_common.scss' 文件,可以这样写: @import './common';
3.2、默认变量值
可以用 !default 来声明一个默认变量,如果没有重复声明的话,用户使用该变量就会使用默认值。但是如果被重复声明赋值,该默认变量值就会被覆盖掉。
$link-color: blue !default;; $link-color: red; a { color: $link-color; /*color会被赋值为red*/ }
3.3、嵌套导入
sass
允许 @import
命令写在css
规则内,在这种导入方式下,被导入的局部文件中定义的所有变量和混合器,只会在这个规则范围内生效,而不会全局生效。
/* blue.scss文件 */ aside { background: blue; color: white; } /* 导入 */ .blue { @import "blue.scss" } /* 编译后 */ .blue { aside { background: blue; color: #fff; } }
3.4、原生的CSS导入
通常在sass
中使用@import
时,sass
会尝试找到对应的sass
文件并导入进来。但是在 sass 中也可以导入 css 文件,在下列三种情况下,sass 会将 @import 命令认为是导入 css 文件,这会造成浏览器额外的下载。
- 被导入文件的名字以
.css
结尾; - 被导入文件的名字是一个URL地址(比如http://www.sass.hk/css/css.css),由此可用谷歌字体API提供的相应服务;
- 被导入文件的名字是
CSS
的url()值。
4、静默注释
css
中的注释是对用户可见的,在sass中
另外提供了一种语法即静默注释,该语法不同于css
标准注释格式/* ... */
,并且其注释的内容不会出现在生成的css
文件中。以 // 开头的注释语法即为静默注释,跟javascript注释语法一样。
body { color: #333; // 这种注释内容不会出现在生成的css文件中 padding: 0; /* 这种注释内容会出现在生成的css文件中 */ }
5、混合器(@mixin、@include)
使用sass
的混合器可以实现大段样式的重用,混合器使用@mixin
标识符定义,这个标识符可以给一段样式命名,然后我们就可以通过@include
引用这个名字来重用这段样式。
//定义 @mixin aaa { -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; } //引用 notice { background-color: green; @include aaa; } //sass最终生成: .notice { background-color: green; -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }
混合器中不仅可以包含属性,同时也可以包含css
规则,包含选择器和选择器中的属性等
@mixin no-bullets { list-style: none; //混合器中使用属性 li { //混合器中使用元素选择器 list-style-image: none; list-style-type: none; margin-left: 0px; } } //导入 ul.plain { color: #444; @include no-bullets; } //相当于 ul.plain { color: #444; list-style: none; li { list-style-image: none; list-style-type: none; margin-left: 0px; } }
5.1、给混合器传参
混合器并不一定总得生成相同的样式。可以通过在@include
混合器时给混合器传参,来定制混合器生成的精确样式。当@include
混合器时,参数就是css
属性值,混合器的这种特性跟 javascript 中的 function 类似。
//声明 @mixin link-colors($normal, $hover, $visited) { color: $normal; &:hover { color: $hover; } &:visited { color: $visited; } } //使用 a { @include link-colors(blue, red, green); } //Sass最终生成的是: a { color: blue; } a:hover { color: red; } a:visited { color: green; }
sass 还允许通过语法 $name: value 的形式指定每个参数的值,这种形式的传参,就可以不必在乎参数的顺序了,只需要保证没有漏掉参数即可
a { @include link-colors( $normal: blue, $visited: green, $hover: red ); }
5.2、混合器默认参数
在混合器中,我们可以给参数指定默认的属性值。参数默认值使用 $name: value 的声明形式,默认值可以是任何有效的 css 属性值,或者是其他参数的引用。
@mixin link-colors( $normal, $hover: red, $visited: $normal ) { color: $normal; &:hover { color: $hover; } &:visited { color: $visited; } }
6、选择器继承(@extend)
使用选择器继承 @extend 可以在一个选择器中继承另一个选择器定义的所有样式。
.error { border: 1px solid red; background-color: #fdd; } //通过选择器继承继承样式 .seriousError { @extend .error; border-width: 3px; }
上面的代码会使得以class="seriousError"
修饰的 html 元素最终的展示效果是class="seriousError error"
注意:上面中的.seriousError
不仅会继承.error
自身的所有样式,任何跟.error
有关的组合选择器样式也会被.seriousError
以组合选择器的形式继承
.error a{ //将也会影响.seriousError a color: red; } h1.error { //将也会影响hl.seriousError font-size: 1.2rem; } //使用继承后class="seriousError"的所有元素内的 h1 标签和超链接也会变成红色和粗体。 .seriousError { @extend .error; }
6.1、继承元素标签的样式
实际上,@extend 不仅可以继承类的样式,同样也可以继承元素标签的的样式
a { color: green; } //继承 a 标签的样式 .panel { @extend a; }
6.2、sass继承的原理
sass 中继承实际上是在每个被继承的类处添加需要继承的类名,以使得样式对两个类名都起作用。
.seriousError{ @extend .error; } //使用继承后,样式表中的任何一处.error都用.error, .seriousError这一选择器组进行替换。 .error { color: red; } //将会被替换为 .error, .seriousError { color: red; } .error a{ color: red; } //将会被替换为 .error a, .seriousError a{ color: red; }
注意:应避免用复杂选择器(比如.a .b这种有后代选择器的)去使用继承,那样会使得在一个CSS规则中的选择器的个数变得非常大,代码也变得艰涩难懂。