Sass 入门
什么是 CSS 预处理?
定义
CSS预处理器定义了一种新的语言, 其基本思想是用一种专门的编程语言, 为CSS增加了一些编程的特性, 将CSS作为目标生成文件, 然后开发者就只要使用这种语言就可进行编码工作
通俗的说, CSS预处理器是用一种专门的编程语言, 进行Web页面样式设计, 然后再编译成正常的CSS文件以供项目使用, CSS预处理器为CSS增加一些编程的特性, 无需考虑浏览器的兼容性问题
例如你可以在CSS中使用变量、简单的逻辑程序、函数等等在编程语言中的一些基本特性, 可以让你的CSS更加简洁、适应性更强、可读性更佳、更利于代码的维护等诸多好处
CSS 预处理语言
Sass(SCSS)LessStylusTurbineSwithch CSSCSS CacheerDT CSS
Sass 简介
定义
Sass是一门高于CSS的元语言, 它能用来清晰地、结构化地描述文件样式, 有着比普通CSS更加强大的功能
Sass能够提供更简洁、更优雅的语法, 同时提供多种功能来创建可维护和管理的样式表
前世今生
Sass是最早的CSS预处理语言, 有比Less更为强大的功能, 不过其一开始的缩进式语法并不能被大众接受, 不过由于其强大的功能和Ruby on Rails的大力推动, 还是有很多开发者选择了Sass
Sass是采用Ruby语言编写的一款CSS预处理语言, 它诞生于2007年, 是最大最成熟的CSS预处理语言, 最初它是为了配合HTML而设计的, 因此有着和HTML一样的缩进式风格
基本使用
$num: 6px;
$side: left;
.test {
border-#{$side}-radius: $num;
}Sass、SCSS 与 CSS
Sass与SCSS其实是一个东西, 我们平时都称之为Sass, 不同之处有:
- 文件扩展名不同,
Sass是以.sass后缀为扩展名, 而SCSS是以.scss后缀为扩展名 - 语法书写方式不同,
Sass是以严格的缩进式语法规则来书写, 不带大括号{}和分号;, 而SCSS的语法书写和CSS语法书写方式非常类型 - 由于
Sass是基于Ruby写出来的, 所以延续了Ruby的书写规范, 与CSS写法存在一定的差异 SCSS与CSS写法无差别, 可将现有的.css文件改成.scss即可使用
示例
Sass语法:
$font-stack: Helvetica, sans-serif;
$primary-color: #333;
body
font: 100% $font-stack
color: $primary-colorSCSS语法:
$font-stack: Helvetica, sans-serif;
$primary-color: #333;
body {
font: 100% $font-stack;
color: $primary-color;
}- 编译出来的
CSS:
body {
font: 100% Helvetica, sans-serif;
color: #333;
}环境安装
确保本地已经安装并配置了 Node 环境
使用 npm 本地安装 Sass
1. 进入项目目录
确保项目有package.json, 如果没有, 先运行npm init -y生成
cd your-project2. 本地安装 Sass 作为开发依赖
npm install sass --save-dev--save-dev表示 Sass 仅用于开发环境, 不会影响生产代码- 安装后,
package.json的devDependencies会新增:
"devDependencies": {
"sass": "^1.66.1"
}3. 运行 Sass
1. 直接使用npx临时调用本地安装的 Sass
npx会自动查找项目本地的sass命令, 无需全局安装
npx sass input.scss output.css2. 通过npm scripts(推荐)
在package.json的scripts中添加:
"scripts": {
"sass:build": "sass src/scss/:dist/css/",
"sass:watch": "sass --watch src/scss/:dist/css/"
}然后运行:
npm run sass:build # 单次编译
npm run sass:watch # 监听文件变化自动编译使用 Yarn 本地安装
1. 本地安装 Sass
yarn add sass --dev2. 运行 Sass
yarn sass input.scss output.css或通过 package.json 脚本(与npm的相同)
在构建工具中集成(如 Webpack/Vite)
如果你使用现代前端工具(如Webpack、Vite、Parcel), 可以直接通过插件使用 Sass, 无需手动运行命令
示例: Vite 项目
- 安装 Sass:
npm install sass --save-dev- 直接在
.vue或.scss文件中使用:
<style lang="scss">
$color: red;
body { color: $color; }
</style>Vite会自动编译, 无需额外配置!
基础
声明变量
Sass的变量包括三个部分:
$声明变量的符号- 变量名称
- 赋予变量的值
- 在值后面加上
!default表示默认值, 可根据需求来覆盖
Sass语法:
// SCSS
$w: 100px;
$h: 200px;
$h: 300px !default;
.text {
width: $w;
height: $h;
}编译后的CSS:
.test {
width: 100px;
height: 200px;
}局部/全局变量
Sass从3.4版本开始已经可以正确处理作用域的概念, 并通过创建一个新的局部变量来替代
Sass语法:
// SCSS
$color: red; // 全局变量
.block {
color: $color; // 全局变量
}
em {
$color: blue; // 局部变量
a {
color: $color; // 局部变量
}
}
span {
color: $color; // 全局变量
}嵌套
Sass的嵌套分为三种:
- 选择器嵌套
- 属性嵌套
- 伪类嵌套
选择器嵌套
HTML代码结构
<header>
<nav>
<a>Home</a>
<a>About</a>
<a>Blog</a>
</nav>
</header>CSS代码:
nav a {
color: red;
}
header nav a {
color: green;
}Sass使用选择器写为:
nav {
a {
color: red;
header & {
color: green;
}
}
}属性嵌套
CSS中有一些属性前缀相同, 只是后缀不同时可使用属性嵌套写法:
CSS样式代码:
.box {
border-top: 1px solid #000;
border-bottom: 1px solid red;
}Sass使用属性嵌套:
.box {
.border {
top: 1px solid #000;
bottom: 1px solid red;
}
}伪类嵌套
Sass中借助&符合实现伪类嵌套:
Sass样式代码:
.clearFix {
&:before,
&:after {
content: "";
display: table;
}
&:after {
clear: both;
overflow: hidden;
}
}- 编译后的
CSS:
.clearFix:before,
.clearFix:after {
content: "";
display: table;
}
.clearFix:after {
clear: both;
overflow: hidden;
}混合宏
如果网页中有几处小样式类似, 可以在Sass中使用变量来统一处理, 但当样式越来越复杂, 需要重复使用大段的样式时, 使用混合宏就变得非常有意义
在不同地方调用相同的混合宏时, 并不能智能的将相同的样式代码合并在一起, 也是Sass的不足之处
声明混合宏
在Sass中使用@mixin来声明一个混合宏, 后面是混合宏的名称, 大括号中时复用的样式代码
使用@include来调用声明好的混合宏
- 不带参数的混合宏:
@mixin border-radius {
-webkit-border-radius: 5px;
border-radius: 5px;
}
button {
@include border-radius;
}- 带参数的混合宏:
@mixin border-radius($radius) {
-webkit-border-radius: $radius;
border-radius: $radius;
}
button {
@include border-radius(5px);
}
// 可设置默认值, 没传参时使用默认值, 传参时替换默认值
@mixin border-radius($radius: 3px){
-webkit-border-radius: $radius;
border-radius: $radius;
}- 复杂混合宏:
可传多个参数
@mixin center($w, $h) {
width: $w;
height: $h;
position: absolute;
top: 50%;
left: 50%;
margin-top: -($h) / 2;
margin-left: -($w) / 2;
}
.box-center {
@include center(500px, 300px);
}
Sass的混合宏可提供带有逻辑关系的, 可使用...表示带有多个参数,@if...@else逻辑关系判断
@mixin box-shadow($shadow...) {
@if length($shadow) >= 1{
// 当的传参长度大于等于 1 时:
-webkit-box-shadow: $shadow;
box-shadow: $shadow;
} @else {
// 否则:
$shadow: 0 0 4px rgba(0, 0, 0, .3);
-webkit-box-shadow: $shadow;
box-shadow: $shadow;
}
}
// 调用
.box {
@include box-shadow(0 0 1px rgba(#000, .5), 0 0 2px rgba(#000, .2));
}
// 编译为 CSS
.box {
-webkit-box-shadow: 0 0 1px rgba(0,0,0,0.5),0 0 2px rgba(0,0,0,0.2);
box-shadow: 0 0 1px rgba(0,0,0,0.5),0 0 2px rgba(0,0,0,0.2);
}继承
Sass中使用@extend来继承已存在的类样式块, 从而实现代码继承
Sass代码:
.btn {
border: 1px solid #ccc;
padding: 6px 10px;
font-size: 14px;
}
.btn-primary {
background-color: #F36;
color: #FFF;
@extend .btn;
}
.btn-sec {
background-color: orange;
color: #000;
@extend .btn;
}- 编译后的
CSS:
/*
可继承样式块中所有的样式的代码
而且编译出来的 CSS 会将选择器合并在一起, 形成组合选择器
*/
.btn, .btn-primary, .btn-sec {
border: 1px solid #ccc;
padding: 6px 10px;
font-size: 14px;
}
.btn-primary {
background-color: #F36;
color: #FFF;
}
.btn-sec {
background-color: orange;
color: #000;
}占位符
Sass中的占位符%(placeholder)功能是一个很强大很实用的功能, 可以取代CSS中基类造成的代码冗余的情形, 因为Sass中%(placeholder)声明的代码, 如果没有被@extend调用的话, 不会产生任何代码
Sass代码:
%mt {
margin-top: 5px;
}
%pt {
padding-top: 10px;
}
.btn {
@extend %mt;
@extend %pt;
}
.block {
@extend %mt;
span{
@extend %mt;
}
}- 编译后的
CSS:
.btn, .block {
margin-top: 5px;
}
.btn, .block span {
padding-top: 10px;
}混合宏、继承和占位符的使用场景
混合宏
使用场景
若代码块中涉及到变量, 建议使用混合宏来创建相同的代码块
缺点
如果样式文件中调用同一个混合宏, 会产生多个对应的样式代码, 不会自动合成相同的样式代码, 造成代码的冗余
继承
使用继承会将编译出来的CSS代码块通过组合选择器的方式合并到一起
使用场景
若代码块不需要传任何变量参数, 且有一个基类已经在文件中存在, 建议使用继承
缺点
不能传变量参数
占位符
编译出来的CSS代码和使用继承基本上是相同的, 主要区别为:
- 占位符是独立定义的, 不调用的时候是不会在
CSS中产生任何代码 - 继承是首先有一个基类存在, 不管调用与不调用, 基类的样式都会出现在编译后的
CSS代码中
插值
使用Sass可以获得一个更好的结构体系, 使用插值能写出更干净、高效和面向对象的CSS
设置属性值
Sass代码:
$properties: (margin, padding);
@mixin set-value($side, $value) {
@each $prop in $properties {
#{$prop}-#{side}: $value;
}
}
.box {
@include set-value(top, 14px);
}- 编译后的
CSS:
.box {
margin-top: 14px;
padding-top: 14px;
}构建选择器
Sass代码:
@mixin generate-sizes($class, $small, $medium, $big) {
.#{$class}-small{ font-size: $small; }
.#{$class}-medium{ font-size: $medium; }
.#{$class}-big{ font-size: $big }
}
@include generate-size("header-text", 12px, 20px, 40px);- 编译出来的
CSS:
.header-text-small {
font-size: 12px;
}
.header-text-medium {
font-size: 20px;
}
.header-text-big {
font-size: 40px;
}WARNING
不能使用插值替换变量名, 会导致此变量删除
$margin-big: 40px;
@mixin set-value($size) {
margin-top: $margin-#{$size};
}
.box {
@include set-value(big);
}
// 报错: error style.scss (Line 5: Undefined variable: “$margin-".)WARNING
不能使用插值替换混合宏名称
@mixin update-status {
margin-top: 20px;
background: #FFF;
}
$flag: "status";
.box{
@include update-#{$flag};
}
// 报错: error style.scss (Line 7: Invalid CSS after "...nclude updated-": expected "}", was "#{$flag};")WARNING
可以在@extend中使用插值
%updated-status {
margin-top: 20px;
background: #FFF;
}
.selected-status {
font-weight: bold;
}
$flag: "status";
.box {
@extend %updated-#{$flag};
@extend .selected-#{$flag};
}
// @extend 中可正常使用注释
- 类似
CSS的注释方式, 使用/* 这是一个注释 */, 编译后会在CSS中显示 - 类似
JS的注释方式, 使用// 这是一个注释, 编译后不会在CSS中显示
数据类型
Sass和JS语言类似, 也具有自己的数据类型:
- 数字, 如
1 2 13 10px等 - 字符串, 有
/无引号字符串, 如"foo" 'bar' baz等 - 颜色, 如
blue #FFF rgba(255,0,0,0.5)等 - 布尔型, 如
true false - 空值, 如
null - 值列表, 空格或者逗号分开, 如
1.5em 1 2px、sans-serif, Helvetica, Arial等
字符串
SassScript支持CSS的两种字符串类型:
- 有引号字符串
- 无引号字符串
在编译CSS文件时不会改变其类型, 只有使用#{}插值表达语句时, 有引号字符串会被编译为无引号字符串, 当deprecated = property syntax时, 所有字符串都将被编译为无引号字符串
Sass代码:
@mixin firefox-message($selector){
body.firefox #{$selector}:before {
content: "Hi Firefox users!";
}
}
@include firefox-message(".header");- 编译后的
CSS:
body.firefox .header:before{
content: "Hi Firefox users!";
}值列表
通过空格或者逗号分隔的一系列的值:
margin: 10px 15px 0 0font-face: Helvetica, Arial, sans-serif
Sass列表函数赋予了值列表更多功能:
nth函数(nth function)可以直接访问值列表中的某一项join函数(join function)可以将多个值列表连接在一起append函数(append function)可以在值列表中 添加值@each规则(@each rule)能够给值列表中的每一项添加样式
()表示空的列表, 但是这样不可以直接编译成CSS, 只有一个()会报错, 多个时将清除空值
运算
程序中的运算是常见的一件事情, 但在CSS中能做运算的目前仅有calc()函数
在Sass中可以做各种数学计算, 运算只是基本特性之一
加/减
Sass在变量或属性中都可以做加/减法运算
Sass代码:
$full-height: 960px;
$side-height: 100px;
.box {
width: 20px + 800px;
height: $full-height - $side-height;
}- 编译出来的
CSS:
.box {
width: 820px;
height: 860px;
}- 携带不同类型的单位时计算会报错:
.box{
width: 20px + 1em;
}
// 报错: Incompatible units: 'em' and ‘px'.乘/除
乘/除法运算与加/减法运算略有不同:
Sass直接使用/符号作为除号时, 将不会生效单独除法运算需要搭配
()使用已有的数学表达式中运算不需要使用
()用于变量计算不需要使用
()Sass代码:
$num: 200px;
.box {
width: 10px * 2;
height: (100px / 5);
margin-left: 100px / 2 + 2in;
margin-top: round(1.5) / 2;
padding-right: $num / 10;
}- 编译后的
CSS:
.box {
width: 20px;
height: 20px;
margin-left: 242px;
margin-top: 4;
padding-right: 20px;
}- 同一单位或不同单位运算时会报错:
.box {
width: 10px * 2px; // 报错: 20px*px isn't a valid CSS value.
height: 20px * 4em; // 40em*px isn't a valid CSS value.
}变量计算
Sass中除了可以使用数值进行运算之外, 还可以使用变量进行计算
Sass代码:
$c-width: 720px;
$s-width: 220px;
$gutter: 20px;
.container {
width: $c-width + $s-width + $gutter;
}- 编译后的
CSS:
.container {
width: 960px;
}数字运算
Sass中可以通过()来修改运算的先后顺序
Sass代码:
.box {
width: ((220px + 720px) - 11 * 20) / 12;
}- 编译后的
CSS:
.box {
width: 60px;
}颜色运算
所有算数运算都支持颜色值, 使用红、绿、蓝各颜色分段单独进行运算
Sass代码:
p {
color: #010203 + #040506;
background: #010203 * 2;
}- 编译后的
CSS:
p {
color: #050709;
background: #020406;
}字符运算
Sass中可以通过+号来对字符串进行连接
Sass代码:
$content: "Hello" + "" + "Sass!";
.box:before {
content: " #{$content} ";
}
div {
cursor: e + -resize;
font-family: sans- + "serif";
}- 编译后的
CSS:
.box:before {
content: " Hello Sass! ";
}
div {
cursor: e-resize;
font-family: sans-serif;
}