一 css预处理是什么
css是描述性语言,不能像js使用编程式方法写,变量、循环。运算等无法使用。css预处理解决了这个问题,可以编程式写css,写变量、循环、函数等。术语是这样,但其实就是更简单的css书写格式,常见的有3种:Sass/Less/stylus。
今天主要讲清楚Sass
二 Sass和Less的区别
这俩是目前应用最广的,语法类似,区别如下: 1. 底层实现语言不同:Sass是Ruby实现,编译时在服务端处理;Less是js编写,编译时在浏览器处理; 2. Sass功能更强大:Sass有循环、函数、混合宏等;Less没有; 3. Sass有框架可以辅助开发,如Compass,Less没有; 4. 因此Sass在国内外讨论更多,使用更多;
三 Sass和Scss的语法格式
Sass有2种语法格式:Sass和Scss。我更偏向于用Scss,语法跟css相近,而Sass的语法与Ruby相近。
Sass语法格式:
相似Ruby,严格的缩进。
Scss语法格式:
相似css,{}和;
1. 变量
变量的来源可以是css中定义的,也可以是js中的。js中可以是data里的,也可以是标签内:style定义的,或者是父组件内定义后子组件直接引用。
(1. 变量声明
用color:red,调用:color: $color; `
color:red !default;顾名思义,默认值可以被同名变量覆盖。
(2. 变量作用域
类似js的变量作用域,有全局和局部。局部比如说选择器内,混合宏内,继承样式内等。例:一个同名变量,全局和局部都有,优先调用局部的。
$width: 100px;
div{
$width: 200px;
width: $width;
}
* 解析为200px,选择器内的局部变量
(3. 变量的值可以有7种
- 数字:也可结合css单位,例1.5,10px,50%等;
- 字符串:css内的字符串同等拿过来设置就可,有无引号跟css值保持一致。如bold,"黑体";
- 布尔值:跟@if...@else一起使用;
- 颜色值,类似css的关键字、rgba、16进制等颜色格式;
- 列表:变量值可以是list,例margin的4个值就是空格隔开的list;font-family是,隔开的list;
- map值:键值对,在这里语法是(key1:val1, kay2:val2, key3:val3)
2.插值,#{}
其实还是变量的使用,只是用来表示名称等,加个#{}做区分。
在“选择器名”、"属性名"、“属性值”中插入一个变量值,而构成一个新选择器名,离nth-child($i),常见用法。可结合循环@for使用
@for $i 1through 3 {
nth-child(#{$i}){
border-width: $ipx
}
}
3. 嵌套
3种嵌套方式都比较常用:选择器、属性、伪类,使用方便简单非常好。但是考虑到解析难度,一般控制在3层内。
// 1.最常见的选择器嵌套
.wrap{
...
.nav{
...
}
}
// 2.属性嵌套,可减少一定的代码书写量,一定记得冒号:
div{
...
margin:{
top: 10px;
right: 0;
bottom: 0;
left: 10px;
}
}
// 3.伪类、伪元素嵌套,结合&:符号,也常用
div{
color: $color;
&:hover{
color: $red
}
}
4.注释
3种常见注释格式都行:
1. // ...
2. /* ... */
3. /*! ... */
5.基本运算
css有计算属性calc,但是能做的有限。Sass提供了类似js的各种运算。有3种运算形式:数字、字符、颜色。
(1.数字运算
类似js,数字可以加减乘除,可以带单位,但是单位要相同,否则报错Incompatible units。
$width: 100px;
// 1. 加减法一样简单。
div{
width: $width + 20px; //120px
}
// 2.乘法理解为一个值的n倍,所以倍数n不能带单位。
div{
width: ($width * 2); //200px
width: ($width * 2px); // 报错200px*px isn't a valid CSS value
}
@for $i 1through 3{
.item_#{$i}{
width: 10px * $i;
}
}
// 3.除法的语法格式是/,但是因为这个“/”在css中常用作其他意义,所以常量计算要加()
div{
height: (100px / 2); //常量计算
height: $width / 2; //变量计算可以不加()
}
(2.字符运算,也就是拼接
as is known to all,scss里的字符串存在有无引号两种情况,那么拼接后有无引号?不管右边有无引号,跟随左边的引号情况。
(3.颜色运算
As we know, scss里的颜色支持多种写法,解析器会转为16进制颜色后计算:
color: #010203 + # 040506;
color: #010203 * 2;
color: (rgba(17, 32,34) * 2);
6.代码重用
这个很好用,传统css会有很多重复代码,我们只能通过提取公共样式复用。scss里提供了3种复用手段,更加灵活:
- 继承@extend
- 占位符%placeholder
- 混合宏@mixin
(6.1 scss继承
使用@extend继承一个样式块。继承的解析,是要添加继承人的;混合宏是要混入到下面的引用块里。
.box{
width: 100px;
height: 100px;
}
.box_1{
@extend .box;
color: red;
}
// 解析后,相当于给.box代码块增加并列选择器,如下:
.box, .box_1{
width: 100px;
height: 100px;
}
.box_1{
color: red;
}
(6.2 Sass占位符placeholder
占位符%可进一步优化extend,不是取代,而是配合extend使用。
%btn{
padding: 6px 10px;
font-size: 14px;
}
.btn_1{
@extend %btn;
color: red;
}
// 解析后,如果没用到的类名会自动省略,如下:
.btn_1{
padding: 6px 10px;
font-size: 14px;
}
.btn_1{
color: red;
}
//综上,占位符%什么时候使用?看是否需要保留基类%btn
(6.3 Sass的混合宏
混合宏@mixin可以定义一个要复用的代码块——混合宏,@include调用混合宏。
应对特殊情况,比如设置border,兼容各浏览器需要加浏览器前缀,且border的值我们希望是参数形式传入设置,那么,有“混合宏的参数”,参数可以是1-n个,数量不限制,参数匹配规则与js类似,也可以带默认值。
@mixin border_mixin($myBorder){
border: $myBorder;
-webkit-border: $myBorder;
-moz-border: $myBorder;
}
@mixin width_mixin($width:20px){
width: $width;
}
#nav{
color: red;
@include border_mixin(1px solid red);
}
.btn{
@include border_mixin(2px solid blue)
}
//编译后:
#nav{
color: red;
border: 1px solid red;
-webkit-border: 1px solid red;
-moz-border: 1px solid red;
}
7. 判断语句@if、@else
类似js的if、else if、else的规则。
@isScroll ($boolean:flase){
@if $boolean{
overflow: scroll;
}
@else {
overflow: hidden;
}
}
.box{
height: 200px;
@include isScroll(true)
}
8. @for循环
同类似js的for规则,很适合网格样式使用。2种写法:through和to。
to表示不包含end,through包含end。
@for $i from [start] to [end]
// 1 to 3 =>1,2
@for $i from [start] through [end]
// 1 through 3 => 1,2,3
9. @while循环
只要while后边的判断是true就会一直执行,适用于>n等情况。
$num: 3;
@while $num > 0 {
.box_#{$num}{
height: 20px;
}
$num: $num - 1
}
// .box_3,2,1
10. @each循环
写法:@each $el in [list]。什么时候用呢?
//比如10张不同背景图
$list: img1, img2, img3;
@each $name in $list{
.#{$name}{
background: url("images/#{$name}.png");
}
}
//可以结合@mixin混入、@extend继承
四 webpack中的sass-loader做什么的
sass-loader是帮助webpack打包sass文件,把scss转换为标准的css书写格式。先把文件内的文本格式转换为常见css格式,并支持相应的优化和扩展;然后css-loader根据各文件依赖关系,整合成一段css,然后给style-loader去挂载到页面的head。