SASS可编译的CSS语言
SASS是一种预处理语言,通过SASS的功能,我们可以在写css的时候使用到继承,变量等功能
在这里我们是经过nodejs来学习的,所以需要使用到node-sass的编译环境
目前来讲主流的可以编译的css语言有以下几种
1、less 它是第一代的编译型css语言,功能强大,但是编译效率不高,现在已经慢慢不用了
2、sass 它是第二代编译型css语言,相较于less多了很多功能,编译效率更高,但是对于平台的依赖性也越强
3、stylus 简单但不友好,它的语法简洁,但是书写起来会让人感觉不适用
SASS并不能直接运行在浏览器上面,它必须借助第三方平台,官方建议我们适用ruby来完成,但是我们偏不,因为我们有node
sass基础语法
SASS的语法比较特殊
.box
width: 100px
height: 100px
上面就是SASS的语法,他没有空格,没有分号,他是最原始的SASS语言,不能被浏览器直接执行,需要通过node-sass变成css语言才性
SASS的语法非常严格,不能适用分号,不能适用空格,不能适用花空话,必须严格遵守缩进,否则无效
安装sass运行环境
这里我们使用一个叫做sass的包来搭建环境,这个包有个曾用名dart-sass
npm i sass -D
配置sass的编译命令
我们通过命令行来将sass文件编译成css文件
基本编译命令
举例,我们现在要把sass文件夹下面的a.sass文件内的预编译样式编译成css代码写入到css文件夹下面的a.css文件内,那么,编译命令如下
sass sass/a.sass:css/a.css
格式:sass 输入文件 : 输出文件
其他命令形式
# 同时处理多个文件,使用空格分隔
sass index.scss:index.css index1.scss:index1.css
# 处理目录,将 styles 目录全部 sass/scss 编译到 public/css 目录中
sass styles:public/css
当我们通过上面的命令执行编译之后,我们发现除了会完成编译外,还会额外生成一个同名的map文件,这里面记录了编译资源的来源,如果不想生成这个文件我们需要添加一个命令行选项 --no-source-map
sass --no-source-map index.scss:index.css
sass命令行选项
# 查看当前 sass 版本
sass --version
# 查看帮助
sass --help
# 从标准输入读取输入文件,此时不能手动指定输入文件,只能指定输出文件
# 处理多文件时不能使用此选项
sass --stdin index.css
# 强制使用缩进语法去解析输入文件,不管是 sass 还是 scss
# 在输入文件来自标准输入时非常有用,因此它的语法无法自动确定是 sass 还是 scss。
sass -–indented
# 强制不使用缩进语法去解析输入文件,,不管是 sass 还是 scss
sass -–no-indented
# 指定文件加载路径,避免输入文件携带太长的路径
# 可以多次传递该选项,前面的路径优先于后面的路径
# 简写 -I
sass --load-path=src/styles index.scss:public/index.css
sass -I=src/styles index.scss:public/index.css
# 控制输出文件的风格, expanded (默认)展开代码, compressed 压缩代码为一行
sass --style=compressed index.scss:index.css
# --style 简写为 -s
sass -s=compressed index.scss:index.css
# 使用 --charset 后,强制在开头加上 @charset 标记
# 默认情况下,如果出现了非 ASCII 字符,Sass 自动在开头加上 @charset 标记
sass --charset index.scss:index.css
# --no-charset 无论如何都不添加 @charset 标记
sass --no-charset index.scss:index.css
# 强制在编译错误时,生成错误信息到 css 注释 和 body::before 的 content 中
sass --error-css index.scss:index.css
# 禁用生成错误信息
sass --no-error-css index.scss:index.css
# 每次执行命令,都会去检查输入文件和输出文件的状态:
# 当输入文件的最后修改时间晚于输出文件的时间时,才会去重新编译
# 如果执行了编译,会在终端打印消息,否则没有任何操作。
# 和 --watch 的区别,--update 执行后便退出,--watch 持续监测输入文件变化
sass --update themes:public/css
# Dart Sass 默认为它发出的每个CSS文件生成源码映射文件(source map)。
# 不允许生成 source map 文件
sass --no-source-map index.scss:index.css
# 指定生成的 source map 文件和 sass 源文件的位置关系
# relative 默认,生成相对路径,absolute 生成绝对路径
sass --source-map-urls=relative index.scss:index.css
# 将 source map 文件嵌入到生成的 css 代码中,css 文件体积会很大
sass --embed-sources index.scss:index.css
# 开启监听模式,运行后终端保持运行,监听到文件变更立即重新编译
sass --watch index.scss:index.css
# --poll 只能和 --watch 一起使用
# 让 Sass 时不时地手动检查源文件更改,而不是依赖于操作系统在更改时通知它。
# 如果在操作系统通知系统无法工作的远程驱动器上编辑 Sass,这可能是必要的。
sass --watch --poll index.scss:index.css
# 遇到错误时立即停止编译
sass --stop-on-error index.scss:index.css
# sass 交互对话,执行后可以在命令行输入 sass 代码然后编译
sass --interactive
# 简写 -i
sass -i
# 简写 -c ,终端使用有颜色的信息
sass --color index.scss:index.css
# 默认,为这些消息发出非 ASCII 字符。这个标志不会影响CSS输出。
sass --unicode index.scss:index.css
# 只将 ASCII 字符作为错误消息的一部分发送到终端。
sass --no-unicode index.scss:index.css
# 静默终端,不显示 @warn 及 @debug 的信息,默认情况下,使用了废弃的功能会有警告信息
sass –quiet index.scss:index.css
# 遇到错误时打印完整的Dart或JavaScript堆栈跟踪。Sass团队使用它来调试错误。
sass --trace index.scss:index.css
在package.json中配置执行脚本
为了文件操作,我们可以直接在package.json中来配置这个命令
"css":"sass --no-source-map --watch sass:css"
这个时候我们只需要在控制他执行npm run css就可以了
SCSS
上面我们有说sass非常严格,这种语法给程序的代码书写会造成极大的不方便,这个时候SASS就推出一个语法叫做SCSS
什么是scss
SASS是标准,SCSS是语法
SCSS的本质就是SASS+CSS,他使用css的语法来完成sass的功能
相当于在css的原有的基础上面扩展了4个基础核心点
SCSS的四个核心基础点
1、变量
2、嵌套
3、混合
4、继承
SASS的语法
.box
width: 100px
height: 100px
SCSS的语法
.box{
width:100px;
height:100px;
color:red;
}
SASS的注释
/*
这是css的注释
*/
//这个是sass注释
变量
在scss中我们可以声明变量
$color1:red;
.box1{
color:$color1;
}
$color1:blue;
.box2{
color:$color1;
}
变量是可以进行多次定义的,后面定义的会把前面覆盖掉
但是,并不是所有后面的定义的变量都会把前面的覆盖掉
$w:200px;
$w:100px !default;
嵌套
.box{
width:100px;
a{
color:red;
}
>p{
height:100px;
#abc{
border-radius:50%;
}
}
}
经过编译
.box {
width: 100px;
}
.box a {
color: red;
}
.box > p {
height: 100px;
}
.box > p #abc {
border-radius: 50%;
}
父级选择标识符&
在css中,有时候,我们需要在子级当中使用父级选择器,这个时候,我们就需要使用 & 来选取父级选择器
#abc{
border-radius:50%;
&:hover{
color:yellow;
}
}
经过编译
#abc {
border-radius: 50%;
}
#abc:hover {
color: yellow;
}
在嵌套里面,会自动根据我们的嵌套关系来实现以下功能
1、后代选择器
2、子代选择器
3、相邻选择器
4、兄弟选择器
综上:我们可以得到嵌套实际上是标签的父子级关系的一个体现,通过嵌套关系表示父子关系,从而编译所有的后代或兄弟选择器
混合
混合我们可以理解成js里面的函数,定义了函数就可以调用,混合定义的函数可以接收参数,也可以返回值
假设我们希望某一个页面上面的button具备一个基础样式,然后在这个基础样式的上面扩展新的样式
//定义一个混合器
@mixin btn(){
min-width:90px;
height:35px;
border:solid 1px #ccc;
text-align:center;
border-radius:10px;
}
.btn1{
background:red;
@include btn();
}
.btn2{
background:blue;
@include btn();
}
经过编译
.btn1 {
background: red;
min-width: 90px;
height: 35px;
border: solid 1px #ccc;
text-align: center;
border-radius: 10px;
}
.btn2 {
background: blue;
min-width: 90px;
height: 35px;
border: solid 1px #ccc;
text-align: center;
border-radius: 10px;
}
混合器带参
//弹性盒子
@mixin flex-box($dir:row){
display:flex;
flex-direction:$dir;
}
@mixin btn(){
min-width:90px;
height:35px;
border:solid 1px #ccc;
text-align:center;
border-radius:10px;
}
.box1{
width:500px;
@include flex-box();
}
.box2{
height:500px;
@include flex-box(column);
@include btn();
}
混合器里面如果没有参数,后面的小括号可以省略
继承
sass里面的继承实现是使用分组选择器的功能来是现实的
//继承
.box1{
width:100px;
height:100px;
border:solid 1px #ccc;
}
.box2{
background:red;
@extend .box1;
}
.box3{
border-radius:50%;
@extend .box2;
}
经过编译
.box1, .box2, .box3 {
width: 100px;
height: 100px;
border: solid 1px #ccc; }
.box2, .box3 {
background: red; }
.box3 {
border-radius: 50%; }
跳出
跳出主要针对的是嵌套,他使用@at-root来完成
.box1{
width:100px;
.abc{
height:200px;
//在任何地方写@at-root都代表跳到最外层
@at-root{
.def{
color:blue;
}
}
}
}
注意:@at-root默认情况下是跳不除@media媒体查询
@media only screen and (max-width:768px){
.box1{
width:100px;
.abc{
height:200px;
//在任何地方写@at-root都代表跳到最外层
@at-root{
.def{
color:blue;
}
}
}
}
}
以上代码编译结果
@media only screen and (max-width: 768px) {
.box1 {
width: 100px; }
.box1 .abc {
height: 200px;
}
.def {
color: blue;
}
}
如果要跳出媒体查询,则需要使用@at-root(without:media)
@media only screen and (max-width:768px){
.box1{
width:100px;
.abc{
height:200px;
//在任何地方写@at-root都代表跳到最外层
@at-root(without:media){
.def{
color:blue;
}
}
}
}
}
数组定义
$a:red;
$list:red,yellow,pink
一般来说,我们为了更好的理解,我们会用小括号将值包裹起来
$list:(red,yellow,pink);
对象的定义
//对象的定义
$themeColor:(
primary:lightgreen,
danger:red,
warning:orange,
success:green
);
@each $key,$value in $themeColor {
.bg-#{$key}{
background-color:$value;
}
}
上面的代码进行遍历,最终生成如下结果
.bg-primary {
background-color: lightgreen; }
.bg-danger {
background-color: red; }
.bg-warning {
background-color: orange; }
.bg-success {
background-color: green; }
set定义
之前的数组定义是一样的,数组的定义就是set的定义
map定义
之前的对象的定义是一样的,对象的定义就是map的定义
$themeColor:(
primary:lightgreen,
danger:red,
warning:orange,
success:green
);
.box1{
width:100px;
color:map-get($themeColor,primary);
}
循环
循环这个东西是所有变成语言的基础点,在sass里面也可以使用,他用@for来开始
语法如下
@for $i from start through end{
}
start代表开始,end代表结束
@for $i from start to end{
}
上面的语法里面一个through一个to
through包含end,to不包含end
如果要生成下面的代码,怎么写?
.div1{
background-image:url("./img/1.png");
}
.div2{
background-image:url("./img/2.png");
}
.div3{
background-image:url("./img/3.png");
}
.div4{
background-image:url("./img/4.png");
}
.div5{
background-image:url("./img/5.png");
}
scss代码:
@for $i from 1 through 5{
.div#{$i}{
background-image: url("./img/#{$i}.png");
}
}
两个注意点:
1、through和to的区别
2、变量插入值使用#{} 来完成
遍历
$arr:(red,blue,yellow,pink);
@each $item in $arr{
.bg-#{$item}{
background-color:$item;
}
}
$index:1;
@each $item in $arr{
.bg-#{$index}{
background-color:$item;
}
$index:$index + 1;
}
注意:
这里如果要将数组中的元素作为选择器的名称使用可以写成
""+$item
,有点类似与转字符串进行拼接的意思,不然会报一个警告(Warning),但是警告不是错误,所以按照上面案例的写法也行
进行编译:
.bg-red {
background-color: red; }
.bg-blue {
background-color: blue; }
.bg-yellow {
background-color: yellow; }
.bg-pink {
background-color: pink; }
.bg-1 {
background-color: red; }
.bg-2 {
background-color: blue; }
.bg-3 {
background-color: yellow; }
.bg-4 {
background-color: pink; }
条件判断
在sass里面实现条件判断的方式有两种
1、三目运算符
2、@if
$w:100px;
.box1{
color:red;
//如果$w的值大于200px,则背景为蓝色,否则为黑色
@if $w > 200px {
background-color:blue;
}
@else{
background-color:black;
}
}
$index:4;
.box{
width:100px;
//如果index为1,颜色为红色,index为2,颜色为黑色,否则蓝色
@if $index == 1{
background-color:red;
}
@else if $index == 2{
background-color:black;
}
@else{
background-color:blue;
}
}
上面的判断里面的if语法,还可以使用if函数来进行
$a:2;
.div1{
color:red;
background-color: if($a == 1,rgb(255,255,255),blue);
}
函数
这个函数和我们之前学过的js的函数一样,他可以使用@function的关键字来定义,还可以使用@return来设置返回值
$baseFontSize: 16px !default;
@function pxToRem($px){
@return $px / $baseFontSize * 1rem;
}
.box1{
width:pxToRem(100px);
}
这里我们使用到了 / 作为除法运算符使用,但是我们看到一个Warning警告,告诉我们官方不建议我们在calc() 外使用 / 作为除法运算符,并且这种写法将在sass2.0中弃用
建议我们使用以下两种方式做触发运算
math.div($px, b a s e F o n t S i z e ) o r c a l c ( baseFontSize) or calc( baseFontSize)orcalc(px / $baseFontSize)
scss里面有很多自带函数
.box1{
width:pxToRem(100px);
color:lighten(#000,10%);
background-color:darken(red,10%);
}
运算
sass具有运算的能力,可以对数值型的value(比如数字,颜色,变量等)进行四则运算
一定要注意,运算符前后一定要留一个空格,不然会出错