CSS企业级应用方案(二、Sass预处理器)

预处理器介绍

  • 预处理器基本介绍
  • Sass 快速入门
  • Sass 基础语法
  • Sass 控制指令
  • Sass 混合指令
  • Sass 函数指令
  • Sass 中的 @规则

预处理器基本介绍

平时在工作的时候,经常会面临这样的情况:需要书写很多的样式代码,特别是面对比较大的项目的时候,代码量会急剧提升,普通的 CSS 书写方式不方便维护以及扩展还有复用。

通过CSS预处理技术就可以解决上述问题,基于预处理技术的语言,我们称之为 CSS 预处理语言,该语言会提供一套增强语法,我们在书写CSS的时候就会使用增强语法,书写完毕后通过预处理技术编译为普通的 CSS 语言即可(类似于TypeScript)。

CSS 预处理的出现,解决了如下问题:

  • 代码组织:通过嵌套,模块化和文件引入等功能,使 CSS 代码结构更加清晰,便于管理和维护。
  • 变量和函数:支持自定义变量和函数,增强代码的可复用性和一致性。
  • 代码简洁:通过简洁的语法结构和内置函数,减少代码冗余,提高开发效率。
  • 易于扩展:可以通过插件系统扩展预处理器的功能,方便添加新特性。

目前前端领域常见的 CSS 预处理器有三个:

  • Sass
  • Less
  • Stylus

下面简单介绍下这三种 CSS 预处理器:

Sass

Sass是最早出现的 CSS 预处理器,最早出现为2006年 该预处理器有两种语法格式:

  • 缩进式语法(2006出现)
scss 复制代码
$primary-color: red
.container
    background-color: $primary-color
    padding: 20px
    
    .title
        font-size: 24px
        color: white
    
  • 类 CSS 语法(2009出现)
scss 复制代码
$primary-color: red;
.container {
    background-color: $primary-color;
    padding: 20px;
    
    .title {
        font-size: 24px;
        color: white;
    }
}

Sass 提供了很多丰富的功能例如 嵌套、声明变量、混合、继承、函数等,另外Sass还有强大的社区支持以及丰富的插件资源,因此Sass比较适合大型项目及团队协作。

Less

Less 也是一个比较流行的CSS预处理器,最早出现为2009年,该处理器借鉴了 Sass 的长处,并在此基础上兼容CSS语法,让开发者开发起来更加得心应手。

less 复制代码
@primary-color: red;
.container {
    background-color: @primary-color;
    padding: 20px; 
    
    .title {
        font-size: 24px;
        color: white;
    }
}

早期的 Sass 一开始只有缩进式语法,所以 Less 的出现降低开发者的学习成本,因为 Less 兼容原生 CSS 语法。相较于 Sass,Less 学习曲线平滑,语法简单,但是编程功能相比 Sass 要弱一些,并且插件社区也没有 Sass 那么强大,Less 的出现反而让 Sass 出现了第二版语法(类CSS语法)。

Stylus

Stylus 是一种灵活且强大的 CSS 预处理器,其语法非常简洁,具有很高的自定义性,Stylus 支持多种语法风格包括缩进式语法、类CSS语法,Stylus 提供了丰富的功能,如变量、嵌套、混合、条件语句、循环等。相较于 Sass 和 Less,Stylus 的社区规模较小但仍有不少开发者喜欢其简洁灵活的特点。

  • 缩进式语法
stylus 复制代码
primary-color: red
.container
    background-color: primary-color
    padding: 20px
    
    .title
        font-size: 24px
        color: white
  • 类 CSS 语法
stylus 复制代码
primary-color: red
.container {
    background-color: primary-color;
    padding: 20px; 
    
    .title {
        font-size: 24px;
        color: white;
    }
}

Sass 快速入门

Sass 最早是由 Hampton Catlin 于2006年开发的,并且于2007年首次发布。

在最初的时候,Sass 采用的是缩进敏感语法,文件扩展名为 .sass,编写完毕之后,需要通过基于 ruby 的 Ruby Sass 的编译器进行编译,编译为普通的 CSS。因此在最早期的时候,如果想使用 Sass,是需要安装 Ruby 环境的。

为什么早期选择采用 Ruby 呢?这和当时的 Web 开发大环境有关系,在2006-2010左右,当时 Web 服务器端开发就特别流行基于 Ruby 的 Web 框架 Ruby on Rails。 像早期的 GitHub,Twitter 一开始都是使用的 Ruby。

2009年 Less 的出现给 Sass 带来竞争压力,因为 Less 是基于原生 CSS 语法进行扩展,使用者没有什么学习压力,于是 Natalie Weizenbaum 和 Chris Eppstein 为 Sass 引入类 CSS 语法,也是基于原生 CSS 进行语法扩展,文件后缀名为 .scss。虽然文件的后缀以及语法更新了,但是功能上仍然支持之前 Sass 所支持的所有功能,加上 Sass 本身插件和社区就比 Less 强大,因此 Sass 重新变为了主流。

接下来说下编译器,随着社区发展和技术的进步,Sass 已经不再局限于 Ruby,目前已经有多种语言实现了 Sass 的编译器

  • Dart Sass:由 Sass 官方团队维护,使用 Dart 语言编写,它是目前推荐的 Sass 编译器,因为它是最新的,功能最全的实现。
  • Lib Sass:使用 C/C++ 编写的 Sass 编译器,它的性能优于 Ruby 版本,Lib Sass 有多个绑定,例如 Node Sass(Node绑定)和 SassC(C绑定)。
  • Ruby Sass:最早的 Ruby 实现,已被官方废弃,并且建议迁移到 Dart Sass。

官方推荐使用 Dart Sass 来作为 Sass 的编译器,并且在 npm 上发面布了 Dart Sass 包,直接通过 npm 安装即可。 接下来看一个 Sass 快速上手示例,首先创建一个新的项目目录 sass-demo 使用 pnpm init 初始化,然后使用 pnpm 进行安装依赖:

pnpm add sass -D

接下来在 src/index.scss 里面写入如下代码

scss 复制代码
$primary-color: red;
.container {
    background-color: $primary-color;
    padding: 20px;
    
    .title {
        font-size: 24px;
        color: white;
    }
}

写下来我们使用 Sass 提供的 compile 方法进行编译代码如下:

ini 复制代码
// 读取 scss 文件
// 调用 sass 提供的 compile 方法进行文件的编译
// 最终在 dist 目录下新生成一个 index.css (编译后的文件 )
 
const sass = require('sass'); // 做 scss 文件编译的
const fs = require('node:fs'); // 处理路径相关的
const path = require('node:path');  // 处理文件读写相关的
const scssPath = path.resolve('src','index.scss'); // 定义一下文件输入和输出的文件路径
const cssDir = 'dist'; // 之后编译的 index.scss 要存储的目录名
const cssPath = path.resolve(cssDir,'index.css');
// 编译
const result = sass.compile(scssPath)
// 将编译后的字符串写入到 index.css 文件里面
if(!fs.existsSync(cssDir )){
    fs.mkdirSync(cssDir)
}
fs.writeFileSync(cssPath,result.css)

编译前 编译后

上面的方式,每次都需要手动运行 nodejs 来进行编译,而且还需要手动指定要编译的文件是哪一个,比较麻烦,早期的时候出现了一个专门做 sass 编译的 GUI 工具,叫做考拉

现在随着 VScode 这个集大成的 IDE 的出现,可以直接安装 Sass 相关的插件做编译工作,例如 scss-to-css。注意在一开始安装的时候,该插件进行 scss 转换时压缩 CSS 代码,这个是可以进行配置的。

Sass 基础语法

  • 注释
  • 变量
  • 数据类型
  • 嵌套语法
  • 插值语法
  • 运算

注释

CSS 里面的注释 /* */,Sass 中支持 // 来进行注释,// 类型的注释在编译后是会消失。

scss 复制代码
/*
   Hello
*/

// Hello
css 复制代码
/*
   Hello
*/

然后是压缩输出模式,那么注释也会被去掉,这个时候可以再多行注释的第一个字符书写一个感叹号(!),即便是在压缩模式,这条注释也会保留,通常用于版权信息。

scss 复制代码
/*!
   该 CSS 作者 xxxx
   创建于 xxxx年xx月xxxx日
*/
$primary-color: red;
.container {
    background-color: $primary-color;
    padding: 20px;
    
    .title {
        font-size: 24px;
        color: white;
    }
}
css 复制代码
/*!
   该 CSS 作者 xxxx
   创建于 xxxx年xx月xxxx日
*/.container{background-color:red;padding:20px}.container .title{font-size:24px;color:#fff}

变量

这是当初 Sass 推出时一个极的大亮点,支持变量的声明,声明方式很简单,通过 $ 开头来进行声明,赋值方法和 CSS 属性的写法是一致的。

scss 复制代码
$width: 20px;
$size: 10px;
div{
    width: $width;
    font-size: $size;
}
css 复制代码
div{
    width:20px;
    font-size:10px
 }

变量的声明是支持块级作用域的,如果是在嵌套规则内部定义的变量,只能 在嵌套规则内部使用(局部变量),如果不是在嵌套规则内部定义的变量,那就是全局变量。

scss 复制代码
$width: 1000px;
div{
    $width:600px;
    $color:red;
    p.one{
        width: $width; /* 600px */
        background-color: $color; /* red */
    }
}

p.two{
    width: $width; /* 1000px */
    background-color: $color; /* 报错 因为 ¥color 是一个局部变量 */
}
css 复制代码
div p.one{
    width:600px;
    background-color: red;
}
p.two{
    width:1000px;
}

可以通过一个 !global 将一个局部变量转换为全局变量

scss 复制代码
$width: 1000px;
div{
    $width:600px;
    $color:red !global;
    p.one{
        width: $width;
        background-color: $color;
    }
}

p.two{
    width: $width;
    background-color: $color;
}
css 复制代码
div p.one{
    width:600px;
    background-color: red;
}
p.two{
    width:1000px;
    background-color: red;
}

数据类型

因为 CSS 预处理器就是针对 CSS 这一块融入了编程语言的特性,所以自然会有数据类型。

在 Sass 中支持七种数据类型:

  • 数值类型:1、2、13、10px
  • 字符串类型:有引号字符串和无引号字符串("foo"、'foo'、foo)
  • 布尔类型:true和false
  • 空值类型:null
  • 数组类型(list):用空格或者逗号进行分割,例如 1px 10px 15px 5px 或者 1px,10px,15px, 5px
  • 字典类型(map):用一个小括号括起来,里面是一对一对健值对(key1:value1,key2:value2)
  • 颜色类型:blue、#f40、rgba(0,0,12,0.5)

数值类型

Sass 里面支持两种数值类型,带单位的和不带单位的数值。数字可以是正数、负数、浮点数

scss 复制代码
$width: 1000px;
$height: -100px;
$my-age: 18;
$your-age: 19.5;

字符串类型

支持两种:有引号字符串 和 无引号字符串,并且引号可以是单引号或者是双引号

scss 复制代码
$name: "to bob";
$container: 'to button';
$what: heart;
div{
    background-image: url( $what + '.png'); 
}
css 复制代码
div{
    background-image:url(heart.png)
}

布尔类型

该类型只有两个值:true 和 false 可以进行逻辑运算,支持 and(与)、or(或)、not(非) 来做逻辑运算

scss 复制代码
$a: 1 > 0 and 0 > 5; // false
$b: 'name' == name; // true
$c: false; // false
$d: not $c; // false 

空值类型

就一个值,nnull 表示为空的意思

scss 复制代码
$value:null; // null

因为是空值因此不能和其他类型进算术运算

数组类型

数组有两种表示方式,通过空格来间隔 以及 通过逗号来间隔 例如:

scss 复制代码
$list1: 10px 20px 30px 40px;
$list2: 10px 20px,30px 40px;
$list3: (10px 20px),(30px 40px);

关于数组,有如下注意事项:

  1. 数组里面可包含子数组,例如 10px 20px,30px 40px 就包含了两个数组 10px 20px 是一个数组 30px 40px 是另一个数组。如果数组的内外分隔方式相同,例如都是采用空格来分割,这个时候可以使用小括号来分割 (10px 20px) (30px 40px)。
  2. 添加了小括号的内容最终被编译为 CSS 的时候,是会被去掉小括号的,例如 (10px 20px) (30px 40px) -> 10px 20px 30px 40px
scss 复制代码
$list1: 10px 20px 30px 40px;
$list2: 10px 20px,30px  40px;
$list3: (10px 20px),(30px 40px);


div{
    padding: $list2;
}
css 复制代码
div{
    padding:10px 20px 30px 40px;
}
  1. 小括号内部如果为空,则表示是一个空数组,空数组是不可以直接编译为 CSS 的
scss 复制代码
$list1: 10px 20px 30px 40px;
$list2: 10px 20px,30px  40px;
$list3: (10px 20px),(30px 40px);
$list4: ();
div{
    padding: $list4; /* 报错 */
} 

但是如果是数组里面包含 空数组 或者 null空值,编译能够成功,空数组 以及 null空值 会被去除掉

scss 复制代码
$list1: 10px 20px 30px 40px;
$list2: 10px 20px,30px  40px;
$list3: (10px 20px),(30px 40px);
$list4: 10px 20px null ();

div{
    padding: $list4;
}
css 复制代码
div{
    padding:10px 20px;
}
  1. 可以使用 nth 函数去访问数组里面的值,注意数组的下标是从 1 开始的。
scss 复制代码
$list1: 10px 20px 30px 40px;
$padding: nth($list1, 3);
div{
    padding: $padding;
}
css 复制代码
div{ 
     padding:30px
}

最后我们来看一个在实际开发中用到数组的典型案例:

scss 复制代码
$sizes:  40px 50px 60px;
// #{} Sass 插值语法 相当于 JavaScript 中的模版字符串 ${}
@each $s in $sizes{
    .icon-#{$s} {
        font-size: $s;
        height: $s;
        width: $s;
    }
}
css 复制代码
.icon-40px{
    font-size:40px;
    height:40px;
    width:40px
}
.icon-50px{
    font-size:50px;
    height:50px;
    width:50px
}
.icon-60px{
    font-size:60px;
    height:60px;
    width:60px 
}

字典类型

字典类型必须用小括号扩起来,小括号里面是一对一对的健值对,

scss 复制代码
$map:(
    key1:value1,
    key2:value2
)

可以通过 map-get 方法来获取字典值

scss 复制代码
$colors:(
    primary: #f40,
    secondary: #f25,
    accent: #ff4
);

$primary: map-get($colors , '$primary' );

button{
    background-color: $primary;
}
css 复制代码
button{
    background-color:#f40
}

接下来看一个实际开发中的示例

scss 复制代码
$icons: (
    eye: '\f112',
    start: '\f12e',
    stop: '\f12'
);

@each $key, $value in $icons {
    .icon-#{$key} {
        display: inline-block;
        font-family:'微软雅黑';
        content: $value
    }
}
css 复制代码
 .icon-eye{
    display:inline-block;
    font-family:"微软雅黑";
    content:"f112"
}
.icon-start{
    display:inline-block;
    font-family:"微软雅黑";
    content:"f12e"
}
.icon-stop{
    display:inline-block;
    font-family:"微软雅黑";
    content:"f12"
}

颜色类型

支持原生 CSS 中各种颜色的表示方式,十六进制、RGB、RGBA、HSL、HSLA、颜色英语单词。

Sass 还提供了内置的 Colors 相关的各种函数,可以方便对颜色的一个颜色值进行调整和操作。

  • lighten 和 darken:调整颜色的亮度,lighten 是增加亮度,darken 是减少亮度
scss 复制代码
$colors: red;

.read1 {
    width: 200px;
    height: 100px;
    background-color: lighten($color: $colors, $amount: 10%); // 亮度增加 10%
}
.read2 {
    width: 200px;
    height: 100px;
    background-color: darken($color: $colors, $amount: 10%); // 亮度减少 10%
}
css 复制代码
.read1{
    width:200px;
    height:100px;
    background-color:#f33
}
.read2{
    width:200px;
    height:100px;
    background-color:#c00
}
  • saturate 和 desaturate:调整颜色饱和度
scss 复制代码
$colors: #4caf50;

.read1 {
    width: 200px;
    height: 100px;
    background-color: saturate($color: $colors, $amount: 10%); // 饱和度增加 10%
}
.read2 {
    width: 200px;
    height: 100px;
    background-color: desaturate($color: $colors, $amount: 10%); // 饱和度减少 10%
}
css 复制代码
.read1{
    width:200px;
    height:100px;
    background-color:#3fbc44
}
.read2{
    width:200px;
    height:100px;
    background-color:#59a25c 
}
  • adjust-hue:通过调整颜色的色相来创建新的颜色。
scss 复制代码
$colors: #4caf50;
.read1 {
    width: 200px;
    height: 100px;
    background-color: adjust-hue($color:$colors, $degrees: 30); // 色相增加 30 度 
}
css 复制代码
.read1{
    width:200px;
    height:100px;
    background-color:#4caf82
}
  • rgba:为颜色添加透明度。
scss 复制代码
$colors: #4caf50;
.read1 {
    width: 200px;
    height: 100px;
    background-color: rgba($color: $colors, $alpha: 0.5); // 添加 50% 透明度
}
css 复制代码
.read1{
    width:200px;
    height:100px;
    background-color:rgba(76,175,80,.5)
}
  • mix:混合两种颜色
scss 复制代码
$colors1: #4caf50;
$colors2: #ff4400;
.read1 {
    width: 200px;
    height: 100px;
    background-color: mix($colors1, $colors2, 50%); // 混合两种颜色权重 50%
}
css 复制代码
.read1{
    width:200px;
    height:100px;
    background-color:#a67a28
}

如果想要查阅具有哪些颜色相关的函数,可以参考官方文档 sass-lang.com/documentati...

嵌套语法

嵌套语法是 Sass 刚推出来的时候一大亮点,嵌套语法让开发者在书写 CSS 的时候减少很多代码量。 例如:

scss 复制代码
.container{
    width: 100px;
    height: 100px;
    div{
        width: 30px;
        height: 30px;
        color: red;
    }
    p{
        color: hotpink;
    }
}
css 复制代码
.container{
    width:100px;
    height:100px
}
.container div{
    width:30px;
    height:30px;
    color:red
}
.container p{
    color:hotpink
}

另外还支持一个 & 符号,表示和父选择器结合,如果不加 & ,那么最终编译的时候,会后编译为代选择器,如果书写了 & 符号则会和父选择器结合到一起。

scss 复制代码
a{
    color: yellow;
    &:hover{
        color: green;
    }
    &:active{
        color: red;
    }
}
div{
    width: 100px;
    height: 100px;
    &.one{
        background-color: aqua;
    }
    .two{
        background-color: aquamarine;
    }
}
css 复制代码
a{
    color:#ff0
}
a:hover{
    color:green
}
a:active{
    color:red
}
div{
    width:100px;
    height:100px
}
div.one{
    background-color:aqua
}
div .two{
    background-color:#7fffd4
} 

另外还允许属性的嵌套

scss 复制代码
div{
    font: {
        family :'微软雅黑';
        size:20px;
        weight:600;
    }
}
css 复制代码
div{
    font-family:"微软雅黑";
    font-size:20px;
    font-weight:600
}

插值语法

通过 #{} 进行插值,在 #{} 放入变量,可以解析变量对应的值,类似于 ES6 里面的模版字符串。

scss 复制代码
$name:'foo';
$attr:border;
p.#{$name}{
    #{$attr}-color:red
}
css 复制代码
p.foo{
    border-color:red
}

插值语法可以避免 Sass 去运行运算表达式(calc),直接编译为带有运算表达式的代码原生 CSS 代码。

scss 复制代码
$size: 16px;
$line-height: 1.5;

.div1{
    padding: calc( $size * $line-height * 2 );
}
 
.div2{
    padding: calc(#{$size * $line-height} * 2);
}
css 复制代码
.div1{
    padding:48px
}
.div2{
    padding:calc(24px * 2)
}

运算

关于运算相关的一些函数

  • calc
  • max 和 min
  • clamp

calc

该方法是 CSS3 提供的方法,用于做属性值计算(注意 如果单位相同 Sass 在做编译的时候会直接运行 calc 表达式,得到计算出来的最终值 ,如果单位不相同,会保留 calc 表达式 )

scss 复制代码
div{
    width: 100%;
    .element1{
        width: calc(100% - 20px );
    }
    .element2{
        width: calc(100px - 20px);
    }
}
css 复制代码
div{
    width:100%
}
div .element1{
    width:calc(100% - 20px)
}
div .element2{
    width:80px
}

min 和 max

min 在一组数据里面找到最小值,max 在一组数据里面找到最大值

scss 复制代码
$width1: 500px;
$width2: 600px;
div{
    width: 100%;
    .element1{
        width: min($width1,$width2 );
    }
    .element2{
        width: max($width1,$width2 );
    }
}
css 复制代码
div{
    width:100%
}
div .element1{
    width:500px
}
div .element2{
    width:600px
}

clamp

clamp 也是 CSS3 提供的函数,语法为:clamp(min,value,max)。min 代表下限,max 代表上限,value 是需要限制的值,clamp 的作用就是将 value 值限制在 min 和 max 之间,如果 value 小于 min,则取 min 值,如果 value 大于 max 值,则取 max 值,如果 value 值在 min 和 max 之间,则返回 value 值本身。

Sass 控制指令

CSS 预处理器最强大的功能就是将编程语言的特性融入到 CSS 里面,因此既然 CSS 预处理器里面有变量、数据类型、自然而然也会有流程控制。因为关于流程控制,大家在 JavaScript 里面已经非常熟悉了,所以这里就为大家简介绍下:

  • 三元运算符:语法格式为:if( expression, value1, value2 ) expression 表达式成立返回 value1 否则返回 value2
  • @if:表示为分支,分支分为三种(单分支:@if( expression )、双分支:@if( expression ) @else()、多分支:@if( expression1 ) @else if( expression2 ) @else()
  • @for 循环:语法格式为:@for $var from <start> through <end>(会包含结束值)或者 @for $var from <start> to <end>(不会包含结束值)
  • @while 循环:语法格式为:@while expression,注意一定要在 while 里面书写改变变量的表达式否则形成死循环
  • @each 循环:语法格式为:@each $var in $vars( <math xmlns="http://www.w3.org/1998/Math/MathML"> v a r 可以是任何变量名, var 可以是任何变量名, </math>var可以是任何变量名,vars 只能是 list 数组类型或者 map 字典类型), 有点类似于 JavaScript 里面的 for...of 循环,会把数组或者字典类型的每一项都取出来。

Sass 混合指令

在 Sass 里面存在一种叫做混合指令的东西,踏足大的特点就是允许我们创建可以复用的代码片段,从而避免代码重复,提高代码的可维护性。

混合指令基本使用

要使用混合指令,首先要先定义一个混合指令,语法格式为:@mixin name { 样式代码... },使用混合指令@include name

scss 复制代码
// 创建混合指令
@mixin large-test {
    font: {
        family: '微软雅黑';
        size: 20px;
        weight: 600;
    }
}
// 使用混合指令
div {
    width: 100%;
    color: red;
    @include large-test()
}
css 复制代码
div{
    width:100%;
    color:red;
    font-family:"微软雅黑";
    font-size:20px;
    font-weight:600
}

混合指令的参数

在混合指令的后面添加一对圆括号即可,圆括号里面书写对应的形参,语法格式为:@mixin name ( $arguments ) { }。在定义混合指令的时候,指定了参数,在使用时传递的参数一定要和形参一致,否则 Sass 在编译的时候会出错或者在定义形参的时候可以给形参添加默认值,添加了默认值之后,在使用的时候即使没有传递参数,它就会使用默认值。在传递参数的时候还支持关键词传参,就指定哪一个参数对应哪一个形参。如果在使用混合指令的地方会传递多少个参数,可以使用 ... 来声明,类似于 JavaScript 里面的不定参数,Sass 会把这些值当做一个列表来处理

scss 复制代码
// 创建混合指令
@mixin large-test ($color,$radius:20px) {
    font: {
        family: '微软雅黑';
        size: 20px;
        weight: 600;
    }
    border-color: $color;
    border-radius: $radius;
}
@mixin box-shadow ($shadow...){
    box-shadow: $shadow;
}
// 使用混合指令
.div1{
    width: 100%;
    @include large-test(red,50px)
} 
.div2{
    width: 100%;
    @include large-test(green) // 使用默认值
}
.div3{
    width: 100%;
    @include large-test($radius:100px, $color:yellow) // 使用关键词传参
} 
.div4{
    width: 100%;
    height: 20px;
    @include box-shadow(0 1 1 0 rgba(0,0,255,0.5), 1 1 1 1 rgba(255,0,200,0.7)) //不确定形参个数
} 
css 复制代码
.div1{
    width:100%;
    font-family:"微软雅黑";
    font-size:20px;
    font-weight:600;
    border-color:red;
    border-radius:50px
}
.div2{
    width:100%;
    font-family:"微软雅黑";
    font-size:20px;
    font-weight:600;
    border-color:green;
    border-radius:20px
}
.div3{
    width:100%;
    font-family:"微软雅黑";
    font-size:20px;
    font-weight:600;
    border-color:#ff0;
    border-radius:100px
}
.div4{
    width:100%;
    height:20px;
    box-shadow:0 1 1 0 rgba(0,0,255,.5),1 1 1 1 rgba(255,0,200,.7)
}

Sass 函 数指令

  • 自定义函数:在 Sass 里面自定义函数的语法如下:
scss 复制代码
@function fn-name ($arguments...){
    @retrun xxxx
}

通过可以接收多个参数,如果不确定有几个参数,可以使用不定参数的形式

使用时例如下:

scss 复制代码
@function divide ($a,$b){ 
    @return  $a / $b
};
.container{
    width: divide(100px,2 );
}

@function sun ($sums...){
    $sum:0;
    @each $n in $sums{
        $sum:$sum + $n
    }
    @return $sum
};
.container1{
    width: sun(1,2,3,4,5) + px;
}

@function container-color ($background-color){
    $brightness:red($background-color)* 0.299 + green($background-color) * 0.587 + blue($background-color )* 0.114;
    @if($brightness > 128) {
        @return #000;
    } @else {
        @return #fff
    }
};

.container2{
    $background-color:#46facc;
    width: sun(1,2,3,4,5) + px;
    background-color: $background-color;
    color: container-color($background-color);
}
css 复制代码
.container{
    width:50px
}
.container1{
    width:15px
}
.container2{
    width:15px;
    background-color:
    #46facc;color:#000 
}
  • 内置函数: 除了自定义函数,Sass 里面还提供了非常多的内置函数,可以在官方文档查看 sass-lang.com/documentati...

下面介绍一下比较常用的内置函数:

字符串相关 内置函数

函数名和参数类型 函数作用
quote($string) 添加引号
unquote($string) 去除引号
to-lower-case($string) 转小写
to-upper-case($string) 转大写
str-length($string) 返回 $string 的长度(汉字算一个)
str-index( <math xmlns="http://www.w3.org/1998/Math/MathML"> s t r i n g , string, </math>string,substring) 返回 <math xmlns="http://www.w3.org/1998/Math/MathML"> s u b s t r i n g 在 substring 在 </math>substring在string 的位置
str-insert( <math xmlns="http://www.w3.org/1998/Math/MathML"> s t r i n g , string, </math>string,insert,$index) 在 <math xmlns="http://www.w3.org/1998/Math/MathML"> s t r i n g 的 string 的 </math>string的index 处插入 $insert
str-slice( <math xmlns="http://www.w3.org/1998/Math/MathML"> s t r i n g , string, </math>string,start-at,$end-at) 截取 <math xmlns="http://www.w3.org/1998/Math/MathML"> s t r i n g 的 string 的 </math>string的start-at 和 $end-at 之间的字符串
注意索引是从 1 开始的,如果书写 -1,那么就是倒着来的。

数字相关内置函数

函数名和参数类型 函数作用
percentage($number) 转为百分比形式
round($number) 四舍五入为整数
ceil($number) 数值向上取整
floor($number) 数值向下取整
abs($number) 获取绝对值
min($number) 获取最小值
max($number) 获取最大值
random($number) 不传入值:获取 0:1 之间的随机数,传入正整数 n,获取 0:n 之间的随机整数 (左开右闭

数组相关内置函数

函数名和参数类型 函数作用
length($list) 获取数组长度
nth( <math xmlns="http://www.w3.org/1998/Math/MathML"> l i s t , list, </math>list,n) 获取指定下标的元素
set-nth( <math xmlns="http://www.w3.org/1998/Math/MathML"> l i s t , list, </math>list,n,$value) 向 <math xmlns="http://www.w3.org/1998/Math/MathML"> l i s t 的第 list 的第 </math>list的第n 处插入 $value
join( <math xmlns="http://www.w3.org/1998/Math/MathML"> l i s t 1 , list1, </math>list1,list2,$separator) 拼接 <math xmlns="http://www.w3.org/1998/Math/MathML"> l i s t 1 和 list1 和 </math>list1和list2 ,$separator 为新的 list 的分隔符,默认为 auto,可选择为 comma、space
append( <math xmlns="http://www.w3.org/1998/Math/MathML"> l i s t , list, </math>list,val,$separator) 向 list 末尾添加 <math xmlns="http://www.w3.org/1998/Math/MathML"> v a l , val, </math>val,separator 为 新的 list 分隔符,默认为 auto,可选择为 comma、space
index( <math xmlns="http://www.w3.org/1998/Math/MathML"> l i s t , list, </math>list,value) 返回 <math xmlns="http://www.w3.org/1998/Math/MathML"> v a l u e 值在 value 值在 </math>value值在list 中的索引
zip($list...) 将多个列表结合成一个多维列表,要求每个的列表个数值必须相同 的

字典相关内置函数

函数名和参数类型 函数作用
map-get( <math xmlns="http://www.w3.org/1998/Math/MathML"> m a p , map, </math>map,key) 获取 <math xmlns="http://www.w3.org/1998/Math/MathML"> m a p 中 map 中 </math>map中key 对应的 $value
map-merge( <math xmlns="http://www.w3.org/1998/Math/MathML"> m a p 1 , map1, </math>map1,map2) 合并 <math xmlns="http://www.w3.org/1998/Math/MathML"> m a p 1 和 map1 和 </math>map1和map2 返回一个新的 $map
map-remove( <math xmlns="http://www.w3.org/1998/Math/MathML"> m a p , map, </math>map,key) 从 <math xmlns="http://www.w3.org/1998/Math/MathML"> m a p 中删除 map 中删除 </math>map中删除key 返回一个新的 $map
map-key($map) 返回 <math xmlns="http://www.w3.org/1998/Math/MathML"> m a p 中所有的 map 中所有的 </math>map中所有的key
map-values($map) 返回 <math xmlns="http://www.w3.org/1998/Math/MathML"> m a p 中所有的 map 中所有的 </math>map中所有的value
map-has-key( <math xmlns="http://www.w3.org/1998/Math/MathML"> m a p , map, </math>map,key) 判断 <math xmlns="http://www.w3.org/1998/Math/MathML"> m a p 中是否存在 map 中是否存在 </math>map中是否存在key 返回布尔值
keywords($args) 返回一个函数的参数,并可以动态修改其值

颜色相关内置函数

RGB 函数

函数名和参数类型 函数作用
rgb( <math xmlns="http://www.w3.org/1998/Math/MathML"> r e d , red, </math>red,green,$blue) 返回一个十六进制颜色值
rgba( <math xmlns="http://www.w3.org/1998/Math/MathML"> r e d , red, </math>red,green, <math xmlns="http://www.w3.org/1998/Math/MathML"> b l u e , blue, </math>blue,alpha) 返回 rgba: <math xmlns="http://www.w3.org/1998/Math/MathML"> r e d , red, </math>red,green 和 $blue 可以被当做一个整体颜色单词、hsl、rgb和十六进制形式传入
red($color) 从 $color 中获取其绿色值
green($color) 从 $color 中获取其绿色值
blue($color) 从 $color 中获取其蓝色值
mix( <math xmlns="http://www.w3.org/1998/Math/MathML"> c o l o r 1 , color1, </math>color1,color2,$weiht) 按照 <math xmlns="http://www.w3.org/1998/Math/MathML"> w e i h t 比例,将 weiht 比例,将 </math>weiht比例,将color1 和 $color2 混合为一个新的颜色
HSL 函数
函数名和参数类型 函数作用
--- ---
hsl( <math xmlns="http://www.w3.org/1998/Math/MathML"> h u e , hue, </math>hue,saturaion,$lightness) 通过色相(hue),饱和度(saturaion)和亮度(lightness)的值创建一个颜色
hsla( <math xmlns="http://www.w3.org/1998/Math/MathML"> h u e , hue, </math>hue,saturaion, <math xmlns="http://www.w3.org/1998/Math/MathML"> l i g h t n e s s , lightness, </math>lightness,alpha) 通过色相(hue),饱和度(saturaion)、亮度(lightness)和透明度(alpha)的值创建一个颜色
saturation($color) 从一个颜色中获取饱和度(saturation)值
lightness($color) 从一个颜色中获取饱和度(lightness)值
adjust-hue( <math xmlns="http://www.w3.org/1998/Math/MathML"> c o l o r , color, </math>color,degrees) 通过改变一个颜色的色相值,创建一个新的颜色
lighten( <math xmlns="http://www.w3.org/1998/Math/MathML"> c o l o r , color, </math>color,amount) 通过改变一个颜色的亮度值,让颜色变亮,创建一个新的颜色
darken( <math xmlns="http://www.w3.org/1998/Math/MathML"> c o l o r , color, </math>color,amount) 通过改变一个颜色的亮度值,让颜色变暗,创建一个新的颜色
hue($color) 从一个颜色中获取亮度色相(hue)值
Opacity 函数
函数名和参数类型 函数作用
alpha( <math xmlns="http://www.w3.org/1998/Math/MathML"> c o l o r ) / o p a c i t y ( color)/opacity( </math>color)/opacity(color) 获取颜色透明度值
rgba( <math xmlns="http://www.w3.org/1998/Math/MathML"> c o l o r , color, </math>color,alpha) 改变颜色的透明度
opacify( <math xmlns="http://www.w3.org/1998/Math/MathML"> c o l o r , color, </math>color,amount)/fade-in( <math xmlns="http://www.w3.org/1998/Math/MathML"> c o l o r , color, </math>color,amount) 使颜色更不透明
transparentize( <math xmlns="http://www.w3.org/1998/Math/MathML"> c o l o r , color, </math>color,amount)/fade-out( <math xmlns="http://www.w3.org/1998/Math/MathML"> c o l o r , color, </math>color,amount) 使颜色更透明

其他内置函数

函数名和参数类型 函数作用
type-of($value) 返回 $value 值的类型
unit($number) 返回 $number 的单位
unitless($number) 判断 $number 是否带单位 返回布尔值
comparable( <math xmlns="http://www.w3.org/1998/Math/MathML"> n u m b e r 1 , number1, </math>number1,number2) 判断 <math xmlns="http://www.w3.org/1998/Math/MathML"> n u m b e r 1 和 number1 和 </math>number1和number2 是否可以做加、减和合并,返回的对应布尔值
还有一些其他函数,请参考官方文档 sass-lang.com/docu mentation/modules 。

@规则

在原生 CSS 中存在一些 @ 开头的规则,例如 @import、@media Sass 对这些规则完全支持,不仅支持,还在原有的基础上做了一些扩展。

@import

在原生 CSS 里面,@import 是导入其他 CSS 文件,Sass 在此基础上做了一些增强:

  • 编译时合并:Sass 在编译时将导入的文件内容合并到生成的 CSS 文件中,这意味着只会生成一个 CSS 文件,而不像原生 CSS 那样需要额外的 HTTP 请求去加载导入的文件。
  • 变量、函数和混合体共享:Sass 允许在导入的文件共享变量、函数和混合体,这有助于组织代码并避免重复。
  • 部分文件:Sass 支持将文件名后缀_的文件称之为部分文件(partials)。当使用 @import 指令导入部分文件时,Sass 不会生成一个单独的 CSS 文件,而是将内容合并到朱文件中,这有助于更好的组织项目。
  • 文件扩展名可选:在 Sass 中使用 @import 可以忽略文件扩展名(.scss或.sass),Sass 会自动识别并导入正确的文件。
  • 嵌套导入:Sass 允许一个文件中嵌套导入其他文件,请注意,嵌套导入的文件并在父级上下文中编译,这可能会导致输出的 CSS 文件中的选择器层级不符合预期。

通常情况下在使用 @import 导入文件时,不给后缀名,会自动寻找 Sass 文件并将其导入。但是某些情况下,会编译为普通的 CSS 语句,并不会导入任何文件:

  • 文件扩展名为 css
  • 文件名以 http:// 开头
  • 文件名是 url()
  • @import 包含 media queries

@media

这个规则在 CSS 里面是做媒体查询,Sass 里面是完全支持的,并且做了一些增强操作。

  • Sass 允许将 @media 嵌套在选择器内部
  • 允许使用变量
  • 可以使用混合体

@extent

在书写 CSS 样式时候,会遇到这么一种情况, 一个元素使用样式基本和另一个元素相同,但是又增加了一些额额外的样式,这个时候我们就可以使用继承,Sass 里面提供了 @extent 来实现继承,让一个选择器继承另外一个选择器的样式规则。

如果是刚接触的同学,可能会觉着 @extent 和 @mixin 比较相似,感觉都是把公共的样式提取出来,但是两者其实是不同的

  • 参数支持:@mixin 支持传递参数,使其更具灵活性,而 @extent 不支持参数传递
  • 生成的 CSS:@extent 会将选择器合并,生成更紧凑的 CSS,并其所继承的样式在最终生的 CSS 样式中也是真实存在的,而 @mixin 会在每个 @include 处生成完整的 CSS 代码,做的就是一个简单的 CSS 替换
  • 使用场景:@extent 更适用于继承已有样式的情况,例如 UI 中的通用样式。而 @mixin 更适用于自定义参数的情况,例如为不同组件生成类似样式。

有些时候我们需要定义一套用于继承的样式,不希望 Sass 单独编译输出,那么这个时候可以使用 % 作为占位符

@at-root

有些时候,我们会涉及到将嵌套规则移动到根级别(声明的时候并没有书写在根级别)。这个时候就可以使用 @at-root。如果想要移动的是一组规则,这个时候需要在 @at-root 后面添加一对大括号,将想要移动的这一组样式放入大括号里面。

@debug、@warn、@error

这三个是和调试相关的,可以在编译过程中输出一条信息,有助于调试和诊断代码中的问题。

相关推荐
码爸18 分钟前
flink doris批量sink
java·前端·flink
深情废杨杨19 分钟前
前端vue-父传子
前端·javascript·vue.js
J不A秃V头A1 小时前
Vue3:编写一个插件(进阶)
前端·vue.js
司篂篂2 小时前
axios二次封装
前端·javascript·vue.js
姚*鸿的博客2 小时前
pinia在vue3中的使用
前端·javascript·vue.js
宇文仲竹3 小时前
edge 插件 iframe 读取
前端·edge
Kika写代码3 小时前
【基于轻量型架构的WEB开发】【章节作业】
前端·oracle·架构
天下无贼!4 小时前
2024年最新版Vue3学习笔记
前端·vue.js·笔记·学习·vue
Jiaberrr4 小时前
JS实现树形结构数据中特定节点及其子节点显示属性设置的技巧(可用于树形节点过滤筛选)
前端·javascript·tree·树形·过滤筛选
赵啸林4 小时前
npm发布插件超级简单版
前端·npm·node.js