Sass、Scss、Css关系介绍
- Sass是基于ruby的一种CSS预处理语言(可以理解成一种能生成CSS,而且语法更强大的语言),相比CSS,里面多了变量、函数等特性,更加方便了CSS样式的开发,但是由于其语法和ruby靠拢,因此在语法上和CSS也有一定的差异,为了兼容CSS,在Sass发展到3.0版本以后就推出了Scss,所以Scss就是3.0+版本的Sass,其中Sass文件后缀名为
.sass
、Scss文件后缀名为.scss
- Scss在语法上完全兼容CSS,因此你甚至可以直接将现有的CSS文件后缀名改成
.scss
就是一个Scss文件,CSS和Scss就像是C和C++的关系,后者语法上完全兼容前者,是前者的升级版,因此现在Scss越来越被广泛应用 - 本文介绍的就是3.0+版本的Sass,即Scss
安装
- 由于Sass基于ruby语言,因此首先要安装ruby,参考:
https://jingyan.baidu.com/article/5553fa827b5d7d65a23934ba.html - 安装完成后在命令行输入命令:
gem install sass
交互式命令行
如果想要测试sass代码是否正确,可以通过命令:sass -i
打开sass的交互式命令行,举例:
>sass -i
>> $a:#ffffff
#ffffff
命令行编译
一般编译时输入以下命令即可:
sass scss文件名:输出的css文件名
如果希望scss文件修改时自动编译,则输入以下命令:
sass --watch sass:css
编译模式
编译模式有分4中,分别是:
- nested:默认模型,花括号的收尾在最后一个样式后面,emmm...感觉作为默认格式有点不太习惯,可以看下面的例子:
// 命令:sass xxx.scss yyy.css ... --style nested
ul {
background: black; }
ul li {
font-size: 10px; }
- expanded:扩展模式,花括号放在最后一个样式的下一行,感觉比较符合自己的风格,举例:
ul {
background: black;
}
ul li {
font-size: 10px;
}
- compact:样式控制在一行内,举例:
ul { background: black; }
ul li { font-size: 10px; }
- compressed:压缩,举例:
ul{background:black}ul li{font-size:10px}
监听示例
sass --watch ./scss:./css --style expanded --sourcemap=none --no-cache
/** 监听scss文件夹下的内容并映射到css文件夹下,使用expanded模式编译,并且不生成map和缓存文件 **/
Sass特性
注释
有三种:
- 单行注释:
// 注释
,编译之后不会出现在CSS文件中 - 多行注释:编译之后会在CSS文件中保留(压缩模式下则不保留),格式:
/*
* xxx
* xxx
*/
- 强制注释:相比多行注释,注释内容一定会在CSS文件中保留,格式:
/*!
* xxx
* xxx
*/
变量
在Sass中可以定义变量,以供后面使用,定义的变量前面加上$
符号,举例:
$my-color: #ffffff;
ul {
background: $my-color;
}
变量里还可以引用变量,举例:
$my-color:#aaaaaa;
$my-style:$my-color;
ul {
background: $my-style;
}
interpolation
通过语法#{变量}
,可以在文件的各处引用这个变量,即使是注释里也可以!举例:
$version: 0.1;
$color: red;
$css:head;
/*
* 当前版本为:#{$version}
*/
.style-#{$css} {
background: #{$color}
}
编译结果为:
@charset "UTF-8";
/*
* 当前版本为:0.1
*/
.style-head {
background: red;
}
数据类型
number
数字,包括普通的数字还有一些加上单位的数字,比如在sass交互式命令行下输入下面语句:
>> type-of(1)
"number"
>> type-of(1px)
"number"
>> type-of(1%)
"number"
数字类型支持基本的加减乘除运算,举例:
>> 1+1
2
>> 2-1
1
>> 2*2
4
>> 2/1
2/1
// 默认除法结果按算式结果显示,如果希望以数字显示,则外面加个括号
>> (2/1)
2
>> 1px+2
3px
// 带单位也可以运算,但不能是单位不同的,如果只有一个带单位了,则按这个单位计算
>> 1px * 2px
2px*px
// 要注意单位也会参与到计算当中,所以不建议这样计算
>> 1px * 2
2px
>> (1px / 2px)
0.5
>> (1px / 2)
0.5px
string
字符串,用单引号或者双引号包起来,也可以不用引号包起来,但是不带引号的话,里面无法加空格,举例:
>> type-of('a')
"string"
>> type-of("a")
"string"
>> type-of(a)
"string"
>> type-of("a a")
"string"
// 加引号可以有空格
>> type-of(a a)
"list"
// 不加引号,中间空格会被当做分隔符,结果变成列表
>> type-of(black)
"color"
// 要注意有些名字已经被注册成内置的颜色类型数据
字符串可以通过+
号进行拼接,而如-
//
这样的符号,则会被直接拼接,但是用*
号则会报错,举例:
>> a+a
"aa"
>> a-a
"a-a"
>> a/a
"a/a"
>> a*a
SyntaxError: Undefined operation: "a times a".
bool
布尔型,有true
和false
,举例:
>> type-of(1>2)
"bool"
>> 1 > 2
false
一般布尔型是结果逻辑运算符操作的,常用的逻辑运算符有>
/<
/==
/and
/or
/not
list
列表,一组用空格、逗号或者是括号隔开的数据,举例:
>> type-of(1px solid #fff)
"list"
>> 1 2
(1 2)
>> 1, 2
(1, 2)
>> 1 2, 3 4
((1 2), (3 4))
>> (1 2)(3 4)
((1 2) (3 4))
map
就是键值对,举例:
>> (a:1,b:2)
(a: 1, b: 2)
color
颜色,一般是#
号开头,或者一些内置颜色,又或者一些能生成色彩的函数,举例:
>> type-of(#fff)
"color"
>> type-of(black)
"color"
>> type-of(rgba(255, 255, 255, 0.1))
"color"
>> type-of(darken(#fff, 0.1))
"color"
注:
可以通过type-of()
函数查看数据类型
函数
Sass当中可以使用函数来实现各种功能
内置函数
为了方便操作数据,Sass中内置了很多函数,常用的列举如下:
- abs:对数字取绝对值,举例:
>> abs(-1)
1
- round:对数字进行四舍五入
- ceil:对数字进行向上取整
- floor:对数字进行向下取整
- percentage:将数字转换成百分数
- max/min:取一组数字的最大/最小值,举例:
>> max(1, 2, 3)
3
- to-upper-case/to-lower-case:将字符串中字母全部转成大写/小写
- str-length:返回字符串的长度
- str-index:获取字符串a在字符串b中的索引(Sass中索引从1开始),不存在则返回
null
,举例:
>> str-index(abc, b)
2
>> str-index(abc, d)
null
- str-insert:往字符串中插入字符串,举例:
>> str-insert(abce, d, 4)
"abcde"
- not:对布尔值取反(参数也不一定要是布尔型),返回布尔值
- length:获取列表或者map的长度
- nth:返回列表索引对应的值,举例:
>> nth(1px 2px 3px, 2)
2px
- index:返回列表某值对应的索引,举例:
>> index(1px 2px 3px, 2px)
2
- append:往列表后面添加内容
- join:将列表合并成一个列表(可以用
space
-空格、comma
-逗号拼接),举例:
>> join(1 2, 3 4, comma)
(1, 2, 3, 4)
- map-get:根据键获取map中对应的值
- map-keys/map-values:获取map中所有的键/值
- map-has-key:判断map中时候含有某个键,举例:
>> $s:(a:1,b:2)
(a: 1, b: 2)
>> map-has-key($s, a)
true
- map-merge:合并map
- map-remove:删除map中的对应键值对,举例:
>> map-remove($s, a, b)
()
// 删除map中的键a和b
自定义函数
通过@function
指令来定义函数,通过@return
来指定返回值,举例:
$i: 5;
$j: 5;
@function add($x, $y){
@return $x + $y;
}
.style {
col {
width: add($i, $j);
}
}
编译结果为:
.style col {
width: 10;
}
嵌套选择器
举例:
ul {
background: black;
li {
font-size: 10px;
}
}
编译后的CSS代码为:
ul {
background: black;
}
ul li {
font-size: 10px;
}
嵌套时调用父选择器
对于伪类(如::hover
/:visited
等)如果直接像前面那样嵌套,那么编译后可能结果和我们想象的不一样,例如下面的代码:
a {
:hover {
background: black;
}
}
编译后的结果如下:
a :hover {
background: black;
}
那么此时由于a
和:hover
之间存在着空格,而被分析成两个选择器,结果导致样式不起作用。因此为了能够调用父类和当前嵌套的内容结合,可以使用与符号&
,举例:
a {
&:hover {
background: black;
}
}
编译结果为:
a:hover {
background: black;
}
注:
&
符号实际上就是相当于一个存放父类的变量,比如看下面的例子:
a {
& &:hover {
background: black;
}
}
编译结果为:
a a:hover {
// 可以发现&符号都被替换成了父类
background: black;
}
嵌套属性
不止是选择器,属性也可以被嵌套,比如:margin-top
/margin-bottom
/margin-left
/margin-right
都可以看做是margin
下的属性,但为了和选择器区分开来,嵌套时需要加个冒号:
,举例:
div {
margin: {
top: 10px;
bottom: 10px;
left: 15px;
right: 15px;
}
}
编译结果为:
div {
margin-top: 10px;
margin-bottom: 10px;
margin-left: 15px;
margin-right: 15px;
}
指令
Sass中提供了很多以@
开头并且能够实现各种功能的指令,包括前面的函数@function
就是其中一种
判断
通过@if
、@else if
和@else
实现,举例:
$theme: dark;
.style {
@if $theme == dark {
background: black;
} @else if $theme == light {
background: white;
} @else {
background: red;
}
}
循环
有for、while还有each三种循环方式
- for循环
通过@for $var from 开始值 through/to 结束值
实现,其中through
会在最后一次$var == 结束值
的时候执行,而to
则不会在最后一次执行,举例:
$times: 4;
.style1 {
@for $i from 1 to $times{
col-#{$i} {
width: percentage(0.25* $i);
}
}
}
.style2 {
@for $i from 1 through $times{
col-#{$i} {
width: percentage(0.25* $i);
}
}
}
编译结果为:
.style1 col-1 {
width: 25%;
}
.style1 col-2 {
width: 50%;
}
.style1 col-3 {
width: 75%;
}
.style2 col-1 {
width: 25%;
}
.style2 col-2 {
width: 50%;
}
.style2 col-3 {
width: 75%;
}
.style2 col-4 {
width: 100%;
}
- while循环
通过@while
实现,举例:
$i: 5;
.style {
@while $i > 0 {
col-#{$i} {
width: $i + px;
}
$i: $i - 1;
}
}
- each循环
主要在遍历列表的时候使用,通过@each $var in $list
实现,举例:
$types: success warning error;
.style {
@each $type in $types{
style-#{$type} {
background-image: url('./img/#{$type}.jpg');
}
}
}
样式组
通过@mixin
指令可以定义一个样式组,然后在别的地方通过@include 样式组名
导入这个样式组,举例:
@mixin my_style {
div {
background: black;
a {
font-size: 15px;
}
}
}
.my {
@include my_style;
}
编译结果:
.my div {
background: black;
}
.my div a {
font-size: 15px;
}
通过@mixin
指令定义样式组时还可以传入参数,举例:
$my_color: black;
@mixin my_style($color, $size) {
// 定义参数
div {
background: $color;
a {
font-size: $size;
}
}
}
.my {
@include my_style($my_color, 15px);
// 传入参数
}
编译结果和之前相同
继承样式
使用@extend
指令可以继承其他选择器的样式,举例:
.style1 {
background: black;
}
.style2 {
@extend .style1;
font-size: 15px;
}
编译结果:
.style1, .style2 {
background: black;
}
.style2 {
font-size: 15px;
}
输出警告或错误
通过@warn
/@error
可以输出警告或者错误,警告举例:
@warn "这是一个警告!"
结果可以看到命令行打印如下:
WARNING: 这是一个警告!
on line 1 of test.scss
错误举例:
@error "这是一个错误!"
结果可以看到命令行打印如下:
>>> Change detected to: test.scss
error test.scss (Line 1: 这是一个错误!)
警告和错误的区别就在于警告会进行提示,但不影响后续的编译操作,而错误则在提示后停止编译
模块化开发
Sass之所以变得越来越流行还有个原因就是能够很好地配合如今前端模块化开发的趋势,在Sass中可以把样式分成好几个模块(称作Partials
,即各个小部分,是一堆.scss
文件,并且文件名以_
开头,只作为引用模块,不会被编译),然后通过@import
指令导入,并且和CSS的@import
不同,CSS当中导入样式将会发起一个http请求,相当消耗资源,而这里则是在编译时引入需要的模块,合并成一个文件而已
使用举例:
./part/_main.scss文件
.style1 {
background: black;
}
$theme-color: #ffffff;
导入文件
@import "./part/main";
.style2 {
@extend .style1;
font-size: 15px;
}
.style3 {
background: $theme-color;
}
编译结果
.style1, .style2 {
background: black;
}
.style2 {
font-size: 15px;
}
.style3 {
background: #ffffff;
}
导出至JS参考
scss导出样式:
:export {
theme_color: #ffffff;
}
js中引入:
<script>
import { theme_color } from "xxx.scss";
export default {
data() {
return {
theme_color: theme_color
};
}
};
</script>