likes
comments
collection

Vue组件库必备 Sass(Dart) 知识

作者站长头像
站长
· 阅读数 31

前言

Sass 有三个版本 Dart SasslibsassRuby Sass

  • Dart Sass:用 Dart 语言写的 sass 实现,于2016年11月1日发布 alpha 版本,版本1.23.0之后完全支持模块化机制。
  • libSass 也就是俗称的 node-sass,用 c/c++ 实现的 sass 版本,使用广泛,其中 node-sass 是绑定了 libsassnodejs 库,可以极快的将 .scss 文件编译为 .css 文件,安装过程很慢,官方也不推荐再使用了。
  • Ruby Sass 是最初的 Sass 实现,但是2019年3月26日被停止了,以后也不会再支持,使用者需要迁移到别的实现上

Sass 官方团队在2020年10月也正式宣布 Libsass 将弃用,以及基于它的 Node SassSassC,并且建议用户使用 Dart Sass,主要有以下几点说明:

  • 不再建议将 LibSass 用于新的 Sass 项目, 改为使用 Dart Sass
  • 建议现有的 LibSass 用户制定计划,最终迁移到 Dart Sass,并且所有 Sass 库都制定计划,最终放弃对 LibSass 的支持。
  • 不再计划向 LibSass 添加任何新功能,包括与新 CSS 功能的兼容性。
  • LibSassNode Sass 将在尽力而为的基础上无限期维护,包括修复主要的错误和安全问题以及与最新的 Node 版本兼容。

为什么使用 Dart Sass

目前 Dart Sass 已经作为 Sass 最新的版本了,当执行 npm install sass -D 默认使用的是 Dart Sass 包,vue-cliVite 脚手架默认也是使用最新版本 Dart sass,而且不需要安装 node-sass【之前安装 node-sass 经常失败】

另外,element-plus 组件库也是使用 dart dass 模块的 sass:map@use 重构了所有的 SCSS 变量,解决了由 @import 造成的重复输出问题。

所以,为了获得 sass 提供更多更强大的功能,强烈推荐使用 dart sass

安装使用

如果之前安装了 node-sass,可以先卸载

npm uninstall node-sass

安装 dart-sass

npm install sass sass-loader@^10.1.1 -D

注意:之前安装 sass-loader 版本是 13.0+,版本过高导致报错,提示 TypeError: this.getOptions is not a function,退回 10.+ 可以运行成功

如果项目之前用到 /deep/ 需要替换为 ::v-deep,全局搜索 /deep/ , 将项目里的 /deep/ 替换为 ::v-deep

SCSS变量

scss 变量命名规则

  • 以美元符号 $ 开头,后面跟变量名;且必须先定义,后使用
  • 变量名不能以数字开头,可包含字母、数字、下划线、横线(连接符)
  • 通过连接符 - 与下划线 _ 定义的同名变量为同一变量
  • 写法同 css,即变量名和值之间用冒号 : 分隔
$color:#F00;
p {
    color: $color;
}

编译为

p {
    color: #F00;
}

SCSS 变量有两种作用域:全局变量域局部变量域

  • 全局变量:声明在最外层的变量,可在任何地方使用;或在局部变量添加 !global 声明
  • 局部变量:嵌套规则内定义的变量只能在嵌套规则内使用
$color: red;
.container {
    $height: 500px;
    $font-size: 16px !global; // 全局变量,外部可以使用
    font-size: $font-size;
    color: $color;
    height: $height;
}
.footer {
    /**$font-size使用!global 申明成全局变量了*/
    font-size: $font-size; 
    /**
    * Error: Undefined variable. 
    * $height是.container下的局部变量,无法在.footer下面编译
    */
    height:$height;
}

编译 css

.container {
    font-size: 16px;
    color: red;
    height: 500px;
}

.footer {
     /**$font-size使用!global 申明成全局变量了*/
    font-size: 16px;
}

CSS 变量

Sass 默认支持css变量,通过 scss 变量 和 css 变量管理可以很容易实现换肤,element-plus 是这样实现的

css 变量 声明一个自定义属性,属性名需要以两个减号(--)开始,定义变量 --变量名:变量值 例如: --main-color: black;,由 var() 函数来获取值,例如 color: var(--main-color)

:root {
    --main-color: #F00;
}
p {
    color: var(--main-color);
}

:root 是在 HTML 文档的任何地方都可以访问到它

注意: 自定义属性名是大小写敏感的,--my-color 和 --My-color 会被认为是两个不同的自定义属性

通过 JavaScript 获取或者修改 CSS 变量和操作普通 CSS 属性是一样

// 获取一个 Dom 节点上的 CSS 变量
element.style.getPropertyValue("--my-var");

// 获取任意 Dom 节点上的 CSS 变量
getComputedStyle(element).getPropertyValue("--my-var");

// 修改一个 Dom 节点上的 CSS 变量
element.style.setProperty("--my-var", jsVar + 4);

SCSS 数据类型

  • 数字:1rem2vh1310px
  • 字符串:分有引号字符串与无引号字符串,"foo"'bar'baz
  • 颜色:blue, #04a3f9, rgba(255,0,0,0.5)
  • 布尔型:truefalse
  • 空值:null 是其类型的唯一值。表示缺少值,通常由函数返回以表示缺少结果;
  • 数组 (list):用空格或逗号作分隔符,1.5em 1em 02em,Helvetica,Arial,sans-serif
  • maps:相当于 JavaScriptobject 对象,格式括号包裹键值对,逗号隔开 (key1: value1, key2: value2)
// 数字
$layer-index: 10;
$border-width: 3px;

// 字符串
$font-weight: bold;

// 数组
$font-base-family: "Open Sans", Helvetica, Sans-Serif;
$block-base-padding: 6px 10px 6px 10px;

// 颜色
$top-bg-color: rgba(255, 147, 29, 0.6);

// 布尔值
$blank-mode: true;

// null
$var: null;

// maps 值
$fonts: (
  serif: "Helvetica Neue",
  monospace: "Consolas",
);

.container {
  // 内部变量
  font-family: $font-base-family;
  font-size: $font-size;
  padding: $block-base-padding;

  @if $blank-mode {
    background-color: #000;
  } @else {
    background-color: #fff;
  }

  content: type-of($var);
  content: length($var);
  color: $top-bg-color;
}

// 如果列表中包含空值,则生成的CSS中将忽略该空值。
.wrap {
  font: 18px $font-weight map-get($fonts, "sans");
}

!default

可以在变量的结尾添加 !default 来给变量设置默认值,有点类似 Javascript 的逻辑运算符 let content=value || "default value" 。注意,变量是 null 时将视为未被 !default 赋值

// 如果$content之前没使用 !default,没办法赋值覆盖
$content: "First content";
$content: "Second content" !default;
#main {
    content: $content;
}

编译成 css

#main {
  content: "First content";
}

插值语句

通过 #{} 插值语句可以在选择器、属性名、注释中使用变量,使用 #{} 插值语句将变量包裹起来即可,和 js 中的 模板字符串 很像

$font-size: 12px;
$line-height: 30px;
$class-name: danger;
$attr: color;
$author: "福大命大";

p {
    font: #{$font-size}/#{$line-height} Arial Helvetica, sans-serif;
}

/* 
* 这是文件的说明部分
* @author: #{$author}
*/

a.#{$class-name} {
    border-#{$attr}: #f00;
}

编译为css

p {
    font: 12px/30px Arial Helvetica, sans-serif;
}

/* 
* 这是文件的说明部分
* @author: 福大命大
*/
a.danger {
    border-color: #f00;
}

条件语句 @if

@if 语法和 js 类似,基本格式是 @if...@else if...@else

$theme:3;
.container {
    @if $theme >= 5 {
        background-color: red;
    }
    @else {
        background-color: blue;
    }
}

编译为 css

.container {
    background-color: blue;
}

@for 循环

for 在条件范围内重复操作,这个指令包含两种格式:

  • @for $var from start through end
  • @for $var from start to end

两者区别在于 throughto 的含义

  • 使用 through 时,条件范围包含 startend 的值;
  • 使用 to 时条件范围只包含 start 的值不包含 end 的值;

$var 可以是任何变量,比如 $istartend 必须是整数值。

@for $i from 1 to 3 {
  #loading span:nth-child(#{$i}) {
      width: 20 * ($i - 1) + px;
  }
}

编译为 css

#loading span:nth-child(1) {
    width: 0px;
}

#loading span:nth-child(2) {
    width: 20px;
}

如果把 to 换成 through

#loading span:nth-child(1) {
    width: 0px;
}

#loading span:nth-child(2) {
    width: 20px;
}

#loading span:nth-child(3) {
    width: 40px;
}

@each 循环

@each 指令的格式是 @each $var in $list , $var 可以是任何变量名,比如 $length 或者 $name,而 $list 是一连串的值,也就是值列表

$color-list:red green blue turquoise darkmagenta;
@each $color in $color-list {
    $index: index($color-list, $color);
    .p#{$index - 1} {
        background-color: $color;
    }
}

编译为 css

.p0 {
    background-color: red;
}

.p1 {
    background-color: green;
}

.p2 {
    background-color: blue;
}

.p3 {
    background-color: turquoise;
}

.p4 {
    background-color: darkmagenta;
}

@while 循环

@while 指令循环输出直到表达式返回结果为 false。这样可以实现比 @for 更复杂的循环。比如,可以借此生成栅格化布局

$column:12;
@while $column>0 {
   .col-sm-#{$column} {
      width: $column / 12 * 100%;
   }
    $column:$column - 1;
}

编译为 css

.col-sm-12 {
    width: 100%;
}

.col-sm-11 {
    width: 91.6666666667%;
}

.col-sm-10 {
    width: 83.3333333333%;
}

.col-sm-9 {
    width: 75%;
}

.col-sm-8 {
    width: 66.6666666667%;
}

.col-sm-7 {
    width: 58.3333333333%;
}

.col-sm-6 {
    width: 50%;
}

.col-sm-5 {
    width: 41.6666666667%;
}

.col-sm-4 {
    width: 33.3333333333%;
}

.col-sm-3 {
    width: 25%;
}

.col-sm-2 {
    width: 16.6666666667%;
}

.col-sm-1 {
    width: 8.3333333333%;
}

@import

scss 拓展了 @import 的功能,允许其导入 scss或 sass文件。被导入的文件将合并编译到同一个 css 文件中,被导入的文件中所包含的变量或者混合指令 (mixin) 都可以在导入的文件中使用。

common.scss

$color:red;

index.scss

@import "common.scss";
.container {
    border-color: $color;
}

编译为 css

.container {
  border-color: red;
}

以下情况下,@import 仅作为普通的 css 语句,不会导入 scss 文件:

  • 文件拓展名是 .css
  • 文件名以 http:// 开头;
  • 文件名是 url()
  • @import 包含媒体查询。
@import "common.css";
@import url(common);
@import "http://xxx.com/xxx";
@import 'landscape' screen and (orientation:landscape);

scss 允许同时导入多个文件,例如同时导入 a.scssb.scss 两个文件,不用再单独写个 import 引入

@import "a", "b";

@Partials

如果需要导入 scss 或者 sass 文件,但又不希望将其编译为 css,只需要在文件名前添加下划线,这样会告诉 scss 不要编译这些文件。 注意:

  • 导入语句中不需要添加下划线
  • 不可以同时存在添加下划线与未添加下划线的同名文件,添加下划线的文件将会被忽略

_common.scss

$color:red;

index.scss

@import "common.scss";
.container {
    border-color: $color;
}

编译为

.container {
  border-color: red;
}

_common.scss 文件不会编译成 _common.css 文件,Partials 主要是用来定义公共样式的,专门用于被其他的 scss 文件 import 进行使用的

@mixin

混合指令(Mixin)用于定义可重复使用的样式。混合指令可以包含所有的css规则,绝大部分 scss 规则,甚至可以通过参数功能引入变量,输出多样化的样式;

@mixin@include 配合使用

// 定义一个区块基本的样式
@mixin block {
    width: 96%;
    margin-left: 2%;
    border-radius: 8px;
    border: 1px #f6f6f6 solid;
}
// 使用混入 
.container {
    .block {
        @include block;
    }
}

编译为 css

.container .block {
    width: 96%;
    margin-left: 2%;
    border-radius: 8px;
    border: 1px #f6f6f6 solid;
}

@mixin 可以定义多个参数和默认值

// 定义块元素内边距,参数指定默认值
@mixin block-padding($top:0, $right:0, $bottom:0, $left:0) {
    padding-top: $top;
    padding-right: $right;
    padding-bottom: $bottom;
    padding-left: $left;
}

// 可指定参数赋值
.container {
    /** 不带参数 */
    @include block-padding;
    /** 按顺序指定参数值 */
    @include block-padding(10px,20px);
    /** 给指定参数指定值 */
    @include block-padding($left: 10px, $top: 20px)
}

编译 CSS

.container {
    /** 不带参数 */
    padding-top: 0;
    padding-right: 0;
    padding-bottom: 0;
    padding-left: 0;
    /** 按顺序指定参数值 */
    padding-top: 10px;
    padding-right: 20px;
    padding-bottom: 0;
    padding-left: 0;
    /** 给指定参数指定值 */
    padding-top: 20px;
    padding-right: 0;
    padding-bottom: 0;
    padding-left: 10px;
}

可变参数:使用 ... 处理参数不固定的情况,类似于js中的函数的剩余参数

@mixin linear-gradient($direction, $gradients...) {
    background-color: nth($gradients, 1);
    background-image: linear-gradient($direction, $gradients);
}

.table-data {
    @include linear-gradient(to right, #F00, orange, yellow);
}

编译为

.table-data {
    background-color: #F00;
    background-image: linear-gradient(to right, #F00, orange, yellow);
}

总结

  • mixin 是可以重复使用的一组 css 声明,有助于减少重复代码,只需声明一次,就可在文件中引用;
  • 使用参数时建议加上默认值;
  • @import 导入局部模块化样式(类似功能、同一组件);
  • @minix 定义的是可重复使用的样式

@function 函数

@function 用于封装复杂的操作,可以很容易地以一种可读的方式抽象出通用公式和行为,函数提供返回值,常用来做计算方面的工作

@function 参数默认值

//change-color和hue是内置方法
//hue 返回$color的颜色为0到360度之间的一个数字。
//change-color 用于设置颜色的属性
@function invert($color, $amount: 100%) {
    //@error hue($color); 调试 210deg
    $inverse: change-color($color, $hue: hue($color) + 180);
    @return mix($inverse, $color, $amount);
}

$primary-color: #036;
.header {
    background-color: invert($primary-color, 80%);
}

编译 CSS

.header {
    background-color: #523314;
}

可变参数 看作 js function 的 rest 参数

@function sum($numbers...) {
    $sum: 0;
    @each $number in $numbers {
        $sum: $sum + $number;
    }
    @return $sum;
}

$widths: 50px, 30px, 100px;
.micro {
    width: sum($widths...);
}

编译为 CSS

.micro {
    width: 180px;
}

@return 只允许在 @function 内使用,和 js 一样,遇到 return 就会返回

总结

  • @function@mixin 参数的使用方式没啥区别;
  • @function 用来计算,@mixin 用来封装样式,@import 用来抽离他们为一个模块

@extend继承

elementUIel-button 组件为例,可以使用 @extend 继承已经存在的样式,使用逗号选择器。

// # id选择器一样的
.button {
    display: inline-block;
    margin-bottom: 0;
    font-weight: normal;
    text-align: center;
    white-space: nowrap;
    vertical-align: middle;
    cursor: pointer;
    background-image: none;
    border: 1px solid transparent;
    padding: 6px 12px;
    font-size: 14px;
    line-height: 1.42857143;
    border-radius: 4px;
    user-select: none;
}

.btn-default {
    @extend .button;
    color: #333;
    background-color: #fff;
    border-color: #ccc;
}

.btn-danger {
    @extend .button;
    color: #fff;
    background-color: #d9534f;
    border-color: #d43f3a;
}

编译成 css

.button, .btn-danger, .btn-default {
    display: inline-block;
    margin-bottom: 0;
    font-weight: normal;
    text-align: center;
    white-space: nowrap;
    vertical-align: middle;
    cursor: pointer;
    background-image: none;
    border: 1px solid transparent;
    padding: 6px 12px;
    font-size: 14px;
    line-height: 1.42857143;
    border-radius: 4px;
    user-select: none;
}

.btn-default {
    color: #333;
    background-color: #fff;
    border-color: #ccc;
}

.btn-danger {
    color: #fff;
    background-color: #d9534f;
    border-color: #d43f3a;
}

占位符选择器

占位符选择器 %,与常用的 idclass 选择器写法相似,只是 #. 替换成了 %,占位符选择器必须通过 @extend 指令调用

.button %base {
    display: inline-block;
    margin-bottom: 0;
    font-weight: normal;
    text-align: center;
    white-space: nowrap;
    vertical-align: middle;
    cursor: pointer;
    background-image: none;
    border: 1px solid transparent;
    padding: 6px 12px;
    font-size: 14px;
    line-height: 1.42857143;
    border-radius: 4px;
    user-select: none;
}
        
.btn-default {
    @extend %base;
    color: #333;
    background-color: #fff;
    border-color: #ccc;
}

.btn-danger {
    @extend %base;
    color: #fff;
    background-color: #d9534f;
    border-color: #d43f3a;
}

效果和上面的类选择器一样,但是,他有个有优点,占位符选择器% 所属的样式未使用时,不会被编译到 css 文件中

.button .btn-danger, .button .btn-default {
    display: inline-block;
    margin-bottom: 0;
    font-weight: normal;
    text-align: center;
    white-space: nowrap;
    vertical-align: middle;
    cursor: pointer;
    background-image: none;
    border: 1px solid transparent;
    padding: 6px 12px;
    font-size: 14px;
    line-height: 1.42857143;
    border-radius: 4px;
    user-select: none;
}

.btn-default {
    color: #333;
    background-color: #fff;
    border-color: #ccc;
}

.btn-danger {
    color: #fff;
    background-color: #d9534f;
    border-color: #d43f3a;
}

@use

存在兼容性问题,仅在 Dart Sass 1.23.0 以上有效,官方文档有兼容性介绍

css 真正意义上的模块化,可以从其它 scss 样式表中加载 mixinfunction 和变量,并将来自多个样式表的 css 组合在一起。scss 还提供了很多内置模块,我们可以通过 @use 使用,官方也推荐使用 @use 替换 @import,后续会废弃 @import

@import缺点

  • 多处导入,存在样式重复加载。
  • 没有命名空间,为了避免撞名,不敢使用简写的 classname,因此起名总是需要注意。
  • 没有私有函数的概念,样式完全暴露在使用 import 的地方,这对ui库不够友好

@use 使用默认带有命名空间,也可以重命名空间

src/_corners.scss

$radius: 3px;
@mixin rounded {
    border-radius: $radius;
}

index.scss

@use "src/corners"; // 默认命名空间 corners
// @use "src/corners" as c; // 重命名空间
.button {
    @include corners.rounded;
    padding: 5px + corners.$radius;
    // padding: 5px + c.$radius; // 重命名 c 引用
}

as * 让模块处于全局命名空间,不需要带上命名空间就可以直接使用

$radius: 3px;
@mixin rounded {
    border-radius: $radius;
}

使用

@use "src/corners" as *;

.button {
    @include rounded;
    padding: 5px + $radius;
}

私有模块

变量使用 - 开头,@use 不会引入这个变量

$-radius: 3px;

@mixin rounded {
    border-radius: $-radius;
}

index.scss

@use "src/corners";

.button {
    @include corners.rounded;
    // Error: Private members can't be accessed from outside their modules
    padding: 5px + corners.$-radius;
}

@forward

@forward 可以看作是转发,在当前模块引入另一个模块的所有变量、mixins 和函数,直接向外暴露 API,不会在当前模块增加代码,不同于 @use@forward 不能给变量添加命名空间

例如在 bootstrap.css 引入 functionsvariablesmixins 文件,不能直接在 bootstrap.scss 文件中使用这些引入的模块。而是需要在另一个文件中引入 @use bootstrap 模块,再去使用这些方法

/* bootstrap.scss */
@forward"functions";
@forward"variables";
@forward"mixins";

@forward 通过控制 showhide 显示或隐藏模块中的某些变量

a.scss

@mixin rounded {
    border-radius: 100px;
}
footer {
    height: 1px;
}

b.scss

$radius: 3px;

c.scss
```scss
@forward "a" show rounded;
@forward "b" hide $radius;

index.scss

@import "c.scss";

.button {
    @include rounded;
    padding: $radius;
}
// Error: Undefined variable. padding: $radius;

@at-root

@at-root 用来跳出嵌套,在多级嵌套时比较常用,包含 withoutwith

//没有跳出
.parent-1 {
    color:#f00;
    .child {
        width:100px;
    }
}

//单个选择器跳出
.parent-2 {
    color:#f00;
    @at-root .child {
        width:200px;
    }
}

//多个选择器跳出
.parent-3 {
    background:#f00;
    @at-root {
        .child1 {
            width:300px;
        }
        .child2 {
            width:400px;
        }
    }
}

编译为

.parent-1 {
    color: #f00;
}
.parent-1 .child {
    width: 100px;
}

.parent-2 {
    color: #f00;
}
.child {
    width: 200px;
}

.parent-3 {
    background: #f00;
}
.child1 {
    width: 300px;
}

.child2 {
    width: 400px;
}

@without和with

默认 @at-root 只会跳出选择器嵌套,而不能跳出 @media@support,如果要跳出这两种,则需使用@at-root (without: media)@at-root (without: support)@at-root 的关键词有四个

  • all 表示所有;
  • rule 表示常规 css 选择器;
  • media 表示 media
  • support 表示 support@support主要是用于检测浏览器是否支持css的某个属性)

默认的 @at-root@at-root (without:rule)

/*跳出父级元素嵌套*/
@media print {
    .parent1{
        color:#f00;
        @at-root .child1 {
            width:200px;
        }
    }
}

/*跳出media嵌套,父级有效*/
@media print {
    .parent2{
        color:#f00;
        @at-root (without: media) {
            .child2 {
                width:200px;
            }
        }
    }
}

/*跳出media和父级*/
@media print {
    .parent3{
        color:#f00;
        @at-root (without: all) {
            .child3 {
                width:200px;
            }
        }
    }
}

编译成

/*跳出父级元素嵌套*/
@media print {
    .parent1 {
        color: #f00;
    }
    .child1 {
        width: 200px;
    }
}
/*跳出media嵌套,父级有效*/
@media print {
    .parent2 {
        color: #f00;
    }
}
.parent2 .child2 {
    width: 200px;
}
/*跳出media和父级*/
@media print {
    .parent3 {
        color: #f00;
    }
}
.child3 {
    width: 200px;
}

@at-root与 & 配合使用

.child{
    @at-root .parent &{
        color:#f00;
    }
}

编译为

.parent .child {
    color: #f00;
}

SCSS 内置拓展

scss内置扩展分为 color, list, map, math, meta, selector, string 等,扩展也就是 scss 内置的一些 function,相当于 JS 内置方法

内置函数可以使用 @use 模块化引入,也可以直接使用他提供的全局函数名调用,以下两种方式是一样的。

@use 'sass:list';
p {
    color: nth($list: red blue green, $n: 2); // blue
    color: list.nth($list: red blue green, $n: 2); // blue
}

String 字符串函数

scss 有许多处理字符串的函数

  • quote($string):向字符串添加引号
quote(hello) //"hello"
  • unquote($string) 移除字符串的引号
unquote("hello") //hello
  • str-index($string, $substring) 返回 substring 子字符串第一次在 string 中出现的位置。如果没有匹配到子字符串,则返回 null。区分大小写。
str-index(abcd, a) // 1 
str-index(abcd, ab) // 1 
str-index(abcd, X) // null
  • str-length($string) 获取字符串长度
str-length("hello") //5
  • string-insert($string, $insert, $index) 在字符串 string 中 index 位置插入 insert
str-insert("Hello world!", " xiaoming", 6) //"Hello xiaoming world!"
  • str-slice($string, $start-at, $end-at: -1) 从 string 中截取子字符串,通过 start-at 和 end-at 设置始末位置,未指定结束索引值则默认截取到字符串末尾。和 js 感觉有点相似
str-slice("abcd", 2, 3)   => "bc" 
str-slice("abcd", 2)      => "bcd" 
str-slice("abcd", -3, -2) => "bc" 
str-slice("abcd", 2, -2)  => "bc"

其他

  • to-lower-case(*string*) 将字符串转成小写
  • to-upper-case(*string*) 将字符串转成大写
  • unique-id() 返回一个无引号的随机字符串作为 id

事例代码

p {
    &:after {
        content: quote(这是里面的内容);
    }
    background-color: unquote($string: "#F00");
    z-index:str-length("scss学习");
}

编译结果

p {
    background-color: #F00;
    z-index: 6;
}
p:after {
    content: "这是里面的内容";
}

Math 数学函数

Math 数值函数处理数值计算

  • abs(number) 返回一个数值的绝对值
abs(13) // 13 
abs(-13) // 13
  • comparable(num1, num2) 返回一个布尔值,判断 num1 与 num2 是否可以进行比较 ,注意是否可以比较,不是比较的结果
comparable(15px, 10px) // true 
comparable(20mm, 1cm) // true 
comparable(35px, 2em) // false
  • ceil(*number*) 向上取整
ceil(13.24) //14
  • floor(*number*) 向下取整
floor(15.84) // 15
  • max(number... 返回最大值
max(5, 7, 9, 0, -3, -7) // 9
  • min(number... 返回最小值
min(7, 2, 0, -2, -7) // -7
  • percentage(number):将数字转化为百分比的表达形式
percentage(1.2) // 120
  • random():返回 0-1 区间内的小数,
random() // 0.2783
  • random(number)如果传入 number 参数,返回 1 至 number 之间的整数,包括 1 和 limit
random(10) // 4
  • round(number):返回最接近该数的一个整数,四舍五入
round(15.20) // 15 round(15.80) // 16
  • div($number1, $number2) //=> number 返回 $number2 除以 $number1 结果
@debug math.div(1, 2); // 0.5
@debug math.div(100px, 5px); // 20
@debug math.div(100px, 5); // 20px
@debug math.div(100px, 5s); // 20px/s
@debug math.percentage(0.2); // 20%

事例代码

p {
    z-index: abs(-15); // 15
    z-index: ceil(5.8); //6
    z-index: max(5, 1, 6, 8, 3); //8
    opacity: random(); // 随机 0-1
}

编译为

p {
    z-index: 15;
    z-index: 6;
    z-index: max(5, 1, 6, 8, 3);
    opacity: 0.8636254167;
}

List 列表函数

List 特点

  • List 函数可以访问列表中的值,向列表添加元素,合并列表等。
  • List 列表是不可变的,因此在处理列表时,返回的是一个新的列表,而不是在原有的列表上进行修改。
  • 列表的起始索引值为 1,记住不是 0

List 方法

  • append(*list*, *value*, [*separator*]) 将单个值 value 添加到列表尾部。separator 是分隔符,默认会自动侦测,或者指定为逗号或空格,分别用 commaspace 表示
append((a b c), d) // a b c d 
append((a b c), (d), comma) // a, b, c, d
  • index(list, value) 返回元素 value 在列表中的索引位置
index(a b c, b) // 2 
index(a b c, f) // null
  • is-bracketed(list) 判断列表中是否有中括号
is-bracketed([a b c]) // true 
is-bracketed(a b c) // false
  • list-separator(list) 返回一列表的分隔符类型。可以是空格或逗号
list-separator(a b c) // "space"
list-separator(a, b, c) // "comma"
  • join(list1, list2, [separator, bracketed]) 合并两列表,将列表 list2 添加到列表 list1 的末尾。separator 是分隔符,默认会自动侦测,或者指定为逗号或空格。bracketed 默认会自动侦测是否有中括号,可以设置为 true 或 false
join(a b c, d e f) // a b c d e f 
join((a b c), (d e f), comma) // a, b, c, d, e, f 
join(a b c, d e f, $bracketed: true) // [a b c d e f]
  • length($list) 返回列表长度
length(a b c) // 3
  • set-nth(list, n, value) 设置列表第 n 项的值为 value
set-nth(a b c, 2, x) // a x c
  • nth($list, $n) 获取第 n 项的值
nth(a b c, 3) // c
  • zip(lists) 将多个列表按照以相同索引值为一组,重新组成一个新的多维度列表,非常好用
zip(1px 2px 3px, solid dashed dotted, red green blue) 
// 1px solid red, 2px dashed green, 3px dotted blue

事例代码

p {
    z-index: length(12px); //1
    z-index: length(12px 5px 8px); //3
    z-index: index(a b c d, c); //3
    padding: append(10px 20px, 30px); // 10px 20px 30px
    color: nth($list: red blue green, $n: 2); // blue
    @debug list.zip(10px 50px 100px, short mid long); // 10px short, 50px mid, 100px long
}

编译结果

p {
    z-index: 1;
    z-index: 3;
    z-index: 3;
    padding: 10px 20px 30px;
    color: blue;
}

Map(映射) 函数