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

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

相关推荐
y先森1 小时前
CSS3中的伸缩盒模型(弹性盒子、弹性布局)之伸缩容器、伸缩项目、主轴方向、主轴换行方式、复合属性flex-flow
前端·css·css3
前端Hardy1 小时前
纯HTML&CSS实现3D旋转地球
前端·javascript·css·3d·html
susu10830189111 小时前
vue3中父div设置display flex,2个子div重叠
前端·javascript·vue.js
IT女孩儿2 小时前
CSS查缺补漏(补充上一条)
前端·css
吃杠碰小鸡3 小时前
commitlint校验git提交信息
前端
虾球xz4 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇4 小时前
HTML常用表格与标签
前端·html
疯狂的沙粒4 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript
小镇程序员4 小时前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js
野槐4 小时前
前端图像处理(一)
前端