typora-root-url: images
typora-copy-images-to: images
Sass的认识
什么是Sass
-
世界上最成熟、最稳定、最强大的专业级CSS扩展语言!
-
sass
是一个css
的预编译工具 -
也就是能够 更优雅 的书写
css
-
sass
写出来的东西 浏览器不认识 -
依旧是要转换成
css
在浏览器中运行 -
这个时候就需要一个工具来帮我们做
环境的搭建(gulp-sass)
gulp-sass-china文档 <https://www.npmjs.com/package/gulp-sass-china>
前提:工作目录下gulp插件已经安装
gulp-sass的安装
安装步骤:
a 切换到项目文件夹
b glup的本地化 npm install gulp --save-dev
c 执行npm install sass gulp-sass --save-dev进行安装
sass文件的手动解析
在项目中创建.scss文件
// 变量测试
$fontColor:red;
h1 {
color: $fontColor;
}
编写gulp文件glupFile.js
// 加载gulp
const gulp = require('gulp');
// 读取用于sass的插件
var sass = require('gulp-sass')(require('sass'));
// 定义gulp任务
gulp.task('sass',async()=>{
gulp.src('./sass/index.scss').pipe(sass()).pipe(gulp.dest('./css'));
});
创建html文件引入并且使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="./css/a.css">
</head>
<body>
<h1>苦与乐都在主观的心,不在客观的事</h1>
</body>
</html>
执行文件
gulp sass
sass文件的自动解析
通常情况下,Sass文件的修改频率并不低,如果每一次修改都要手动指定任务,并运行我们的gulp脚本,太麻烦了。我们就尝试利用gulp的watch功能,实现每当Sass文件的内容发生改变,就会自动执行对应的命令,重新进行编译。
watch("要监视的文件", 要进行的响应处理)
修改glupFile.js文件
var gulp = require('gulp');
var sass = require('gulp-sass');
//sass文件的解析任务
gulp.task('sass-1',function(){
return gulp.src('./sass/*.scss').pipe(sass()).pipe(gulp.dest('./css'))
})
// 通知浏览器刷新文件
// sass文件的自动解析
var watch = require('gulp-watch');
gulp.task('default', function () {
watch('./sass/*.scss', gulp.parallel('sass-1'))
})
在sass.html文件中,添加p标签
在index.sass中设置p的颜色和字号大小
$fontColor :red;
$pColor:green;
$pSize:20;
h1{
color:$fontColor
}
p{
color: $pColor;
font: $pSize;
}
@debug
在 Sass 中是用来调试的,当你的在 Sass 的源码中使用了 @debug 指令之后,Sass 代码在编译出错时,在命令终端会输出你设置的提示 Bug:
@debug 10px + 12px;
SASS单独解析
安装 sass 环境
-
以前的
sass
需要依赖一个ruby
的环境 -
现在的
sass
需要依赖一个python
的环境 -
但是我们的
node
强大了以后,我们只需要依赖node
环境也可以 -
需要我们使用
npm
安装一个全局的sass
环境就可以了# 安装全局 sass 环境 $ npm install sass -g
编译 sass
-
有了全局的
sass
环境以后 -
我们就可以对
sass
的文件进行编译了 -
sass
的文件后缀有两种,一种是.sass
一种是.scss
-
他们两个的区别就是有没有
{}
和;
-
.scss
文件h1 { width: 100px; height: 200px; }
-
.sass
文件h1 width: 100px height: 200px
-
我们比较常用的还是
.scss
文件 -
因为
.sass
我们写不习惯,当然,如果你能写习惯也比较好用 -
我们先不管里面的的什么内容,这个
.scss
或者.sass
文件浏览器就不认识 -
我们就要用指令把这两种文件变成
css
文件# 把 index.scss 编译,输出成 index.css $ sass index.scss index.css
-
这样我们就能得到一个
css
文件,在页面里面也是引入一个css
文件就可以了
实时编译
-
我们刚才的编译方式只能编译一次
-
当你修改了文件以后要从新执行一遍指令才可以
-
实时编译就是随着你文件的修改,自动从新编译成
css
文件 -
也是使用指令来完成
# 实时监控 index.scss 文件,只要发生修改就自动编译,并放在 index.css 文件里面 $ sass --watch index.scss:index.css
-
然后你只要修改
index.scss
文件的内容,index.css
文件中的内容会自动更新
实时监控目录
-
之前的实时监控只能监控一个文件
-
但是我们有可能要写很多的文件
-
所以我们要准备一个文件夹,里面放的全部都是
sass
文件 -
实时的把里面的每一个文件都编译到
css
文件夹里面 -
依旧是使用指令的形式来完成
# 实时监控 sass 这个目录,只要有变化,就会实时响应在 css 文件夹下 $ sass --watch sass:css
-
这样,只要你修改
sass
文件夹下的内容,就会实时的相应在css
文件夹中 -
你新添加一个文件也会实时响应
-
但是你删除一个文件,
css
文件夹中不会自动删除,需要我们自己手动删除
常用的sass知识
变量
必须以$开头,如果变量需要镶嵌在字符串之中,就必须需要写在#{}之中。
例1:声明一个字体变量
$font-size:16px;
div{
font-size: $font-size;
}
例2:将变量嵌入到字符串中
$radius:radius;
.rounded{
border-#{$radius}:10px;
border: solid 1px #{$fontColor};
}
例3:使用nth()调取变量的值
$linkColor:green red!default;
div{
color: nth($linkColor,1);
&:hover{
color:nth($linkColor,2);
}
}
嵌套(三阶段使用较多)
-
sass
里面我们最长用到的就是嵌套了 -
而且相当的好用
h1 { width: 100px; div { width: 200px; } } // 编译结果 h1 { width: 100px; } h1 div { width: 200px; }
-
这个就是嵌套,理论上可以无限嵌套下去
ul { width: 100px; li { width: 90px; div { width: 80px; p { width: 70px; span: { color: red; } } } } }
嵌套中的 &
-
在嵌套中还有一个标识符是
&
我们可以使用 -
先来看一个例子
div { width: 100px; height: 100px; :hover { width: 200px; } } // 我想的是 div 被鼠标悬停的时候 width 变成 200 // 但是编译结果却是 div { width: 100px; height: 100px; } div :hover { width: 200px; }
-
和预想的结果不一样了
-
这个时候就要用到
&
来连接了div { width: 100px; height: 100px; &:hover { width: 200px; } } // 编译结果 div { width: 100px; height: 100px; } div:hover { width: 200px; }
-
这个时候就和我需要的一样了
群组嵌套
-
群组嵌套就是多个标签同时嵌套
div { width: 100px; .box1, .box2, .box3 { color: red; } } // 编译结果 div { width: 100px; } div .box1, div .box2, div .box3 { color: red; }
-
还有一种就是多个标签同时嵌套一个标签
h1, h2, h3 { width: 100px; .box { color: red; } } // 编译结果 h1, h2, h3 { width: 100px; } h1 .box, h2 .box, h3 .box { color: red; }
嵌套属性
-
在
scss
里面还有一种特殊的嵌套 -
叫做 属性嵌套
-
和选择器嵌套不一样,是写属性的时候使用的
div { border: { style: solid; width: 10px; color: pink; } } // 编译结果 div { border-style: solid; border-width: 10px; border-color: pink; }
-
这个属性嵌套还可以有一些特殊使用
div { border: 1px solid #333 { bottom: none; } } // 编译结果 div { border: 1px solid #333; border-bottom: none; }
sass中的map
语法
Sass 的 map 常常被称为数据地图,也有人称其为数组,它是以 key:value 成对出现
数据以 key:value 的形式赋予,其中 key 和 value 是成对出现,并且每对之间使用逗号 (,) 分隔,其中最后一组后面没有逗号 .
$map: (
key1: value1,
key2: value2,
key3: value3
)
map的相关函数
map-get($map, key) 获取指定的值
根据 key 参数,返回 key 在 $map 中对应的 value 值。如果 key 不存在 $map 中,将返回 null 值
此函数包括两个参数:
$map:定义好的map
key:需要遍历的key
例1:获取$btn-colors中map的facebook的值
$btn-colors: (
jd: red,
facebook: pink,
github: green
);
.btn {
color: map-get($btn-colors, facebook);
}
map-has-key($map, $key)
根据给定的 key 值判断 map 是否有对应的 value 值,如果有返回 true,否则返回 false
当 $key 不在 $map 中时,使用 map-get($map, $key) 函数将返回一个 null
例:判断其中是否有需要的颜色
$btn-colors: (
jd: red,
facebook: pink,
github: green
);
@if map-has-key ($social-colors, facebook){
.btn-facebook {
color: map-get($social-colors,facebook);
}}
// 编译为:.btn-fackbook{ color: #3b5998; }
map-values($map) 返回集合中的values
例:将一个border的样式进行设置
$border-style: (
text:#f63,
link:#f36,
border:#ddd,
background:#fff
);
$list:map-values($color);
@debug $list
map-remove( m a p , map, map,key) 删除当前 $map 中的某一个 $key,返回值是不包含删除的key和value的map。
例:删除集合中指定的第一个颜色
$map:map-remove($btn-colors,jd);
判断
@if 指令是一个 SassScript,它可以根据条件来处理样式块,如果条件为 true 返回一个样式块,反之 false 返回另一个样式块。在 Sass 中除了 @if 之,还可以配合 @else if 和 @else 一起使用.
例1:单独的@if使用
$baColor: true;
.id{
display:inline-block;
@if $baColor {
background:red;
}
}
例2:根据传入的值判断不同的状态,显示不同颜色
$status: success;
p{
@if $status == login {
color: blue;
} @else if $status == error {
color: red;
} @else if $status == success {
color: green;
} @else {
color: black;
}
}
}
Sass中的循环
@for循环
for循环有两种形式,
形式1 @for $i from through
形式2 @for $i from to 。
$i表示变量,start表示起始值,end表示结束值,这两个的区别是关键字through表示包括end这个数,而to则不包括end这个数。
例1:先来个使用 through 关键字的例子
ul {
list-style: none;
}
@for $i from 1 through 3{
li:nth-child(#{$i}){
background: url(../../images/#{$i}.jpg);
float: left;
width: 200px;
height: 200px;
margin: 0 20px 20px 0;
background-size:cover;
}
}
输出结果
li:nth-child(1) {
background: url(../../images/1.jpg);
float: left;
width: 200px;
height: 200px;
margin: 0 20px 20px 0;
background-size: cover;
}
li:nth-child(2) {
background: url(../../images/2.jpg);
float: left;
width: 200px;
height: 200px;
margin: 0 20px 20px 0;
background-size: cover;
}
li:nth-child(3) {
background: url(../../images/3.jpg);
float: left;
width: 200px;
height: 200px;
margin: 0 20px 20px 0;
background-size: cover;
}
例2:to 关键字的例子
ul {
list-style: none;
}
@for $i from 1 to 3{
li:nth-child(#{$i}){
background: url(../../images/#{$i}.jpg);
float: left;
width: 200px;
height: 200px;
margin: 0 20px 20px 0;
background-size:cover;
}
}
@each循环
@each 循环就是去遍历一个列表,然后从列表中取出对应的值。
@each 循环指令的形式:
@each $var in <list>
例:多字段的map循环
$style:(h1:20px,h2:10px,h3:6px);
@each $h,$s in $style{
#{$h}{
font-size:$s
}
}
继承
-
在
sass
里面使用继承可以大大的提高开发效率 -
其实继承很简单,就是把之前写过的选择器里面的内容直接拿过来一份
div { width: 100px; height: 100px; background-color: pink; }
-
这个是之前写过的一个规则样式表
-
接下来我要写另外一个样式了,发现我要写的一些内容和之前这个
div
一样,并且还有一些我自己的内容 -
那么我就可以把这个样式表先继承下来,再写我自己的内容就好了
p { @extend div; font-size: 20px; color: red; }
-
编译结果
div, p { width: 100px; height: 100px; background-color: pink; } p { font-size: 20px; color: red; }
注释
-
在
scss
文件中的注释分为几种-
编译的时候不会被编译的注释
// 我是一个普通注释,在编译的时候,我就被过滤了
-
编译的时候会被编译的注释
/* 我在编译的时候,会被一起编译过去 */
-
强力注释
/*! 我是一个强力注释,不光编译的时候会被编译过去,将来压缩文件的时候也会存在 */
-
导入文件
-
我们刚才学过了定义变量,定义混合器
-
而这两个内容在定义过以后,如果没有使用,是不会被编译出内容的
-
所以我们可以把变量单独写一个文件,混合器单独写一个文件,然后直接导入后使用
// 我是 variable.scss $w: 100px; $h: 200px; $c: pink; // 我是 mixin.scss @mixin my_transition($dur: 1s, $pro: all, $delay: 0s, $tim: linear) { -webkit-transition: $dur $pro $delay $tim; -moz-transition: $dur $pro $delay $tim; -ms-transition: $dur $pro $delay $tim; -o-transition: $dur $pro $delay $tim; transition: $dur $pro $delay $tim; } @mixin radius { -webkit-border-radius: 10px; -moz-border-radius: 10px; -ms-border-radius: 10px; -o-border-radius: 10px; border-radius: 10px; }
-
然后在我们的主要文件中把这个两个文件导入进来就行了
// 我是 index.scss @import './variable.scss'; @import './mixin.scss'; div { width: $w; height: $h; background-color: $c; @include radius; } h1 { @include my_transition; }
-
编译结果
sass中mixin
概念
Mixins
是SASS中的一个强大的功能。使用@mixin
根据功能定义一个模块,然后在需要使用的地方通过@include
来调用声明的mixins
。其主要功能是可以让你的代码简洁高效.
基本使用
例1: 基本的使用button的样式mixin,进行调用
@mixin button {
font-size: 1em;
padding: 0.5em 1.0em;
text-decoration: none;
color: #fff;
}
引用
.btn{
@include button;
}
参数的使用
Mixins可以接收和使用参数,多个参数使用逗号隔开,也可以设置参数默认值
例1:定义一个button的mixin然后传递参数,更新之前的button
模块,增加了名为background
的参数并将其传递给模块。
@mixin button($background) {
font-size: 1px;
padding: 0.5px 1.0px;
text-decoration: none;
color: #fff;
background: $background;
}
注意到参数被设置为一个变量并成为backround属性的值。如果我们想创建一个绿色的按钮,那么就可以使用以下代码:
进行调用
.button-green {
@include button(green);
}
例2:在例1的基础上增加$color,同时给背景设置默认颜色
@mixin button($backgroundColor,$color:red){
font-size:1px;
padding:0.5px 2px;
text-decoration: none;
color:$color;
background: $backgroundColor;
}
.button-green{
@include button(green);
}
自定义函数
要实现函数的声明和返回内容我们需要使用function和return两个指令,类似于其他语言中的关键字。
语法
@function 函数名(形参) {
@return;
}
例1:将宽度乘以2然后,返回
@function getWidth($w) {
@return $w * 2;
}
.main{
max-width: #{getWidth(20)}px;
}
mixin与function的区别
函数可以有多个语句组成,但是必须设定返回值(return)。但是混合(mixin)就可以不用设置返回值即可操作。函数(function)传入的值也可以带有变量