Sass笔记
简介
- Sass是一款强化CSS的辅助工具,它在CSS语法的基础上增加了变量 (variables)、嵌套 (nested rules)、混合 (mixins)、导入 (inline imports) 等高级功能
- sass从第三代开始,放弃了缩进式风格,并且完全向下兼容普通的css代码,这一代的sass也被称为scss
使用方法
- 我使用的WebStorm编辑器,用它写scss不太理想。第一点输出css文件路径,如何配置,我是真的不懂。第二点安装autoprefixer插件,如何配置,同样不懂,感觉自己有点蠢(´-ω-`)
- 换成VSCode吧,安装Live Sass Compiler插件,它是scss预处理器用来编译成css文件,如果你见到两个相同名字的插件,老版本v3.0.0已经停止更新,当前新版本是v5.5.1,总之选最新版的就对了
- 另外,再安装个Autoprefixer插件,它是用来辅助Live Sass Compiler插件,帮助你生成兼容前缀,比如万恶的IE,你不需要亲自写兼容前缀了,Autoprefixer插件会帮你做这件事
- 两个插件完毕后,开始配置吧,首先打开Live Sass Compiler插件扩展设置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34{
"liveSassCompile.settings.formats":[
/*
nested:嵌套格式
expanded:展开格式
compact:紧凑格式
compressed:压缩格式
*/
{
//定制输出css样式(nested、expanded、compact、compressed)
"format": "expanded",
"extensionName": ".css",
//~是当前路径
"savePath": "~/../css"
},
],
//排除目录
"liveSassCompile.settings.excludeList": [
"**/node_modules/**",
".vscode/**"
],
//是否生成对应的map文件
"autoprefixer.formatOnSave": true,
//是否添加兼容前缀,例如:-webkit- -moz-等
"liveSassCompile.settings.autoprefix": [
"> 1%",
"last 2 versions"
],
//下面这些是VSCode设置出来的,我希望编辑器字体很大,tab缩进2个空格...
"files.autoSave": "onFocusChange",
"editor.fontSize": 21,
"editor.tabSize": 2,
"liveSassCompile.settings.compileOnWatch": false
} - 打开Autoprefixer插件扩展设置,勾选这一行Autoprefixer: Format On Save(保存文件时向Css添加兼容前缀)
- 测试时,在项目中创建scss、css文件夹,并在scss文件夹内创建test.scss文件,点击最下方菜单栏Watch Sass开始监听文件,test.scss写入样式保存后,看是否生成test.css文件,最后打开看是否有兼容前缀
- 学习过程中,不想见到兼容前缀暂时关闭插件即可
语法扩展
选择器嵌套
- scss允许将一套CSS样式嵌套进另一套样式编译后
1
2
3
4
5
6
7#left{
width: 100px;
height: 100px;
a{
color: #fff;
}
}1
2
3
4
5
6
7#left {
width: 100px;
height: 100px;
}
#left a {
color: #fff;
}
父选择器
- 如果不想写父选择器,可以用&符号替代,自动识别父选择器编译后
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#left {
width: 100px;
height: 100px;
a {
color: #fff;
&:hover {
color: #f08a5d;
}
}
.top {
border: 1px #f2f2f2 solid;
&-left {
width: 200px
}
}
}1
2
3
4
5
6
7
8
9
10
11
12#left a {
color: #fff;
}
#left a:hover {
color: #f08a5d;
}
#left .top {
border: 1px #f2f2f2 solid;
}
#left .top-left {
width: 200px;
}
属性嵌套
- 属性嵌套:不错,看起来很直观编译后
1
2
3
4
5
6
7p {
font: {
size: 24px;
family: serif;
weight: bolder;
}
}1
2
3
4
5p {
font-size: 24px;
font-family: serif;
font-weight: bolder;
}
占位符选择器%name
- 占位符选择器:没有调用占位符时,它是隐藏的,直到使用
@extend %name;
调用,它才会显示,顺便说一下%后面的名字可以自定义编译后1
2
3
4
5
6
7
8
9
10
11
12
13
14%ulan {
font-size: 24px;
color: #000;
}
.a {
@extend %ulan;
width: 50px;
}
.b {
@extend %ulan;
height: 50px;
}1
2
3
4
5
6
7
8
9
10
11
12.b, .a {
font-size: 24px;
color: #000;
}
.a {
width: 50px;
}
.b {
height: 50px;
}
变量
定义规则
- 变量以美元符号($)开头,后面跟变量名
- 变量名是不以数字开头的可包含字母、数字、下划线、横线(连接符)
- 写法同css,即变量名和值之间用冒号(:)分隔
- 变量一定要先定义,后使用
连接符与下划线
- 连接符与下划线定义的同名变量是一样的,建议使用连接符
1
2
3
4
5$font-size: 14px;
$font_size: 16px;
.ulan {
font-size: $font-size; /* 16px */
}
全局与局部
- 全局变量定义在选择器外部,局部变量定义在选择器内部,其他选择器无法访问局部变量
1
2
3
4
5
6
7
8
9
10
11
12
13
14/* 全局 */
$p14: 14px;
.ulan {
/* 局部 */
$white: #fff;
color: $white;
font-size: $p14;
}
.jintao {
color: $white; /* 报错,变量white未定义 */
font-size: $p14;
} - 如果你希望其他选择器能访问局部变量,可以写
!global
1
2
3
4
5
6
7
8.ulan {
$white: #fff !global;
color: $white;
}
.jintao {
color: $white;
}
变量值类型
- 主要6种数据类型
- 数值:1、2、10px
- 字符串:有引号字符串与无引号字符串
- 颜色:blue、#fff、rbga(255, 0, 0)
- 布尔:true、false
- 空值:null
- 数组:用空格或逗号作分隔符
- maps:相当于js的object(key1: value1, key2: value2)编译后
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30// 数值
$layer-index: 10;
$border-width: 3px;
// 字符串or数组
$font-base-family: 'Microsoft YaHei', Helvetica, Sans-Serif;
// 颜色
$top-bg-color: rgba(255, 147, 29, 0.6);
// 布尔
$blank-mode: true;
// 空值
$var: null;
// maps
$color-map: (color1: #6a2c70, color2: #b83b5e, color3: #f08a5d);
$fonts: (yahei: 'Microsoft YaHei', Helvetica: 'Helvetica');
.container {
@if $blank-mode {
background-color: #6a2c70;
}
@else {
background-color: #b83b5e;
}
content: type-of($var) length($var);
color: map-get($color-map, color2);
}
.wrap {
// 如果没有sans键,生成的css将忽略空值
font: 18px bold map-get($fonts, 'sans');
}1
2
3
4
5
6
7
8
9.container {
background-color: #6a2c70;
content: null 1;
color: #b83b5e;
}
.wrap {
font: 18px bold;
}
默认值
- 这个功能有点鸡肋啦,我会使用默认值,通常是担心覆盖掉老样式,但你设置的新样式又用不了;如果是使用老样式直接调用,某天想用新样式了直接覆盖,所以默认值的意义在哪?
1
2
3
4
5
6
7$color: #333;
$color: #666 !default;
$p24: 24px !default;
p {
color: $color; // #333
font-size: $p24; // 24px
}
导入规则
scss导入方式
- 新建
_base.scss
文件,添加下划线可以防止生成css文件1
2$p14: 14px;
$red: #fc5185; - 同目录
test.scss
文件,导入base文件,不添加下划线、后缀名,照样能识别编译后1
2
3
4
5@import "base";
p {
font-size: $p14;
color: $red;
}1
2
3
4p {
font-size: 14px;
color: #fc5185;
} - 作为局部导入,另一边没有导入base文件的选择器,它会报错
1
2
3
4
5
6
7
8
9
10
11p {
@import "base";
font-size: $p14;
color: $red;
}
// 下面报错,未定义$p14和$red
div {
font-size: $p14;
color: $red;
}
css导入方式
- 以下几种方式,都将作为普通css语句
- 文件后缀名是.css
- 文件名以http://开头
- 文件名是url()
- @import包含media queries
1
2
3
4@import "public.css";
@import "http://xxx.com/xxx";
@import url(public);
@import "landscape" screen and (orientation: landscape);
混合指令@mixin
- 第一种用法,通过
@mixin name
定义重复使用的样式,接着用@include name
引入到选择器内,如果name过长建议使用-连接编译后1
2
3
4
5
6
7
8
9
10@mixin block-ulan {
width: 96%;
margin-left: 2%;
border-radius: 8px;
border: 1px #f6f6f6 solid;
}
.container {
@include block-ulan;
}1
2
3
4
5
6.container {
width: 96%;
margin-left: 2%;
border-radius: 8px;
border: 1px #f6f6f6 solid;
} - 第二种用法,批量传参编译后
1
2
3
4
5
6
7
8
9
10@mixin flex-align($aitem) {
-webkit-box-align: $aitem;
-webkit-align-items: $aitem;
-ms-flex-align: $aitem;
align-items: $aitem;
}
.container {
@include flex-align(center);
}1
2
3
4
5
6.container {
-webkit-box-align: center;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
} - 第三种用法,形参设置默认值,使用参数时建议加上默认值
1
2
3
4
5
6
7@mixin block-padding($top: null, $right: null, $bottom: null, $left: 40px) {
padding: $top $right $bottom $left;
}
.container {
@include block-padding(10px, 20px, 30px)
} - 第四种用法,剩余参数,这里的1指下标项1编译后
1
2
3
4
5
6
7
8@mixin linear-gradient($direction, $gradients...) {
background-color: nth($gradients, 1);
background-image: linear-gradient($direction, $gradients);
}
.container {
@include linear-gradient(to right, #ffffd2, #fcbad3, #aa96da)
}1
2
3
4.container {
background-color: #ffffd2;
background-image: linear-gradient(to right, #ffffd2, #fcbad3, #aa96da);
} - 混入总结
- mixin是可以重复使用的一组CSS声明
- 混合指令可以包含所有的CSS规则,绝大部分scss规则,甚至通过参数功能引入变量,输出多样化的样式
- 使用参数时建议加上默认值
继承@extend
- 儿子继承父亲样式,由于哥哥已经继承了父亲样式,这时弟弟在去继承哥哥样式,同时拥有两人的样式编译后
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15.father {
width: 100px;
height: 100px;
background-color: #aa96da;
}
.son-a {
@extend .father;
font-size: 24px;
}
.son-b {
@extend .son-a;
font-weight: bold;
}1
2
3
4
5
6
7
8
9
10
11
12
13.father, .son-a, .son-b {
width: 100px;
height: 100px;
background-color: #aa96da;
}
.son-a, .son-b {
font-size: 24px;
}
.son-b {
font-weight: bold;
} - 占位符选择器、混合指令、继承,他们三个都能实现同样效果,该如何选择呢?
- 占位符选择器:它适合写公共样式,由于占位符隐藏特性,编译出来的代码量较少
- 混合指令:它跟占位符选择器很相似,缺点是编译出来的代码量超多
- 继承:它也跟占位符选择器很相似,但会多出一个选择器,编译出来的代码量较少
- 总结:父选择器拥有的样式,可以提供给子选择器,毫无疑问用继承;在没有父选择器提供样式情况下,使用占位符选择器,更加合理,实在不行就用混合指令
scss运算符
等号操作符
- 等于写法
1
2
3
4
5
6
7
8
9$theme: 1;
.container {
@if $theme == 1 {
background-color: #000; // 执行
}
@else {
background-color: #fff;
}
} - 不等于写法,也可以叫取反
1
2
3
4
5
6
7
8
9$theme: "black";
.container {
@if $theme != "black" {
background-color: #000;
}
@else {
background-color: #fff; // 执行
}
}
关系运算符
>
or<
,>=
or<=
1
2$theme: 3;
@if $theme >= 5
逻辑运算符
- and:逻辑与
- or:逻辑或
- not:逻辑非编译后
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17$width: 100;
$height: 200;
$index: 10;
div {
@if $width > 50 and $height < 300 {
font-size: 24px;
}
@else {
font-size: 18px;
}
@if not ($index > 5) {
border-color: #000;
}
@else {
border-color: #fff;
}
}1
2
3
4div {
font-size: 24px;
border-color: #fff;
}
数字操作符
加运算
1
2
3
4
5
6
7
8
9.container {
width: 50 + 20;
width: 50 + 20%;
width: 50% + 20%;
width: 20 + 10px;
width: 10px + 20px;
width: 10px + 10pt; // 23.3333333333px
//width: 20% + 10px;
}减运算
1
2
3
4
5
6
7
8
9.container {
width: 50 - 30;
width: 50 - 30%;
width: 60% - 30%;
width: 20px - 10px;
width: 50px - 20pt; // 23.3333333333px
width: 50px - 20;
//width: 50px - 10%;
}乘运算
1
2
3
4
5
6
7.container {
width: 10 * 20;
width: 5 * 10%;
//width: 50% * 10%;
//width: 10px * 20px;
width: 10px * 2;
}除运算
1
2
3
4
5
6
7
8
9.container {
$width: 100px;
width: 10 / 5; // width: 10/5; 这里识别成斜杠
width: (10 / 5);
width: $width / 10;
width: round($number: 50) / 2;
width: 10px / 2px + 3px; // 8px
width: 10px / 2 + 3px;
}以下三种情况/将被视为除法运算符
- 如果值或值的一部分,是变量或函数的返回值
- 如果值被圆括号包裹
- 如果值是算数表达式的一部分
求余运算
1
2
3
4
5
6
7
8
9
10
11
12.container {
width: 10 % 3;
width: 50 % 3px;
width: 50px % 3px;
width: 50px % 7;
width: 50% % 7; // 1%
width: 50% % 9%; // 5%
//width: 50% % 10px;
width: 50px % 10pt; // 50px % 13.3333333333px
width: 50px + 10pt; // 10pt == 13.3333333333px
width: 50px % 13.3333333333px; // 10.0000000001px
}字符串拼接
1
2
3
4
5
6.container {
content: "foo" + bar; // "foobar"
content: foo + "bar"; // foobar
content: foo + bar; // foobar
content: "foo" + "bar"; // "foobar"
}
插值语句
- 插值写法
#{name}
,name通常为变量;用了插值语法不会触发除法运算符1
2
3
4
5$font-size: 12px;
$line-height: 30px;
p {
font: #{$font-size} / #{$line-height} Helvetica; // font: 13px/30px Helvetica;
} - 还能设置成属性名、属性值
1
2
3
4
5$class-name: danger;
$attr: color;
a.#{class-name} {
border-#{attr}: #aa96da;
} - 甚至注释也能办得到
1
2
3
4
5$author: '幽蓝';
/*
这是文件说明部分
@author: #{$author} // @author: 幽蓝
*/
常见函数的基本使用
Color(颜色函数)
- lighten()调亮,darken()调暗,opacify()降低颜色透明度,transparent()使颜色透明度增加,mix()可用来混合两种颜色
lighten($color, $amount)
,$amount的取值在0%~100%之间darken($color, $amount)
,通常使用color.scale()代替该方案opacify(rgba($color, 0.1), 0.5)
,通常使用color.scale()代替该方案1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17$color: #00adb5;
.color01 {
background-color: $color;
}
.color02 {
background-color: lighten($color, 30%);
}
.color03 {
background-color: darken($color, 15%);
}
.color04 {
// 如果0.1和0.5这两个参数大于1,透明度效果就没了,直接恢复成原本颜色
background-color: opacify(rgba($color, 0.1), 0.5);
}
String(字符串函数)
- unquote()去掉引号,str-length()获取字符串长度,quote()向字符串添加引号,str-insert()将内容插入字符串给定位置(0表示字符串的第0项)编译后
1
2
3
4
5
6
7
8
9
10p {
background-color: unquote($string: '#aa96da');
z-index: str-length('幽蓝/ulan');
&:before {
content: quote(周杰伦);
}
&:after {
content: str-insert('七里香', '专辑名:', 0);
}
}1
2
3
4
5
6
7
8
9
10
11@charset "UTF-8";
p {
background-color: #aa96da;
z-index: 7;
}
p:before {
content: "周杰伦";
}
p:after {
content: "专辑名:七里香";
}
Math(数值函数)
- percentage()将无单元的数值转换为百分比
- round()将数字四舍五入为最接近的数字
- abs()会返回一个数的绝对值
- ceil()将一个数转换成最接近于自己的整数
- min()和max()获取几个数字中的最小值或最大值;我的WebStrom编辑器在这里会有点小bug,无法使用变量,换成VSCode可以了
- random()返回一个随机数
1 | p { |
List函数
- length()返回列表长度,index()查询位置,nth()返回列表中的特定项,join()将两个列表连接在一起,append()在列表末尾添加一个值
1
2
3
4
5
6
7p {
z-index: length(12px); // 1
z-index: length(12px 5px 8px); // 3
z-index: index(a b c d, c); // 3
color: nth($list: red blue green, $n: 2); // blue
padding: append(10px 20px, 30px); // 10px 20px 30px
}
Map函数
- map-get()根据键获取map中的对应值,map-has-key()判断是否有键,map-merge()将两个map合并成一个新的map,map-keys()映射所有键,map-values()映射所有值编译后
1
2
3
4
5
6
7
8
9
10
11$font-sizes: ('small': 12px, 'normal': 18px, 'large': 24px);
$padding: (top: 10px, right: 20px, bottom: 10px, left: 30px);
p {
font-size: map-get($font-sizes, 'normal'); // 18px
@if map-has-key($padding, 'right') {
padding-right: map-get($padding, 'right');
}
&:after {
content: map-keys($font-sizes) + ' ' + map-values($padding) + '';
}
}1
2
3
4
5
6
7p {
font-size: 18px;
padding-right: 20px;
}
p:after {
content: '"small", "normal", "large" 10px, 20px, 10px, 30px';
}
选择器函数
- selector-append()可以把一个选择符附加到另一个选择符,selector-unify()将两组选择器合成一个复合选择器
1
2
3
4
5.header {
background-color: #000;
content: selector-append('.a', '.b', '.c') + ''; // ".a.b.c"
content: selector-unify('a', '.disabled') + ''; // "a.disabled"
}
自检函数
- feature-exists()检查当前scss版本是否存在某个特性,variable-exists()检查当前作用域中是否存在某个变量,mixin-exists()检查某个mixin是否存在编译后
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15$color: #fff;
@mixin padding($top:0, $right:0, $bottom:0, $left:0) {
padding: $top $right $bottom $left;
}
.container {
@if variable-exists(color) {
color: $color;
}
@else {
content: '$color不存在';
}
@if mixin-exists(padding) {
@include padding($left: 10px, $right: 10px);
}
}1
2
3
4.container {
color: #fff;
padding: 0 10px 0 10px;
}
流程控制指令
@if控制指令
- @if()允许你根据条件进行分支,并返回两种可能的其中一种结果
- 语法方式同js的if…else if…else
@for指令
- @for指令可以在限制的范围内重复输出格式,每次按要求(变量的值)对输出结果做出变动。这个指令包含两种格式:
@for $var from<start>through<end>
@for $var from<start>to<end>
- through与to的含义
- 使用through时,条件范围包含
与 的值 - 使用to时,条件范围只包含
的值,不包含 的值 - $var可以是任何变量,比如$ulan;
与 必须是整数值 编译后1
2
3
4
5
6
7
8// 不包含4,也就是说循环3次
@for $i from 1 to 4 {
.p#{$i} {
width: 10px * $i;
height: 30px;
background-color: #aa96da;
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17.p1 {
width: 10px;
height: 30px;
background-color: #aa96da;
}
.p2 {
width: 20px;
height: 30px;
background-color: #aa96da;
}
.p3 {
width: 30px;
height: 30px;
background-color: #aa96da;
}
- 使用through时,条件范围包含
@while指令
- 同js语法没区别,别写成死循环就好编译后
1
2
3
4
5
6
7
8
9
10
11$column: 12;
$unit: '%';
@while ($column > 0) {
.col-sm-#{$column}{
// 下面两种写法效果一样,第二种写法方便修改单位
// unquote是去除字符串意思
//width: $column / 12 * 100%;
width: unquote($string: $column / 12 * 100 + $unit);
}
$column: $column - 1;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47.col-sm-12 {
width: 100%;
}
.col-sm-11 {
width: 91.6666666667%;
}
.col-sm-10 {
width: 83.3333333333%;
}
.col-sm-9 {
width: 75%;
}
.col-sm-8 {
width: 66.6666666667%;
}
.col-sm-7 {
width: 58.3333333333%;
}
.col-sm-6 {
width: 50%;
}
.col-sm-5 {
width: 41.6666666667%;
}
.col-sm-4 {
width: 33.3333333333%;
}
.col-sm-3 {
width: 25%;
}
.col-sm-2 {
width: 16.6666666667%;
}
.col-sm-1 {
width: 8.3333333333%;
}
@each指令
- 参考格式
@each $var in <list>
,$var可以是任何变量名,比如$lenght或者$name,而- 是一连串的值,也就是值列表
编译后1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18p {
width: 10px;
height: 10px;
display: inline-block;
margin: 10px;
}
$color-list: #ffffd2 #fcbad3 #aa96da #a8d8ea;
// 获取列表每项的颜色值
@each $color in $color-list {
// 用$index存数据,index表示查询$color-list的全部颜色值
$index: index($color-list, $color);
// $index-1这样写会识别成一个变量名
// $index - 1这样写会识别成减法运算符
.p#{$index - 1} {
background-color: $color;
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22p {
width: 10px;
height: 10px;
display: inline-block;
margin: 10px;
}
.p0 {
background-color: #ffffd2;
}
.p1 {
background-color: #fcbad3;
}
.p2 {
background-color: #aa96da;
}
.p3 {
background-color: #a8d8ea;
}
@function
- 定义函数
1
2
3
4@function function-name([$param1, $param2, ...]){
...
@return $value;
} - @return只允许在@function中使用,并且每个@function必须以@return结束,当遇到@return时,它会立即结束函数并返回其结果编译后
1
2
3
4
5
6
7
8
9
10@function row-cols-width($column) {
//percentage是用来转换百分比1/1就是100%
@return percentage(1 / $column);
}
@for $i from 1 through 6 {
.row-cols-#{$i} > * {
width: row-cols-width($i);
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23.row-cols-1 > * {
width: 100%;
}
.row-cols-2 > * {
width: 50%;
}
.row-cols-3 > * {
width: 33.3333333333%;
}
.row-cols-4 > * {
width: 25%;
}
.row-cols-5 > * {
width: 20%;
}
.row-cols-6 > * {
width: 16.6666666667%;
} - 看一些奇淫技巧,按照key进行传参编译后
1
2
3
4
5
6
7
8@function background-linear-gradient($direction, $start-color, $end-color: #a8d8ea) {
@return linear-gradient($direction, $start-color, $end-color)
}
body {
// 默认参数不说了,都懂,主要看传递参数,位置顺序无所谓,返回结果时自动排序
background-image: background-linear-gradient($start-color: #aa96da, $direction: to right);
}1
2
3body {
background-image: linear-gradient(to right, #aa96da, #a8d8ea);
} - 剩余参数几乎跟js一样,定义方式
$name...
,同样是放在参数末尾,以…形式接受剩余的参数;我的WebStorm编辑器在这里会有小小bug,width: min($padding...)
里面加了变量无法编译,换成VSCode解决了;另外,计算变量最小、最大值要加上…不然会报错1
2
3
4
5
6
7
8
9
10
11
12@function lists($ulan...){
@return $ulan;
}
$a: 10px;
$b: 20px;
$c: 30px;
$d: 40px;
$padding: 50px, 30px, 80px, 30px;
.top {
margin: lists($a, $b, $c, $d); // 10px, 20px, 30px, 40px
width: min($padding...); // 30px
} - @mixin和@function区别,@mixin也能通过参数传值,主要用在重复使用上,而@function用于内部计算
三元条件函数if
- 写法
if($condition, $if-true, $if-false)
- 判断$condition,如果条件成立,则返回$if-true的结果,如果条件不成立,则返回$if-false的结果编译后
1
2
3
4
5
6
7
8
9
10
11
12$theme: 'light';
.p1{
@if($theme == 'light') {
color: #aa96da;
}
@else {
color: #a8d8ea;
}
}
.p2{
color: if($theme=='light', #aa96da, #a8d8ea);
}1
2
3
4
5
6
7.p1 {
color: #aa96da;
}
.p2 {
color: #aa96da;
}
@use也称作模块
- 从其他scss样式表加载mixin,function和变量,并将来自多个样式表的css组合在一起,@use加载的样式表被称为”模块”,多次引入只包含一次;@use也可以看作是对@import的增强
@use和@import的区别
两者重复引入相同文件,@use首先会报错,给重复文件重新命名,就不会报错,接着看合成文件,不会出现相同样式
_test01.scss文件1
2
3
4.test01 {
width: 100px;
height: 100px;
}_test02.scss文件
1
2
3
4
5
6
7.test02 {
width: 100px;
height: 100px;
}
p {
color: aquamarine;
}css.scss文件
1
2
3
4@use "test01";
// 引入相同文件
@use "test02" as t2-1;
@use "test02" as t2-2;编译后
1
2
3
4
5
6
7
8
9
10
11
12
13.test01 {
width: 100px;
height: 100px;
}
.test02 {
width: 100px;
height: 100px;
}
p {
color: aquamarine;
}@import不会报错,但合成文件会出现重复样式
1
2
3
4@import "test01";
// 引入相同文件
@import "test02";
@import "test02";编译后
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22.test01 {
width: 100px;
height: 100px;
}
.test02 {
width: 100px;
height: 100px;
}
p {
color: aquamarine;
}
.test02 {
width: 100px;
height: 100px;
}
p {
color: aquamarine;
}调用方式也不同,@use调用某个文件需要加上某个文件名,@import直接用就完事;由于篇幅太长,就不写了,直接使用其他文件定义好的变量与方法
@use写法1
2
3
4
5
6
7
8
9@use "test01";
@use "test02" as t2-1;
@use "test02" as t2-2;
body {
font-size: test01.$font-size;
//尽管是同一个文件使用方法,但因为取了别名,允许重复样式出现
@include t2-1.base(#fff); // color: #fff;
@include t2-2.base(#000); // color: #000;
}@import写法
1
2
3
4
5
6
7
8@import "test01";
@import "test02";
@import "test02";
body {
font-size: $font-size;
@include base(#fff); // color: #fff;
@include base(#000); // color: #000;
}重写默认值
@use 'opinionated' with ($black: #333);
@forward也称作导出
- 介绍:通过@forward加载一个模块的成员,并将这些成员当作自己的成员对外暴露出去,类似于es6的export,通常用于跨多个文件组织scss库
- 区别:@use和@forward很像,只是@use不能转发,而@forward可以;通常@forward用来整合文件,暴露出去,自身含有样式代码是取不到变量的,最好不要在里边写样式;@use可以在里面写样式
- 命名:通常用
文件名-*
来定义名字,嫌麻烦用简写也可以,使用方式跟@use一样,不再重复写一次了1
2//@forward 'user/global' as global-*;
@forward 'user/global' as g-*; - @forward和@use同时使用,建议@forward放上面,@use放下面
1
2@forward 'user/global' as g-*;
@use 'user/global'; - 利用hide,可以对部分进行屏蔽
@forward "src/list" hide list-reset, $horizontal-list-gap
- 重写默认值,末尾需要带上
!default
1
2
3
4@forward 'library' with (
$black: #222 !default,
$border-radius: 0.1rem !default
); - @import、@use、@forward总结
- @import别用了,你也看到弊端了,它会污染文件
- 尽量的使用@use和@forward
- 通常用@forward整合转发,这个过程可以屏蔽部分样式,也可以修改默认值
- 接着使用@use引入由@forward转发的文件
@at-root嵌套规则独立到外层
- 很单纯地进行了分离,没有任何覆盖和计算,这个功能很微妙,我想多数情况会用不到编译后
1
2
3
4
5
6
7
8
9
10
11
12article .outside {
font-size: medium;
background-color: blue;
@at-root .inside {
font-size: small;
border: 0.2rem;
}
.inside2 {
font-size: x-small;
font-weight: 400;
}
}1
2
3
4
5
6
7
8
9
10
11
12article .outside {
font-size: medium;
background-color: blue;
}
.inside {
font-size: small;
border: 0.2rem;
}
article .outside .inside2 {
font-size: x-small;
font-weight: 400;
}
总结
- 个人体验来说,webstorm写scss不太理想,vscode比较好
- 编译时生成兼容前缀,你需要进行配置,没有生效的代码行会以灰色展现
- Autoprefixer插件也能实现生成兼容前缀
- 不要忘了,用scss主要是方便维护,尽量写可维护的代码