一、 什么是sass
Sass (英文全称:Syntactically Awesome Stylesheets) 是一个最初由 Hampton Catlin 设计并由 Natalie Weizenbaum 开发的层叠样式表语言, Sass 是一个 CSS 预处理器。Sass 是 CSS 扩展语言,可以帮助我们减少 CSS 重复的代码,节省开发时间。Sass 完全兼容所有版本的 CSS。
为什么使用 Sass?
CSS 本身语法不够强大,导致重复编写一些代码,无法实现复用,而且在代码也不方便维护。
Sass 引入合理的样式复用机制,增加了规则、变量、混入、选择器、继承、内置函数等等特性。
我们可以举个例子,我们会在 CSS 中重复使用很多次十六进制的颜色代码,当有了变量之后,如果要改变颜色代码,只要修改变量的值就好了:
二、 vscode集成sass
在vscode中配置sass,下载插件
下载完成后在扩展设置里面,点击,然后在settings.json里面添加
代码如下
// 是否生成对应map
"liveSassCompile.settings.generateMap": true,
"liveSassCompile.settings.autoprefix": ["> 1%", "last 2 versions"],
"liveSassCompile.settings.excludeList": ["**/node_modules/**", ".vscode/**"],
"liveSassCompile.settings.formats": [
{
// compressed 压缩格式
// expanded展开格式
// compact 紧凑格式
// nested 嵌套格式
"format": "expanded",
"extensionName": ".css",
"savePath": "~/css/" //编译后的文件生成路径 "~/../css/"
}
],
format后面的参数就是当前通过该插件生成的css代码,生成的目录就是extensionName后面跟的地址
创建文件夹,编写一个sass风格代码,点击vscode下面的watching,发现会生成一个css文件和map文件,css文件代码格式就是我们在json文件中配置的格式
如下图:
三、sass的几种输出格式
compressed 压缩格式 expanded展开格式 compact 紧凑格式 nested 嵌套格式
四、sass语法嵌套规则
嵌套关系,正常CSS的写法
.container{width:1200px; margin: 0 auto;}
.container .header{height: 90px; line-height: 90px;}
.container .header .log{width:100px; height:60px;}
sass嵌套写法
.container {
width: 1200px;
margin: 0 auto;
.header {
height: 90px;
line-height: 90px;
.log {
width: 100px;
height: 60px;
}
}
}
父选择器 &进行嵌套
.container{width: 1200px;margin: 0 auto;}
.container a{color: #333;}
.container a:hover{text-decoration: underline;color: #F00;}
用sass编写
.container {
width: 1200px;
margin: 0 auto;
a {
color: #333;
&:hover {
text-decoration: underline;
color: #F00;
}
}
}
属性进行嵌套
有些 CSS 属性遵循相同的命名空间 (namespace),比如 font-family, font-size, font-weight 都以 font 作为属性的命名空间。为了便于管理这样的属性,同时也为了避免了重复输入,Sass 允许将属性嵌套在命名空间中
.container a {
color: #333;
font-size: 14px;
font-family: sans-serif;
font-weight: bold;
}
用sass编写
.container {
a {
color: #333;
font: {
size: 14px;
family: sans-serif;
weight: bold;
}
}
}
注意font:后面要加一个空格
占位符选择器 %自定义名称 子类必须通过 @extend 注释继承父类
.button%base {
display: inline-block;
margin-bottom: 0;
font-weight: normal;
text-align: center;
white-space: nowrap;
vertical-align: middle;
-ms-touch-action: manipulation;
touch-action: manipulation;
cursor: pointer;
}
.btn-default {
@extend %base;
color: #333;
background-color: #fff;
border-color: #ccc;
}
.btn-success {
@extend %base;
color: #fff;
background-color: #5cb85c;
border-color: #4cae4c;
}
五、注释
Sass支持两种注释
标准的css多行注释 /* … */会编译到.css文件中 单行注释 // 不会编译到.css文件
六、SASS变量
css变量的定义
:root {
--color: #f00;
}
body {
--border-color: #f2f2f2;
}
.header {
--background-color: #f8f8f8;
}
p {
color: var(--color);
border-color: var(--border-color);
}
.header {
background-color: var(--background-color);
}
SASS的写法
$font-size:14px;
.container {
font-size: $font-size;
}
Sass变量的定义
定义规则
变量以美元符号($)开头,后面跟变量名; 变量名是不以数字开头的可包含字母、数字、下划线、横线(连接符); 写法同css,即变量名和值之间用冒号(:)分隔; 变量一定要先定义,后使用;
通过连接符与下划线 定义的同名变量为同一变量,建议使用连接符
$font-size:14px;
$font_size:16px;
.container{font-size: $font-size;}
变量分为局部变量和全局变量
$font-size:14px;
$font_size:16px;
.container{font-size: $font-size;}
.container {
$font-size: 16px !global;
font-size: $font-size;
}
.footer {
font-size: $font-size;
}
SASS支持 7 种主要的数据类型
数字,1, 2, 13, 10px,30% 字符串,有引号字符串与无引号字符串,“foo”, ‘bar’, baz 颜色,blue, #04a3f9, rgba(255,0,0,0.5) 布尔型,true, false 空值,null 数组 (list),用空格或逗号作分隔符,1.5em 1em 0 2em, Helvetica, Arial, sans-serif maps, 相当于 JavaScript 的 object,(key1: value1, key2: value2)
$layer-index:10;
$border-width:3px;
$font-base-family:'Open Sans', Helvetica, Sans-Serif;
$top-bg-color:rgba(255,147,29,0.6);
$block-base-padding:6px 10px 6px 10px;
$blank-mode:true;
$var:null;
$color-map: (color1: #fa0000, color2: #fbe200, color3: #95d7eb);
$fonts: (serif: "Helvetica Neue",monospace: "Consolas");
.container {
@if $blank-mode {
background-color: #000;
} @else {
background-color: #fff;
}
content: type-of($var);
content: length($var);
color: map-get($color-map, color2);
}
$color:#333;
$color:#666 !default;
.container {
border-color: $color;
}
七、SASS 导入@import
@import
Sass 拓展了 @import 的功能,允许其导入 SCSS 或 Sass 文件。被导入的文件将合并编译到同一个 CSS 文件中,另外,被导入的文件中所包含的变量或者混合指令 (mixin) 都可以在导入的文件中使用
public.scss
$font-base-color:#333;
在index.scss里面使用
@import "public";
$color:#666;
注意:在sass中下面几种导入方式会当作默认的css文件进行处理
文件拓展名是 .css;
文件名以 http:// 开头;
文件名是 url();
@import 包含 media queries
@import "public.css";
@import url(public);
@import "http://xxx.com/xxx";
@import 'landscape' screen and (orientation:landscape);
文件名开头加下划线和不加下划线是没有区别的,同一个目录下不能同时出现两个相关名的sass文件(一个不带,一个带),添加下划线的文件将会被忽略。
_theme.scss
@import "theme";
大多数情况下,一般在文件的最外层(不在嵌套规则内)使用 @import,其实,也可以将 @import 嵌套进 CSS 样式或者 @media 中,与平时的用法效果相同,只是这样导入的样式只能出现在嵌套的层中。@import不能嵌套使用在控制指令或混入中。
八、SASS混合指令 (Mixin),作为模板
混合指令(Mixin)用于定义可重复使用的样式。混合指令可以包含所有的 CSS 规则,绝大部分 Sass 规则,甚至通过参数功能引入变量,输出多样化的样式。
普通
@mixin mixin-name() {
}
使用,注意:没有父子关系
// 使用混入
.container {
.block {
@include block;
}
}
使用变量
// 定义flex布局元素纵轴的排列方式
@mixin flex-align($aitem) {
-webkit-box-align: $aitem;
-webkit-align-items: $aitem;
-ms-flex-align: $aitem;
align-items: $aitem;
}
// 只有一个参数,直接传递参数
.container {
@include flex-align(center);
}
// 给指定参数指定值
.footer {
@include flex-align($aitem: center);
}
使用变量(多参数)
@mixin block-padding($top, $right, $bottom, $left) {
padding-top: $top;
padding-right: $right;
padding-bottom: $bottom;
padding-left: $left;
}
使用
.container {
@include block-padding(10px, 20px, 30px, 40px);
}
.container {
@include block-padding($left: 20px, $top: 10px, $bottom: 10px, $right: 30px);
}
.container {
@include block-padding($left: 10px, $top: 10px, $bottom: 0, $right: 0);
}
参数指定默认值
@mixin block-padding($top:0, $right:0, $bottom:0, $left:0) {
padding-top: $top;
padding-right: $right;
padding-bottom: $bottom;
padding-left: $left;
}
可变参数
@mixin linear-gradient($direction, $gradients...) {
background-color: nth($gradients, 1);
background-image: linear-gradient($direction, $gradients);
}
.table-data {
@include linear-gradient(to right, #F00, orange, yellow);
}
九、SASS @extend(继承)
实现代码复用,可以用混入以及继承
用%声明不会将当前复用样式的类名写到css中 用extend会将当前复用样式的类名写到css中
用混入重复的样式不在加入到css中
九、SASS 运算符的基本使用
符号 | 说明 |
---|
等号操作符 | == 或 != | 关系运行符 | >、<、<=、>=(后面只能判断数值) | 逻辑运行符 | and、or、not | 数字操作符 | +、-、*、/、% |
$theme:3;
.container {
@if $theme >= 5 {
background-color: red;
}
@else {
background-color: blue;
}
}
$width:100;
$height:200;
$last:false;
div {
@if $width>50 and $height<300 {
font-size: 16px;
}
@else {
}
}
%和其它不能发生转化
.container {
width: 50 + 20;
width: 50 + 20%;
width: 50% + 20%;
width: 10px + 20px;
width: 10pt + 20px;
width: 10pt + 20;
width: 10px + 10;
height: 50 - 30;
height: 10 - 30%;
height: 60% - 30%;
height: 50px - 20px;
height: 50pt - 20px;
height: 50pt - 40;
height: 50 * 30;
height: 10 * 30%;
height: 50 * 2px;
height: 50pt * 4;
$width: 100px;
width: 10 / 5;
width: 10px / 5px;
width: 10px / 10 * 2;
width: 20px / 2px * 5%;
width: ($width/2); // 使用变量与括号
z-index: round(10)/2; // 使用了函数
height: (500px/2); // 使用了括号
width: 10 % 3;
width: 50 % 3px;
width: 50px % 4px;
width: 50px % 7;
width: 50% % 7;
width: 50% % 9%;
width: 50px % 10pt; // 50px % 13.33333px
width: 50px % 13.33333px;
width: 50px + 10pt;
}
/ 在 CSS 中通常起到分隔数字的用途,SassScript 作为 CSS 语言的拓展当然也支持这个功能,同时也赋予了 / 除法运算的功能。也就是说,如果 / 在 SassScript 中把两个数字分隔,编译后的 CSS 文件中也是同样的作用。 以下三种情况 / 将被视为除法运算符号:
如果值或值的一部分,是变量或者函数的返回值
如果值被圆括号包裹
如果值是算数表达式的一部分
$width: 1000px;
div {
font: 16px/30px Arial, Helvetica, sans-serif; // 不运算
width: ($width/2); // 使用变量与括号
z-index: round(10)/2; // 使用了函数
height: (500px/2); // 使用了括号
margin-left: 5px + 8px/2px; // 使用了+表达式
}
十、插值语句#{…}的使用以及常用函数
类似js中的${}
$width:100px;
$width-size:10px;
$author:"可可";
$attr:color;
$class-name:danger;
div .#{$class-name} {
border-#{$attr}:palegreen;
content:#{$author}
}
sass英文官网
sass包含很多操作颜色的函数。例如:lighten() 与 darken()函数可用于调亮或调暗颜色,opacify()函数使颜色透明度减少,transparent()函数使颜色透明度增加,mix()函数可用来混合两种颜色。
p {
height: 30px;
}
.p0 {
background-color: #009de6;
}
.p1 {
background-color: lighten(#009de6, 30%);
}
.p2 {
// 让颜色变暗 通常使用color.scale()代替该方案
background-color: darken(#009de6, 15%);
}
.p3 {
// 降低颜色透明度 通常使用color.scale()代替该方案
// background-color: opacify(#5c7a29,0.5);
background-color: opacify(rgba(#009de6, 0.1), 0.5);
}
String(字符串函数)
p {
&:after {
content: quote(这是里面的内容);
}
background-color: unquote($string: "#F00");
z-index:str-length("sass学习");
}
List
p {
z-index: length(12px); //1
z-index: length(12px 5px 8px); //3
z-index: index(a b c d, c); //3
padding: append(10px 20px, 30px); // 10px 20px 30px
color: nth($list: red blue green, $n: 2); // blue
}
Math(数值函数)
Map函数操作Map,map-get()根据键值获取map中的对应值,map-merge()来将两个map合并成一个新的map,map-values()映射中的所有值。
p {
z-index: abs($number: -15); // 15
z-index: ceil(5.8); //6
z-index: max(5, 1, 6, 8, 3); //8
opacity: random(); // 随机 0-1
}
$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) + "";
}
}
selector选择器函数
十一、if、for、each、while流程控制指令
三元表达式if
$color:red;
.top{
color:if($color==red,#000,#fff);
}
if else 定义一个css的三角形@mixin声明
@mixin triangle($direction:top, $size:30px, $border-color:black) {
//角方向 尺寸 边框颜色
width: 0px;
height: 0px;
display: inline-block;
border-width: $size;
border-#{$direction}-width: 0;
@if ($direction==top) {
border-color: transparent transparent $border-color transparent;
border-style: dashed dashed solid dashed;
}
@else if($direction==right) {
border-color: transparent transparent transparent $border-color;
border-style: dashed dashed dashed solid;
}
@else if($direction==bottom) {
border-color: $border-color transparent transparent transparent;
border-style: solid dashed dashed dashed;
}
@else if($direction==left) {
border-color: transparent $border-color transparent transparent;
border-style: dashed solid dashed dashed;
}
}
.p0 {
@include triangle();
}
.p1 {
@include triangle(right,20px,green);
}
.p2 {
@include triangle(bottom,40px,pink);
}
使用mixin混合模式,会将重复的代码写在css样式表中,可以用继承减少代码行数
%triangle{
width: 0px;
height: 0px;
display: inline-block;
}
.p0 {
@extend %triangle;
@include triangle();
}
.p1 {
@extend %triangle;
@include triangle(right,20px,green);
}
.p2 {
@extend %triangle;
@include triangle(bottom,40px,pink);
}
@for指令
@for 指令可以在限制的范围内重复输出格式,每次按要求(变量的值)对输出结果做出变动。这个指令包含两种格式:@for $var from through ,或者 @for $var from to
区别在于 through 与 to 的含义:
@for $i from 1 through 4{
.p#{$i}{
width: 200px;
height:10px * $i;
background-color: rgb(round(random()*255),round(random()*255),round(random()*255));
}
}
当使用through时,条件范围包含与的值。
而使用to 时条件范围只包含的值不包含 的值。
css重复样式改写
原生css
#loading {
position: fixed;
top: 200px;
left: 46%;
}
#loading span {
position: absolute;
width: 20px;
height: 20px;
background: #3498db;
opacity: 0.5;
border-radius: 50%;
-webkit-animation: loading 1s infinite ease-in-out;
animation: loading 1s infinite ease-in-out;
}
#loading span:nth-child(1) {
left: 0;
-webkit-animation-delay: 0s;
animation-delay: 0s;
}
#loading span:nth-child(2) {
left: 20px;
-webkit-animation-delay: 0.2s;
animation-delay: 0.2s;
}
#loading span:nth-child(3) {
left: 40px;
-webkit-animation-delay: 0.4s;
animation-delay: 0.4s;
}
#loading span:nth-child(4) {
left: 60px;
-webkit-animation-delay: 0.6s;
animation-delay: 0.6s;
}
#loading span:nth-child(5) {
left: 80px;
-webkit-animation-delay: .8s;
animation-delay: .8s;
}
@-webkit-keyframes loading {
0% {
opacity: 0.3;
-webkit-transform: translateY(0px);
transform: translateY(0px);
}
50% {
opacity: 1;
-webkit-transform: translateY(-20px);
transform: translateY(-20px);
background: green;
}
100% {
opacity: 0.3;
-webkit-transform: translateY(0px);
transform: translateY(0px);
}
}
@keyframes loading {
0% {
opacity: 0.3;
-webkit-transform: translateY(0px);
transform: translateY(0px);
}
50% {
opacity: 1;
-webkit-transform: translateY(-20px);
transform: translateY(-20px);
background: green;
}
100% {
opacity: 0.3;
-webkit-transform: translateY(0px);
transform: translateY(0px);
}
}
sass
#loading {
position: fixed;
top: 200px;
left: 46%;
}
#loading span {
position: absolute;
width: 20px;
height: 20px;
background: #3498db;
opacity: 0.5;
border-radius: 50%;
-webkit-animation: loading 1s infinite ease-in-out;
animation: loading 1s infinite ease-in-out;
}
@for $k from 1 to 6 {
#loading span:nth-child(#{$k}) {
left: 20 * ($k - 1) + px;
animation-delay: 0.2 * ($k - 1) + s;
}
}
@keyframes loading {
0% {
opacity: 0.3;
-webkit-transform: translateY(0px);
transform: translateY(0px);
}
50% {
opacity: 1;
-webkit-transform: translateY(-20px);
transform: translateY(-20px);
background: green;
}
100% {
opacity: 0.3;
-webkit-transform: translateY(0px);
transform: translateY(0px);
}
}
html
<!--
* @Author: wangxue 3208230974@qq.com
* @Date: 2022-08-11 11:41:01
* @LastEditors: wangxue 3208230974@qq.com
* @LastEditTime: 2022-08-12 11:37:05
* @FilePath: \text\sass.html
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="./css/css.css" />
</head>
<body>
<div id="loading">
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
</body>
</html>
unquote去引号
@for $i from 1 to 5 {
#loading span:nth-child(#{$i}) {
left: 20 * ($i - 1) + px;
animation-delay: unquote($string: "0.") + ($i - 1) * 2 + s;
}
}
@each指令
$color-list:red pink green turquoise darkmagenta;
@each $colors in $color-list {
$index: index($color-list, $colors);
.w#{$index - 1} {
background-color: $colors;
}
}
@while 指令指令重复输出格式直到表达式返回结果为 false。
$column:12;
@while $column>0 {
.col-sm-#{$column} {
width: $column / 12 * 100%;
// width: $column / 12 * 100 + %; 会标红
width: $column / 12 * 100#{"%"};
width: unquote($string: $column / 12 * 100 + "%");
}
$column:$column - 1;
}
@function使用
@function row_cols_width($column){
@return percentage(1 / $column);//b百分比函数
}
@for $i from 1 through 6 {
.row-col-#{$i} {
width: row_cols_width($i);
}
}
@function background-linear-gradient($direction,$start-color,$end-color:blue){
@return linear-gradient($direction,$start-color,$end-color);
}
body{
background-image:background-linear-gradient($start-color:pink,$end-color:blue ,$direction:top);
}
可变参数
@function background-linear-gradient($direction,$gradients...){//可变参数
@return linear-gradient($direction,$gradients);
}
body{
background-image:background-linear-gradient(to top,rgb(247, 219, 219), rgb(244, 245, 177), rgb(183, 212, 255), rgb(233, 233, 255));
}
变量中可变参数,要跟…不然会报错
十二、use的使用
use有模块的功能能够重新改变命名空间的名字,是import中的升级版
_下划线与未添加下划线的区别·
如果需要导入 SCSS 或者 Sass 文件,但又不希望将其编译为 CSS,只需要在文件名前添加下划线,这样会告诉 Sass 不要编译这些文件,但导入语句中却不需要添加下划线。 例如,将文件命名为 _colors.scss,便不会编译 _colours.css 文件。 @import “colors”; 上面的例子,导入的其实是 _colors.scss 文件 注意,不可以同时存在添加下划线与未添加下划线的同名文件,添加下划线的文件将会被忽略。
node环境下安装@use监听
npm i -g node-sass
如果发现vscode不支持@use语法到插件中去找当前版本更高的版本
import 后面变量用前面变量覆盖
forword
为了区别不同模块变量名相同加上前缀*不可少
小结:
在嵌套 CSS 规则时,有时也需要直接使用嵌套外层的父选择器,例如,当给某个元素设定 hover 样式时,或者当 body 元素有某个 classname 时,可以用 & 代表嵌套规则外层的父选择器。 Sass可以定义变量,混合宏,%placeholder; Sass可以定义函数; Sass可以使用@if、@fore、@while这样的控制指令; Sass可以使用JSON数据(map);
实战中
|