1 维护 CSS 的弊端
-
CSS 需要书写大量没有逻辑的代码,重复度很高。
-
不方便维护以及扩展,不利于复用。
2 什么是 SASS
SASS 是一种 CSS 的开发工具,提供了许多便利的写法,大大节省了设计者的时间,使得 CSS 的开发,变得简单和可维护。
它没有减少 CSS 的功能,而是在 CSS 的基础上引入了变量,Mixin(混合),运算以及函数等功能,大大简化了 CSS 的编写,并且降低 CSS 的维护成本。
总结:写更少的代码,实现更多的样式。
3 在线工具
4 简单示例
实现两个按钮,当 hover 的时候会上下动。
<div class="btn-box"> <button class="btn btn01">左右晃动</button> <button class="btn btn02">上下晃动</button> </div>
下面是用 CSS 实现的代码。下面用 SASS 一步步去简化这些代码。
* { margin: 0; padding: 0; box-sizing: border-box; } body { height: 100vh; background: white; display: flex; justify-content: center; align-items: center; } /* btn-box */ .btn-box>.btn { padding: 10px 20px; font-size: 24px; border-radius: 4px; color: white; border: none; margin: 40px; box-shadow: 0px 5px 0px 0px rgba(0, 0, 0, 1); cursor: pointer; } .btn-box>.btn01 { background: #55acee; } .btn-box>.btn01:hover { animation: horizontalShake .5s; } .btn-box>.btn02 { background: #2ecc71; } .btn-box>.btn02:hover { animation: verticalShake .5s; } /* 水平弹动 */ @keyframes horizontalShake { 0% { transform: translateX(10%); } 25% { transform: translateX(-10%); } 75% { transform: translateX(10%); } 100% { transform: translateX(0%); } } /* 竖直弹动 */ @keyframes verticalShake { 0% { transform: translateY(15%); } 25% { transform: translateY(-15%); } 75% { transform: translateY(15%); } 100% { transform: translateY(0%); } }
代码也很简单,分别是两个按钮的基本样式和 hover 样式,以及两个动画。
4.1 嵌套
下面开始重构代码。嵌套是 SASS 最常用的技巧,以后的
.a .b .c .d { color: red; } .a .b .c .e { color: blue; }
就可以写成
.a { .b { .c { .d { color: red; } .e { color: blue; } } } }
上面示例代码里的 .btn-box
和 .btn
就是这种结构的,所以可以改写成下面:
.btn-box { .btn { padding: 10px 20px; font-size: 24px; border-radius: 4px; color: white; border: none; margin: 40px; box-shadow: 0px 5px 0px 0px rgba(0, 0, 0, 1); cursor: pointer; } .btn01 { background: #55acee; } .btn01:hover{ animation: horizontalShake .5s; } .btn02 { background: #2ecc71; } .btn02:hover{ animation: verticalShake .5s; } }
4.2 占位符
我们发现像 .btn01:hover
和 .btn01
好像有点重复的感觉,但是这又不是嵌套的关系,只是有点像。所以这就要用到 SASS 占位符了。
&
代表了上一级的选择器,这里可以用 &
来替换 .btn01
,代码改写如下:
.btn-box { .btn { padding: 10px 20px; font-size: 24px; border-radius: 4px; color: white; border: none; margin: 40px; box-shadow: 0px 5px 0px 0px rgba(0, 0, 0, 1); cursor: pointer; } .btn01 { background: #55acee; &:hover{ animation: horizontalShake .5s; } } .btn02 { background: #2ecc71; &:hover{ animation: verticalShake .5s; } } }
4.3 Mixin
我们发现两个按钮的样式差不多,唯一不同的就是颜色。有没有像函数一样的东西,传入颜色参数就生成一样的代码呢?
SASS 有 Mixin 这个东西,其本质就是函数,定义一个代码块。
定义 Mixin 前面要用 @mixin
,调用的时候要在前端用 @include
SASS 的变量要用 $
开头,还有一定别忘了要在结尾加分号。
@mixin btnStyles($color) { padding: 10px 20px; font-size: 24px; border-radius: 4px; color: white; border: none; margin: 40px; box-shadow: 0px 5px 0px 0px rgba(0, 0, 0, 1); cursor: pointer; background: $color; } .btn-box { .btn01{ @include btnStyles(#55acee); &:hover{ animation: horizontalShake .5s; } } .btn02 { @include btnStyles(#2ecc71); &:hover { animation: verticalShake .5s; } } }
4.4 颜色函数
在 box-shadow
那里用黑色明显不好,我们更希望的是按钮颜色再深一点的颜色。可以使用 SASS 提供的 darken(color, percentage)
来生成对应颜色。
@mixin btnStyles($color) { padding: 10px 20px; font-size: 24px; border-radius: 4px; color: white; border: none; margin: 40px; box-shadow: 0px 5px 0px 0px darken($color, 20%); cursor: pointer; background: $color; }
4.5 循环和条件
在 @keyframes
里代码也有很多相似的地方。这里可以用 SASS 提供的循环和条件语法来生成 keyframes 代码。
for 循环使用 @for $i from x to y
将会从 x 开始到 y - 1 依次遍历。
if 条件语句使用 @if condition
。
#{$xxx}
里面要放变量,整体就是一个字符串。
$offset: 10%; $step: 25%; @keyframes horizontalShake { @for $i from 0 to 5{ #{$i * $step} { @if $i == 0 or $i == 3 { transform: translateX($offset); } @else if $i == 1 { transform: translateX(-$offset); } @else { transform: translateX(0%); } } } } @keyframes verticalShake { @for $i from 0 to 5{ #{$i * $step} { @if $i == 0 or $i == 3 { transform: translateX($offset); } @else if $i == 1 { transform: translateX(-$offset); } @else { transform: translateX(0%); } } } }
4.6 示例总结
-
嵌套语法用于后代选择器
-
占位符用代表父选择器
-
Mixin 就是我们熟悉的函数
-
可以使用 SASS 提供的颜色函数
-
变量使用
$variable
-
循环语句
@for $i from x to y
从 x 到 y - 1 依次遍历 -
条件语句
@if condition
5 基本语法
5.1 变量
SASS 的变量名必须是一个 $ 符号开头,后面紧跟变量名
//SASS 样式 $red: #f00; div { color: $red; } // 编译为css后 div { color: #f00; }
特殊变量:如果变量嵌套在字符串中,则需要写在 #{} 符号里面,如:
$top: top; div { margin-#{$top}: 10px; } // 编译为css后 div { margin-top: 10px; }
默认变量:仅需在值后面加入 !default即可, 默认变量一般用来设置默认值,当该变量出现另外一个值时,无论定义先后,都会使用另外一个值,覆盖默认值。
$color: red; $color: blue !default; div { color: $color; } // 编译为css后 div { color: red; }
多值变量:多值变量分为 list 类型和 map 类型,Lists 类型的值可以用空格或加逗号分隔,Maps 代表一个键和值对集合,键用于查找值。和 Lists 不同,Maps 必须始终使用括号括起来,并且必须用逗号分隔。@each
指令能够遍历数组中的每一项
list : 可通过空格,逗号或小括号分割多个值,使用 nth($变量名, $索引) 取值。
// 一维数据 $px: 5px 10px 20px 30px; // 二维数据 $px: 5px 10px, 20px 30px; $px: (5px 10px) (20px 30px); // 例子 $px: 10px 20px; div { /* margin:10px 0 0 20px; */ margin:nth($px, 1) 0 0 nth($px, 2); }
map: 数据以key和value组成,格式:$map: (key1: value1, key2: value2); 通过 map-get($map, $key);
$headings: (h1: 2em, h2: 1.5em, h3: 1.2em); @each $header, $size in $headings { #{$header} { font-size: $size; } } h1 { font-size: map-get($headings,h1) }
5.2 计算功能
SASS 允许使用算式。
div { padding: 2px * 4; margin: (10px / 2); font-size: 12px + 4px; }
5.3 嵌套
标签嵌套,有些时候需要直接使用嵌套外层的父选择器,这个时候需要使用&
// SASS 样式 div { color: #333; a { font-size:14px; &:hover { text-decoration:underline; } } } // 编译后css div { color: #333; } div a { font-size:14px; } div a:hover { text-decoration:underline; }
属性也可以嵌套:
// SASS 样式 .fakeshadow { border: { style: solid; left: { width: 4px; color: #888; } right: { width: 2px; color: #ccc; } } } // css 编译后样式 .fakeshadow { border-style: solid; border-left-width: 4px; border-left-color: #888; border-right-width: 2px; border-right-color: #ccc; }
5.4 注释
SASS 有两种注释风格
-
单行注释
// 注释
只保留在SASS源文件中,不会保留在编译后的文件中。 -
标准 CSS 注释
/* 注释 */
, 会保留到编译后的文件中,压缩则删除。-
在标准注释后面加入一个感叹号,
/*! 重要注释 */
表示重要注释,压缩模式也会保留注释,用于版权声明等。
-
5.5 继承
SASS 中,继承可以让一个选择器继承另一个选择器的所有样式
.alert{ padding: 15px; } .alert a{ text-decoration: none; } .alert-info{ @extend .alert; background-color: lightblue; }
使用占位符选择器 % 从 SASS 3.2.0 后,就可以定义占位选择器 %,这个的优势在于,不调用不会有多余的 CSS 文件
// SASS样式 %h1 { font-size:20px; } div { @extend %h1; color:red; } // css编译后样式 div { font-size:20px; color:red; }
5.6 混合(mixin)
SASS 中使用 @mixin
声明混合,可以传递参数,参数名义 $ 符号开始,多个参数以逗号分开,如果参数有多组值,那么在变量后面加三个点表示,如: $var...,定义的混入@mixin
使用 @include
引用
@mixin alert{ color:#ccc; background-color:red; } // SASS 样式 @mixin opacity($opacity:50) { opacity: $opacity / 100; } .opacity{ @include opacity; //参数使用默认值 50/100 = 0.5 } .opacity-80{ @include opacity(80); //传递参数 80/100 = 0.8 } // css编译后样式 .opacity{ opacity: 0.5; } // --------------------- // 多参数 @mixin center($width, $height) { position: absolute; left:50%; top:50%; width:$width; height:$height; margin:(-$height / 2) 0 0 (-$width / 2); } div { @include center(200px, 100px); } // css编译后样式 div { position:absolute; left:50%; top:50%; width:200px; height:100px; margin:-50px 0 0 -100px; } // ------------------- //多组值 @mixin box-shadow($shadow...) { -webkit-box-shadow: $shadow; box-shadow: $shadow; } div { @include box-shadow(0 1px 0 rgba(0,0,0,.4), 0 -1px 1px rgba(0,0,0,.4)); } // css编译后样式 div { -webkit-box-shadow: 0 1px 0 rgba(0,0,0,.4), 0 -1px 1px rgba(0,0,0,.4); box-shadow: 0 1px 0 rgba(0,0,0,.4), 0 -1px 1px rgba(0,0,0,.4); }
@content:在 SASS 3.2.0 中引入, 可以用来解决 CSS3 中 @meidia 或者 @keyframes 带来的问题。它可以使@mixin 接受一整块样式,接收的样式从 @content 开始
// SASS 样式 @mixin max-screen($res){ @media only screen and ( max-width: $res ) { @content; } } @include max-screen(480px) { body { color: red } } //css 编译后样式 @media only screen and (max-width: 480px) { body { color: red } }
使用 @content 解决 @keyframes关键帧的浏览器前缀问题
// 设置关键帧 @mixin keyframes($name) { @-webkit-keyframes #{$name} { @content; } @-moz-keyframes #{$name} { @content; } @-o-keyframes #{$name} { @content; } @keyframes #{$name} { @content; } } // 引入 @include keyframes(scale) { 100% { transform: scale(0.8); } } // css编译后 @-webkit-keyframes scale { 100% { transform: scale(0.8); } } @-moz-keyframes scale { 100% { transform: scale(0.8); } } @-o-keyframes scale { 100% { transform: scale(0.8); } } @keyframes scale { 100% { transform: scale(0.8); } }
5.7 颜色函数
SASS 提供了一些内置的颜色函数
lighten(#cc3, 10%) // #d6d65c darken(#cc3, 10%) // #a3a329
5.8 插入文件
使用 @import 命令引入外部文件, 引入后,可使用外部文件中的变量等。
@import "base.scss";
如果插入的是 .css
文件,则等同于 CSS 的 import 命令。