Sass 是世界上最成熟、最稳定、最强大的专业级 CSS 扩展语言!
Sass (Syntactically Awesome Style Sheets)是一种流行的预处理器脚本语言,用于扩展CSS的功能。
什么是预处理器
预处理器是在程序源文件被编译之前根据预处理指令对程序源文件进行处理的程序。说白了,预处理器只不过是一个文本替换工具而已。
CSS 预处理器则是通过将有特殊语法和指令的源代码处理成浏览器可使用的 CSS 文件的程序。
Vue2和Vue3中的Sass使用
Vue2提供了Sass的内置支持
在Vue2中使用Sass有两种方法:
1. 全局使用
要在Vue2中全局使用Sass,
请使用以下命令安装sass-loader和sass包:
npm install sass-loader sass --save-dev
在项目的根目录中创建一个名为vue.config.js的文件,并添加以下代码:
module.exports = {
css: { // 配置 CSS 相关的 loader
loaderOptions: { // loader 选项
sass: { // 配置 Sass 的选项
data: `@import "@/styles/main.scss";`
// @import 为引入
// @/styles/main.scss 引入的路径,即要处理的文件
}
}
}
};
2. 作用域使用
在Vue2中按照组件使用Sass:
<template>
<div class="demo-component">
<!-- Component HTML code here -->
</div>
</template>
<script>
export default {
// Component configuration options
};
<style lang="scss" scoped>
.demo-component {
// Sass code for the component
}
</style>
Vue3也提供了对Sass的内置支持
Vue2和Vue3,命令安装sass-loader和sass包的命令相同
在项目的根目录中创建一个名为vite.config.js的文件,并添加以下代码:
1. 全局使用
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue'; // 引入`@vitejs/plugin-vue`插件,用于支持 Vue 单文件组件(SFC)
export default defineConfig({ // 使用`defineConfig`函数定义配置对象
plugins: [vue()], // 在`plugins`数组中添加`vue`插件,以便在构建过程中处理 Vue SFC
css: {
preprocessorOptions: { // 定义预处理器选项
scss: { // 定义`scss`预处理器的选项
additionalData: `@import '@/styles/main.scss';`
// 它使用`@import`语句引入`main.scss`文件,即要传递给 Scss 预处理器处理的文件
}
}
}
});
2. 作用域使用
在Vue3中,scoped属性已被module属性替换。
<template>
<div class="demo-component">
<!-- Component HTML code here -->
</div>
</template>
<script>
export default {
// Component configuration options
};
<style lang="scss" module>
.demo-component {
// Sass code for the component
}
</style>
下面将列出了Sass最有用的一些功能
变量
<style lang="scss" scoped>
$defaultLinkColor: #46EAC2; // 定义一个名为 `$defaultLinkColor` 的变量
a {
color: $defaultLinkColor;
}
</style>
当你运行这个命令后,你的 $defaultLinkColor 变量会被替换为它的实际值(在这个例子中是 #46EAC2),然后应用到所有的 <a> 标签上。
- 方便重复使用、便于局部和全局的样式风格统一控制
字符串插值
<style lang="scss" scoped>
$wk: -webkit-;
.rounded-box {
#{$wk}border-radius: 4px;
}
</style>
一般不使用这样的写法,因为有些浏览器不支持 -webkit- 前缀(例如 Firefox 不支持 -webkit- 前缀)
嵌套写法
// css 原生写法
.page .content .left-side .profile .name{
font-size: 2rem;
}
.page .content .left-side .profile .age{
color: red;
}
// scss 写法
.page{
.content{
.left-side{
.profile{
.name{
font-size: 2rem;
}
.age{
color: red;
}
}
}
}
}
// 两种写法编译后
.page .content .left-side .profile .name{font-size: 2rem;}
.page .content .left-side .profile .age{color: red;}
- 结构清晰简洁,并且可与 html 文档结构对应起来;
- 减少了大量冗余重复的选择器编码;
模块(片段)
// _base.scss
$font-stack: Helvetica, sans-serif;
$primary-color: #333;
// 注意以下划线开头的 Scss 文件
// styles.scss
@use 'base'; // 导入一个Sass模块,并给它一个本地名称 `base`
.inverse {
background-color: base.$primary-color;
color: white;
}
// 编译 css 为:
.inverse {
background-color: #333;
color: white;
}
混合(Mixins)
@mixin heading-font {
font-family: sans-serif;
font-weight: bold;
}
h1 {
@include heading-font;
}
// 编译后
h1 {
font-family: sans-serif;
font-weight: bold;
}
- 抽离公共的样式片段,便于多处复用;
- 将公共的样式片段放在单独的文件里,便于项目的多个文件复用;
- 对 html 的使用没有任何要求,css 自己家的事自己关起门来解决,绝不麻烦别人;
混合的进阶用法
$default-padding: 10px;
@mixin pad($n: $default-padding) { // $n 为参数 & $default-padding 为函数默认值
padding: $n;
}
body {
@include pad(15px);
}
继承(Extend)
.msg{
border: 1px solid #e3e3e3;
background: #dff0d8;
}
.msg-success{
@extend .msg;
color: #4cae4c;
}
.msg-error{
@extend .msg;
color: #d43f3a;
}
// 编译后
.msg, .msg-success, .msg-error {
border: 1px solid #e3e3e3;
background: #dff0d8;
}
.msg-success {
color: #4cae4c;
}
.msg-error {
color: #d43f3a;
}
上面的效果使用混合(mixin)也可以完成。但不同的是:继承拷贝的是选择器,而混合(mixin)拷贝的是样式片段。
函数
$baseFontSize: 20;
@function px2rem($val) {
@return $val/$baseFontSize + rem;
}
.big-text{
font-size: px2rem(30);
}
// 编译后
.big-text {
font-size: 1.5rem;
}
Sass有很多模块或库,可以引入使用,实现代码的重用和模块化
// 引入math-module模块
@use 'path/to/math-module';
// 使用math.min函数
$widths: 50px, 30px, 100px;
$minWidth: math.min($widths...);
// 输出最小宽度
@debug $minWidth;
使用math.min函数来计算一系列像素宽度中的最小值,并将结果存储在变量$minWidth中.
Sass 判断 --- @if
当 @if 的表达式返回值不是 false 或者 null 时,条件成立,输出 {} 内的代码:
p {
@if 1 + 1 == 2 { border: 1px solid; }
@if 5 < 3 { border: 2px dotted; }
@if null { border: 3px double; }
}
// 编译为
p {
border: 1px solid;
}
@if 声明后面可以跟多个 @else if 声明,或者一个 @else 声明。如果 @if 声明失败,Sass 将逐条执行 @else if 声明,如果全部失败,最后执行 @else` 声明,例如:
$type: monster;
p {
@if $type == ocean {
color: blue;
} @else if $type == matador {
color: red;
} @else if $type == monster {
color: green;
} @else {
color: black;
}
}
// 编译为
p {
color: green;
}
Sass 循环 --- @for循环
@for 指令可以在限制的范围内重复输出格式,每次按要求(变量的值)对输出结果做出变动。
$base-color: #036;
@for $i from 1 through 3 {
ul:nth-child(3n + #{$i}) {
background-color: lighten($base-color, $i * 5%);
}
}
// 编译 css 为:
ul:nth-child(3n + 1) {
background-color: #004080;
}
ul:nth-child(3n + 2) {
background-color: #004d99;
}
ul:nth-child(3n + 3) {
background-color: #0059b3;
}
Sass 循环 --- @each循环(简单)
$sizes: 40px, 50px;
@each $size in $sizes {
.icon-#{$size} {
font-size: $size; height: $size;
}
}
// 编译 css 为:
.icon-40px {
font-size: 40px;
height: 40px;
}
.icon-50px {
font-size: 50px;
height: 50px;
}
Sass 循环 --- @each循环(嵌套)
$icons: ("eye": "\f112", "start": "\f12e");
@each $name, $glyph in $icons {
.icon-#{$name}:before {
display: inline-block;
font-family: "Icon Font";
content: $glyph;
}
}
// 编译 css 为:
.icon-eye:before {
display: inline-block;
font-family: "Icon Font";
content: "";
}
.icon-start:before {
display: inline-block;
font-family: "Icon Font";
content: "";
}
Sass 循环 --- @while循环
@use "sass:math";
// 将 `$value` 除以 `$ratio` 直到它低于 `$base`
@function scale-below($value, $base, $ratio: 1.618) {
@while $value > $base {
$value: math.div($value, $ratio);
}
@return $value;
}
$normal-font-size: 16px;
sup {
font-size: scale-below(20px, 16px);
}
// 编译 css 为:
sup {
font-size: 12.36094px;
}