# Sass、Scss - CSS 预处理器从入门到实践

TIP

CSS 预处理器是 Web 前端开发的必备技能之一,也是我们在企业项目开发 和 很多开源项目的源代码中非常常见的。从本节内容开始我们就来深入学习。

# 一、CSS 预处理器简介

TIP

深入浅出什么是 CSS 预处理器,常见的 CSS 预处理器,Sass 的前世今生 等。

# 1、什么是 CSS 预处理器

TIP

CSS 预处理器定义了一种新的语言,其基本思想是,用一种专门的编程语言,为 CSS 增加了一些编程的特性,将 CSS 作为目标生成文件,然后开发者就只要使用这种语言进行编码工作。

通俗的说,“CSS 预处理器用一种专门的编程语言,进行 Web 页面样式设计,然后再编译成正常的 CSS 文件,以供项目使用。CSS 预处理器为 CSS 增加一些编程的特性,无需考虑浏览器的兼容性问题”,

例如你可以在 CSS 中使用变量简单的逻辑程序函数(如下代码中就使用了变量 $color)等等在编程语言中的一些基本特性,可以让你的 CSS 更加简洁适应性更强可读性更佳更易于代码的维护等诸多好处。

$color: orange;

.wrap {
  color: $color;
}

# 2、常见的 CSS 预处理器

TIP

CSS 预处理器技术已经非常的成熟,而且也涌现出了很多种不同的 CSS 预处理器语言

如下:

  • Sass(SCSS)
  • Less
  • Stylus
  • Turbine
  • Swithch CSS
  • CSS Cacheer
  • DT CSS

如此之多的 CSS 预处理器,那么“我应该选择哪种 CSS 预处理器 ?一度也成为了前端工程师们的争论的话题。

到目前为止,在众多优秀的 CSS 预处理器语言中就属 SassLessStylus 最优秀,讨论的也多,对比的也多。Sass 最大的优势在于它诞生的比较早,比较成熟,同时还有 ruby 社区的良好支持以及 Compass 这个强大的工具库。还有就是它更好的支持条件语句,是我们熟知的 if else 的写法,整体来说功能比较强大,热度比较高。

本次我们会介绍 CSS 预处理器中的 Sass。也是目前企业项目中用到最多的 CSS 预处理器。

# 3、什么是 Sass

TIP

Sass 是一门高于 CSS 的元语言,它能用来清晰地、结构化地描述文件样式,有着比普通 CSS 更加强大的功能。 Sass 能够提供更简洁、更优雅的语法,同时提供多种功能来创建可维护和管理的样式表。

Sass 是一个稳定的、强大的、专业级的 CSS 扩展语言。所以说,它是基于 CSS 扩展出来的,也有另一个叫法,Sass 是一个 CSS 预处理器,所以说 Sass 是需要编译后转换为 CSS 的,它一定是在你的项目编译时去做处理,而不是在运行时。

# 3.1、Sass 的前世今生

TIP

Sass 是最早的 CSS 预处理语言,有比 Less 更为强大的功能,不过其一开始的缩进式语法(Sass 老版本语法)并不能被大众接受,不过由于其强大的功能和 Ruby on Rails 的大力推动,还是有很多开发者选择了 Sass。

Sass 是采用 Ruby 语言编写的一款 CSS 预处理语言,它诞生于 2007 年,是最大的成熟的 CSS 预处理语言。最初它是为了配合 HAML(一种缩进式 HTML 预编译器)而设计的,因此有着和 HTML 一样的缩进式风格。

# 3.2、为什么早期不如 Less 普及

TIP

虽然缩进式风格可以有效缩减代码量,强制规范编码风格,但它一方面并不为大多数程序接受,另一方面无法兼容已有的 CSS 代码。

这也是 Sass 虽然出现得最早,但远不如 Less 普及的原因。

# 3.3、为什么要使用 Sass

TIP

CSS 已经可以满足我们编写各种样式,我们为什么又要使用它的扩展语言 Sass 呢?很重要的原因就是提高开发效率提高代码可维护性

在大型的 web 应用开发中我们一般会编写大量的样式代码,Sass 在 CSS 的基础上提供了变量、嵌套(nesting)、混合(mixins)、函数、指令等功能,使得我们可以更高效地编写样式,同时你还可以像编写 JS 一样来灵活地控制你的样式代码,这给 CSS 的开发带来了极大的便利。

# 二、Sass 安装 和 环境配置

TIP

Sass 可以在 Ruby 环境 和 Node 环境下安装,同时也可以使用 VSCode 扩展 Live Sass Compiler,可通过实时浏览器重新加载来帮助我们实时将 SASS / SCSS 文件编译/转换为 CSS 文件。

# 1、在 Ruby 环境中安装 Sass

TIP

具体安装和使用教程

注:对于我们前端开发者来说,很少会在 Ruby 环境下开发项目,了解原理即可。

# 2、在 Node 环境下安装 Sass

TIP

在我们前端企业项目开发中,基本都会使用 Webpack / Vite 这类前端构建工具,而它们都是基于 Node 环境下开发的。

具体如何在 node 环境下如何安装 Sass ,以及如何通过 Webpack / Vite 来整合配置 sass-loader 将会在 Vue 的学习中会讲到。

具体安装和使用教程

# 3、VSCode 插件 Live Sass Compiler

TIP

Visual Studio Code 插件 Live Sass Compiler 可将 Sass 或 Scss 实时编译为 CSS,对于前端开发者来讲是最简单,最快捷的方式来学习 Sass 的。我们接下来将会使用该方式来学习。

相关操作教程:https://www.sass.hk/skill/sass154.html (opens new window)

image-20230529234425866

# 3.1、Live Sass Compiler 插件的用法

TIP

Watch Sass从状态栏单击以打开实时编译,然后Stop Watching Sass从状态栏单击以打开实时编译。

image-20230530001119494

注:

  • 当书写完 .sass.scss 文件后,点击保存就会生成 .css
  • 同时还会生成 .css.map 文件,即:映射文件(如果要去掉这个文件需要手动配置)
  • 点击 VSCode 状态栏中的 Watching 打开实时编译,再次点击即关闭实时编译
  • 如果需要将生成后的 .css 文件 与 .sass.scss 源文件放置在不同的目录中,也需要手动配置

# 3.2、Live Sass Compiler 扩展配置文件

TIP

在 VSCode 的 settings.json 配置文件中,对 Live Sass Compiler 插件对其进行相关的配置

详细配置文档:https://github.com/ritwickdey/vscode-live-sass-compiler/blob/master/docs/settings.md (opens new window)

image-20230530003853317

settings.json 中的基础配置信息

// 设置格式(样式),扩展名&保存导出css的位置[支持多种格式]。
"liveSassCompile.settings.formats": [
    // This is Default.
    {
        // 编译后的样式输出风格
        "format": "expanded",
        // 扩展名
        "extensionName": ".css",
        // 保存导出css的位置
        "savePath": "/src/css"
    }
],
// 不生成 .map 映射文件
"liveSassCompile.settings.generateMap": false

image-20230530004143764

# 4、不同样式风格的输出方法

TIP

众所周知,每个人编写的 CSS 样式风格都不一样,有的喜欢将所有样式代码都写在同一行,而有的喜欢将样式分行书写。

在 Sass 中编译出来的样式风格也可以按不同的样式风格显示。其主要包括以下几种样式风格:

  • 嵌套输出方式 nested
  • 展开输出方式 expanded
  • 紧凑输出方式 compact
  • 压缩输出方式 compressed

注:只需要修改 VSCode settings.json 配置中的 format 字段的值即可

# 三、Sass 语法格式

TIP

深入浅出 Sass 的基础语法格式,Sass 和 Scss 的区别、变量声明与调用、嵌套规则、数据类型等。

# 1、Sass 和 Scss 的区别

TIP

Sass 和 Scss 其实是同一种东西,我们平时都称之为 Sass,两者之间不同之处有以下两点:

  • 文件扩展名不同,Sass 是以 .sass 后缀为扩展名,而 Scss 是以 .scss 后缀为扩展名
  • 语法书写方式不同,Sass 是以严格的缩进式语法规则来书写,不带大括号 {} 和 分号 ; ,而 Scss 的语法书写 和 我们的 CSS 语法书写方式非常类似。

# 1.1、Sass 语法

TIP

这里说的 Sass 语法是 Sass 的最初语法格式,他是通过 tab 键控制缩进的一种语法规则,而且这种缩进要求非常严格。

另外其不带有任何的分号和大括号。常常把这种格式称为 Sass 老版本,其文件名以 .sass 为扩展名。

src/sass/index.sass

.header 
  span 
    font-size: 16px
    width: 1000px
    height: 300px
    background-color: red
    color: skyblue

/* 编译后的 CSS 代码 */
.header span {
  font-size: 16px;
  width: 1000px;
  height: 300px;
  background-color: red;
  color: skyblue;
}

image-20230530165246746

注:

在整个 Sass 代码中,我们没看到类似 CSS 中的大括号和分号。

这种语法格式对于前端人员都不太容易接受,而且容易出错。

# 1.2、Scss 语法

TIP

SCSS 是 Sass 的新语法格式,从外形上来判断他和 CSS 长得几乎是一模一样,代码都包裹在一对大括号里,并且末尾结束处都有一个分号。

其文件名格式常常以 .scss 为扩展名。

src\sass\index.scss

.header {
  span {
    font-size: 16px;
    width: 1000px;
    height: 300px;
    background-color: red;
  }
}

/* 编译后的 CSS 代码 */
.header span {
  font-size: 16px;
  width: 1000px;
  height: 300px;
  background-color: red;
}

image-20230530164415651

注:

这样的语法格式对于从事前端工作的同学来说更易于接受,这也是 SCSS 为什么更被前端人员青眯的原因。

不管是 Sass 的语法格式还是 SCSS 的语法格式,他们的功能都是一样的,不同的是其书写格式和文件扩展名不同。

# 2、Sass 和 CSS 写法有差别

TIP

Sass 和 CSS 写法的确存在一定的差异,由于 Sass 是基于 Ruby 写出来,所以其延续了 Ruby 的书写规范。

在书写 Sass 时不带有大括号和分号,其主要是依靠严格的缩进方式来控制的。

Sass 的写法

.header
  font-size: 16px
  color: skyblue

CSS 的写法

.header {
  font-size: 16px;
  color: skyblue;
}

# 3、Scss 和 CSS 写法无差别

TIP

SCSS 和 CSS 写法无差别,这也是 Sass 后来越来越受大众喜欢原因之一。

简单点说,把你现有的 .css 文件直接修改成 .scss 即可使用。这种方式项目中用到最多的形式,即以 .scss 为后缀名的文件,语法类似 CSS 的写法。

# 4、Sass 声明变量 与 调用

TIP

在 JS 中变量声明使用 关键词 var 开头,在 Sass 中 使用美元符号 $ 开头

$color: red;
$width: 100px;
$min-width: 998px;
$max-width: 1228px;

注:

从以上代码中可以看出,Sass 变量包括三个部分

  • $ 声明变量的符号
  • colorwidthmin-widthmax-width 为变量名称
  • red100px998px1228px 赋予变量的值

# 4.1、普通变量

TIP

普通变量定义之后,可在全局范围内使用

$fontSize: 12px;

body {
  font-size: $fontSize;
}

编译后的 CSS 代码

body {
  font-size: 12px;
}

注:

Sass 文件执行的顺序是从上到下依次执行的,声明的变量必须放在使用的位置之前,否则编译不通过,会报错。

# 4.2、默认变量

TIP

sass 的默认变量仅需要在值后面加上 !default 即可。

$fontSize: 12px !default;

body {
  font-size: $fontSize;
}

编译后的 css 代码

body {
  font-size: 12px;
}

sass 的默认变量一般是用来设置默认值,然后根据需求来覆盖的,覆盖的方式也很简单,只需要在默认变量之前重新声明下变量即可。

$fontSize: 16px;
$fontSize: 12px !default;

body {
  font-size: $fontSize;
}

编译后的 CSS 代码

body {
  font-size: 16px;
}

注:

可以看出现在编译后的 font-size 为 16px ,而不是我们默认的 12px 。

默认变量的价值在进行组件化开发的时候会非常有用。

# 4.3、局部变量 和 全局变量

TIP

  • 定义在元素外面的变量,是一个全局变量
  • 定义在元素内部的变量,是一个局部变量
// 定义全局变量(在选择器、函数、混合宏...的外面定义的变量为全局变量)
$color: red !default;

header {
  // 调用全局变量
  color: $color;
}

main {
  // 定义局部变量
  $color: orange;
  a {
    // 调用局部变量
    color: $color;
  }
}

footer {
  span {
    // 调用全局变量
    color: $color;
  }
}

编译后的 CSS 代码

header {
  color: red;
}

main a {
  color: orange;
}

footer span {
  color: red;
}

# 4.4、全局变量的影子

TIP

当在局部范围(选择器内、函数内、混合宏内...)声明一个已经存在于全局范围内的变量时,局部变量就成为了全局变量的影子

基本上,局部变量只会在局部范围内覆盖全局变量

// 定义全局变量
$color: red !default;

header {
  // 调用全局变量
  color: $color;
}

main {
  // 定义局部变量(全局变量 $color 的影子)
  $color: orange;
  a {
    // 调用局部变量
    color: $color;
  }
}

# 4.5、局部变量转换为全局变量

TIP

将局部变量转换为全局变量可以添加 !global

main {
  // 定义局部变量
  // 添加 !global ,将局部变量转换为全局变量
  $color: orange !global;
  a {
    // 调用局部变量
    color: $color;
  }
}

.sidebar {
  // 调用转换后的全局变量
  color: $color;
}

编译后的 CSS 代码

main a {
  color: orange;
}

.sidebar {
  color: orange;
}

# 4.6、什么时候需要声明变量

TIP

创建变量只适用于必要的情况下,不要为了声明而声明,没有任何意义。按照以下标准来创建新变量:

  • 该值至少重复出现了两次;
  • 该值至少可能会被更新一次;
  • 该值所有的表现都与变量有关

在线练习 sass 的编辑器分享:http://sassmeister.com/ (opens new window)

# 5、嵌套

TIP

Sass 中提供了选择器嵌套功能,但这也并不意味着在 Sass 中的嵌套是无节制的,因为嵌套的层级越深,编译出来的 CSS 代码的选择器层级将越深。切记不要滥用嵌套 !

Sass 的嵌套分为三种:

  • 选择器嵌套
  • 属性嵌套
  • 伪类嵌套

# 5.1、选择器嵌套

TIP

Sass 允许将一套 CSS 样式嵌套进另一套样式中,内层的样式将它外层的选择器作为父选择器。

嵌套功能避免了重复输入父选择器,而且令复杂的 CSS 结构更易于管理。

如下一段代码结构

<header>
  <nav>
    <a href="#">首页</a>
    <a href="#">Web前端</a>
    <a href="#">Java</a>
  </nav>
</header>

想要选中 header 中的 a 标签,在 CSS 中有两种写法

nav a {
  color: orange;
}

header nav a {
  color: red;
}

在 Sass 中,使用 选择器的嵌套实现

nav {
  a {
    color: orange;

    header & {
      color: red;
    }
  }
}

# 5.2、父选择器 &

TIP

在嵌套 CSS 规则时,有时也需要直接使用嵌套外层的父选择器。

例如:当给某个元素设定 hover 样式时,或者当 body 元素有某个 classname 时,可以用 & 代表嵌套规则外层的父选择器。

.header {
  a {
    color: red;
    &:hover {
      color: skyblue;
    }
    &:active {
      color: orange;
    }
  }
}

编译后的 CSS 代码

.header a {
  color: red;
}
.header a:hover {
  color: skyblue;
}
.header a:active {
  color: orange;
}

# 5.3、添加后缀

TIP

& 必须作为选择器的第一个字符,其后可以跟随后缀生成复合的选择器

.main {
  color: red;
  &-sidebar {
    font-size: 20px;
  }
}

编译后的 CSS 代码

.main {
  color: red;
}
.main-sidebar {
  font-size: 20px;
}

# 5.4、属性嵌套

TIP

有些 CSS 属性遵循相同的命名空间(namespace),比如 font-family, font-size, font-weight 都以 font 作为属性的命名空间。与这个类似的还有 margin、padding、border 等属性

为了便于管理这样的属性,同时也为了避免了重复输入,Sass 允许将属性嵌套在命名空间中。

body {
  font: {
    size: 12px;
    family: "Microsoft Yahei";
    weight: bold;
  }
}

.box {
  border: {
    top: 1px solid red;
    bottom: 2px solid orange;
  }
}

编译后的 CSS 代码

body {
  font-size: 12px;
  font-family: "Microsoft Yahei";
  font-weight: bold;
}

.box {
  border-top: 1px solid red;
  border-bottom: 2px solid orange;
}

# 5.5、伪类嵌套

TIP

伪类嵌套和属性嵌套非常类似,只不过他需要借助&符号一起配合使用。

.clearfix {
  &::after {
    content: "";
    clear: both;
    display: block;
  }
}

编译后的 CSS 代码

.clearfix::after {
  content: "";
  clear: both;
  display: block;
}

# 5.6、嵌套组合符选择器

TIP

我们还可以嵌套使用带有选择符的选择器,我们可以将选择符放在外部选择器的末尾,或者内部选择器的开始位置

// 子选择器
ul > {
  li {
    list-style: none;
  }
}

// 相邻兄弟选择器
h2 {
  + p {
    border: 1px solid red;
  }
}

// 通用兄弟选择器
p {
  ~ {
    span {
      color: skyblue;
    }
  }
}

编译后的 CSS 代码

ul > li {
  list-style: none;
}

h2 + p {
  border: 1px solid red;
}

p ~ span {
  color: skyblue;
}

# 5.7、嵌套选择器列表

TIP

嵌套规则可以很方便的处理选择器列表,由逗号分隔的选择器列表会被 Sass 组合到一个选择器列表中

.header,
.nav {
  ul,
  a {
    font-size: 14px;
    color: tomato;
    font-weight: bold;
  }
}

编译后的 CSS 代码

.header ul,
.header a,
.nav ul,
.nav a {
  font-size: 14px;
  color: tomato;
  font-weight: bold;
}

# 四、Sass 数据类型

TIP

所有的开发语言都有数据类型这个概念,Sass 也一样,它共有 7 种数据类型,分别是

  • Number 类型
  • Boolean 类型
  • String 类型
  • Colors 类型
  • Lists 类型
  • Maps 类型
  • Null 类型

这其中大多数都直接来自 CSS ,这里我们主要是了解和知道这几种数据类型,数据类型并不是单独的一个语法,它会应用于 Sass 的其他语法中,如 SassScript 中等等

# 1、Number 类型(数字类型)

TIP

在 Sass 中,数字(Number)是最基本的数据类型,可以是正数、0 或负数。数字在 Sass 中使用非常广泛,大多数都是结合 CSS 单位来实现的。

例如 10px、10em 或者 10%。虽然它们带有单位,但是技术上依然算是数字。

$main-height: 100px; // 带有单位的 Number 类型
$main-flex-grow: 1; // 不带单位的 Number 类型
$main-num: 6e3; // 使用科学计数法的数字
$main-max-height: 2 * 100px; // 运算

.box {
  height: $main-height;
  flex-grow: $main-flex-grow;
  width: $main-num;
  max-height: $main-max-height;
}

以上 .box 的样式中,引用这些变量是为了更加直观的看见编译后的代码,在实际的开发中可能并不会这么使用.

.box {
  height: 100px;
  flex-grow: 1;
  width: 6000;
  max-height: 200px;
}

注:Sass 的 Number 类型支持小数点后 10 位的精度

# 2、Boolean 类型(布尔类型)

TIP

Sass 中的布尔值只有 2 种取值:true 和 false

在 Sass 中,布尔值一般用于 @if … @esle … 条件判断,只有条件表达式结果是 false 或 null 才会返回 false,其他一切将返回 true

$numA: 100px;
$numB: 200px;

.box {
  @if ($numA > $numB) {
    display: none;
  } @else {
    display: block;
  }
}

编译后的 CSS 代码

.box {
  display: block;
}

# 3、String 类型(字符串类型)

TIP

在 Sass 中支持两种展现方式不同的 String 类型,带引号的字符串和不带引号的字符串。

同时任何的字符都可以作为字符串的一部分来书写,带需要为字符写上转义符 \

$one: "Yahei"; // 带引号的字符串
$two: Yahei; // 不带引号的字符串
$three: '"yahei'; // 使用转义符的字符串
$bannerUrl: "images/banner.jpg";

.box {
  font: $one;
  font-family: $two;
  font: $three;
  background-image: url($bannerUrl);
}

编译后的 CSS 代码

.box {
  font: "Yahei";
  font-family: Yahei;
  font: '"yahei';
  background-image: url("images/banner.jpg");
}

# 4、Colors 类型(颜色类型)

TIP

在 Sass,有一种特殊的数据类型,那就是“颜色值”。

Sass 中的颜色值共有 4 种:

  • 关键字颜色值,如 red
  • 十六进制颜色值,如 #FFFF00
  • RGB 颜色值,如 rgb(255,255,0)
  • RGBA 颜色值,如 rgba(112,156,130,0.6)
  • HSL 颜色值,如 hsl(360,50%,50%)
$color-one: #ffff00;
$color-two: red;
$color-three: rgb(139, 215, 128);
$color-four: rgba(213, 89, 121, 0.5);

.box {
  color: $color-one;
  background-color: $color-two;
  border-color: $color-three;
  color: $color-four;
}

编译后的 CSS 代码

.box {
  color: #ffff00;
  background-color: red;
  border-color: rgb(139, 215, 128);
  color: rgba(213, 89, 121, 0.8);
}

# 5、Lists 类型(列表类型)

TIP

在 Sass 中,为我们提供了一种“列表值”的数据类型,这种数据类型跟 JavaScript 中的数组是相似的,我们可以把它比作 “Sass 中的数组”

Sass 列表值有 2 种语法格式,一种是由英文逗号隔开的分隔值,另外一种是由空格隔开的分隔值。

$font-list: "Cantarell", "sans-serif"; // 通过逗号分隔元素
$margin-list: 1px 2px 3px 4px; // 通过空格分隔元素
$padding-list: 2px 3px 4px 5px; // 通过逗号分隔元素

.box {
  font: $font-list;
  margin: $margin-list;
  padding: $padding-list;
}

编译后的 CSS 代码

.box {
  font: "Cantarell", "sans-serif";
  margin: 1px 2px 3px 4px;
  padding: 2px 3px 4px 5px;
}

# 6、Maps 类型

TIP

Maps 类型是 key / value 的键值对的形式,可以通过 来查找对应的,就像字典一样。

在 Sass 中 Maps 类型必须使用括号括起来,同时每个键值对之间通过逗号分隔键必须是唯一的,值可以重复。同时一些函数用于获取 Maps 中的键值、合并等等。

$textStyleMap: (
  "font-family": "Microsoft Yahei",
  "font-weight": bold,
  "font-size": 12px,
  "text-align": center,
);

.box {
  font-family: map-get($textStyleMap, "font-family");
  font-weight: map-get($textStyleMap, "font-weight");
  font-size: map-get($textStyleMap, "font-size");
  text-align: map-get($textStyleMap, "text-align");
}

编译后的 CSS 代码

.box {
  font-family: "Microsoft Yahei";
  font-weight: bold;
  font-size: 12px;
  text-align: center;
}

# 7、Null 类型

TIP

在 Sass 中 Null 类型只有一个值 null ,这也和 Javascript 中的 null 类似,在 Sass 中它表示缺少值,通常由函数返回。

如果说在列表中有 null ,那么在生成 CSS 的时候会忽略该空值,你需要知道在 Sass 的数据类型中有这个即可。

# 五、导入 Sass 文件 和 代码拆分及引入

TIP

Sass 扩展了 CSS 的 @import 规则,让它能够引入 SCSS 和 Sass 文件。 所有引入的 SCSS 和 Sass 文件都会被合并并输出一个单一的 CSS 文件。

另外,被导入的文件中所定义的变量或 mixins 都可以在主文件中使用。

# 1、拆分 Sass 文件中的变量

src/sass/index.scss 文件中的 Sass 代码做拆分

$color: red;
$content-color: orange;
$footer-color: skyblue;

.header {
  color: $color;
}

.content {
  color: $content-color;
}

.footer {
  color: $footer-color;
}

将 Sass 文件中的变量,拆分提取到另一个 _variables.scss 文件中

src/sass/_variables.scss

$color: red;
$content-color: orange;
$footer-color: skyblue;

# 2、通过 @import 导入变量文件

src/sass/index.scss 中通过 @import 导入 _variables.scss 变量文件

@import "variables";

.header {
  color: $color;
}

.content {
  color: $content-color;
  background-color: $content-color;
}

.footer {
  color: $footer-color;
}

编译后的 CSS 代码

.header {
  color: red;
}

.content {
  color: orange;
  background-color: orange;
}

.footer {
  color: skyblue;
}

# 3、按模块拆分 Sass 代码块

TIP

新建 _header.scss_content.scss_footer.scss 文件,并将对应的代码放入其中

src/sass/_header.scss

.header {
  color: $color;
}

src/sass/_content.scss

.content {
  color: $content-color;
  background-color: $content-color;
}

src/sass/_footer.scss

.footer {
  color: $footer-color;
}

src/sass/index.scss 中通过 @import 关键字导入_header.scss_content.scss_footer.scss 文件

@import "variables";
@import "header";
@import "content";
@import "footer";

在 Sass 中也可以导入用逗号分隔的多个文件

// 导入多个文件
@import "header", "content", "footer";

编译后的 CSS 代码

.header {
  color: red;
}

.content {
  color: orange;
  background-color: orange;
}

.footer {
  color: skyblue;
}

image-20230531174134588

# 4、@use 导入文件

TIP

使用 @use 替代 @import,Sass 官方团队不鼓励使用 @import 导入,并且在近几年将逐步淘汰它,并最终将 @import 从 Sass 中完全删除。所以使用 @use 是官方团队更推荐的方式。

详细查阅 Sass 官方文档 - @use (opens new window)

@use@import 的语法基本相同

/src/sass/_header.scss

.header {
  width: 100%;
  height: 100px;
  background-color: skyblue;
}

/src/sass/_content.scss

.content {
  color: #333;
  font-size: 14px;
}

/src/sass/index.scss

@use "header";
@use "content";

# 5、为什么要使用 @use

TIP

从上面的代码中可以看到其使用方式与 @import 是相同的,那么为什么还要替换掉 @import

  • @import 会使得所有变量、mixin 和函数都可以全局访问,这使开发者很难去维护这些定义的东西。
  • 因为所有的都是全局的,那么 Sass 必须为所有的成员添加前缀,以避免命名冲突。
  • @extend 也是全局的,这样将很难预测哪些样式将被扩展。
  • 每次使用 @import 时,每个样式表都会被执行,这会增加编译时间
  • 无法定义下游样式表无法访问的私有成员。

基于上述的这些原因,Sass 官方团队将会逐渐淘汰 @import,可以使用 @use 替代,语法是相同的,所以我们在 v4.x.x 及以上的版本中尽量使用 @use 来导入。

# 6、使用 @use 加载成员

TIP

我们可以通过编写 <namespace>.<variable> 即:命名空间.变量 的方式从另一个模块中来访问变量、函数和 mixin 。默认情况下,命名空间只是模块 URL 的最后一个组件 。

注:

使用@use加载的成员(变量、函数和 mixin)仅 在加载它们的样式表中可见。如果其他样式表 也想访问它们,它们需要编写自己的@use规则。这有助于准确 地找出每个成员来自哪里。如果你想 一次从多个文件中加载成员,你可以使用@forward规则 (opens new window) 从一个共享文件中转发所有成员 。

/src/sass/_var.scss 中声明变量

$color: red;
$font_size: 12px;

/src/sass/_header.scss

@use "var";

.header {
  width: 100%;
  height: 100px;
  color: var.$color;
}

/src/sass/_content.scss

@use "var";

.content {
  color: var.$color;
  font-size: var.$font_size;
}

/src/sass/index.scss

@use "header";
@use "content";

编译后的 CSS 代码

.header {
  width: 100%;
  height: 100px;
  color: red;
}

.content {
  color: red;
  font-size: 12px;
}

注:

因为@use将命名空间添加到成员名中,所以在编写样式表时,选择非常简单的名称(如$color$width)是安全的。这与旧的@import规则 (opens new window)不同,它鼓励用户编写像$mat-corner-radius这样的长名称,以避免与其他库冲突,它有助于保持您的样式表清晰易读 !

# 7、选择命名空间

TIP

默认情况下,模块的命名空间只是其 URL 的最后一个组件,没有文件扩展名。

但是,有时您可能希望选择不同的命名空间,您可能希望为经常引用的模块使用较短的名称 ,或者您可能正在加载具有相同文件名的多个模块。

即可以 通过写 @use "<url>" as <namespace>来实现。

/src/sass/_var.scss 中声明变量

$color: red;
$font_size: 12px;

/src/sass/_header.scss

@use "var" as v;

.header {
  width: 100%;
  height: 100px;
  color: v.$color;
}

/src/sass/_content.scss

@use "var" as v;

.content {
  color: v.$color;
  font-size: v.$font_size;
}

/src/sass/index.scss

@use "header";
@use "content";

编译后的 CSS 代码

.header {
  width: 100%;
  height: 100px;
  color: red;
}

.content {
  color: red;
  font-size: 12px;
}

注:

也可以通过编写@use "<url>" as *来加载没有命名空间的模块 。

但是,我们建议您只对自己编写的样式表执行此操作。 否则,它们可能会引入导致名称冲突的新成员 !

# 8、使用 as * 加载模块

TIP

通过编写@use "<url>" as *来加载没有命名空间的模块 。

/src/sass/_var.scss 中声明变量

$color: red;
$font_size: 12px;

/src/sass/_header.scss

@use "var" as *;

.header {
  width: 100%;
  height: 100px;
  color: $color;
}

/src/sass/_content.scss

@use "var" as *;

.content {
  color: $color;
  font-size: $font_size;
}

/src/sass/index.scss

@use "header";
@use "content";

编译后的 CSS 代码

.header {
  width: 100%;
  height: 100px;
  color: red;
}

.content {
  color: red;
  font-size: 12px;
}

注:

具体实践,点击查看 Element UI 源码 (opens new window) 了解项目实践语法

# 9、@import 与 @use 的差异

TIP

@use规则的目的是取代旧的@import规则 (opens new window),但 它的工作方式有所不同。以下是 两者之间的一些主要区别 :

  • @use只在当前文件的范围内提供变量、函数和 mixin 。它从不将它们添加到全局范围。这使得 很容易找出 Sass 文件引用的每个名称的来源, 并且意味着您可以使用较短的名称而不会有任何冲突的风险 。
  • @use每个文件只加载一次。这可以确保您不会 意外地多次复制依赖项的 CSS 。
  • @use必须出现在文件的开头,并且不能嵌套在 样式规则中。
  • 每个@use规则只能有一个 URL。
  • @use需要在其 URL 周围加上引号,即使使用缩进语法 (opens new window)

# 六、混合宏

TIP

在 Sass 中,我们可以使用“混合宏(mixin)”来处理经常被多个地方使用的相同的 CSS 代码块。混合宏,跟 JavaScript 中的函数很相似,我们可以称之为 “Sass 中的函数”。

Sass 中的混合宏跟 C 语言的宏是非常相似的。所谓的“宏”,指的是可重用的代码块。

应用场景:

如果你的整个网站中有几处小样式类似,比如颜色,字体等,在 Sass 可以使用变量来统一处理,那么这种选择还是不错的。

但当你的样式变得越来越复杂,需要重复使用大段的样式时,使用变量就无法达到我们目了。这个时候 Sass 中的混合宏就会变得非常有意义。

# 1、混合宏的定义 和 调用

TIP

在 Sass 中,我们使用 @mixin 来定义一个混合宏,然后使用 @include 来调用一个混合宏。

  • @mixin 用来定义一个混合宏
  • @include 用来调用一个混合宏。
  • 此外,@mixin 跟 CSS3 中的 @font-face@media 语法是一样的。

观察 src/sass/main.scss 中的代码

// 溢出一行隐藏,超出的部分添加 省略号
.header-title {
  min-width: 100px;
  max-width: 200px;
  // 以下相同的代码可以被复用
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 1;
  overflow: hidden;
}

.content-title {
  min-width: 200px;
  max-width: 300px;
  // 以下相同的代码可以被复用
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 1;
  overflow: hidden;
}

注:

以上代码中,除了 min-widthmax-width 值不一样之外,其他代码都是重复的

混合指令的定义是在 @mixin 后跟指令名字和 {} ,在 {} 中可以写需要复用的样式即可。在对应样式的位置通过 @include 跟 混合指令名称即可引入成功。

src/sass/main.scss 中 定义混合宏

// 定义混合宏
@mixin singleline-ellipsis {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 1;
  overflow: hidden;
}

// 溢出一行隐藏,超出的部分添加 省略号
.header-title {
  min-width: 100px;
  max-width: 200px;
  // 引入混合宏
  @include singleline-ellipsis;
}

.content-title {
  min-width: 200px;
  max-width: 300px;
  // 引入混合宏
  @include singleline-ellipsis;
}

编译后的 CSS 代码

.header-title {
  min-width: 100px;
  max-width: 200px;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 1;
  overflow: hidden;
}

.content-title {
  min-width: 200px;
  max-width: 300px;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 1;
  overflow: hidden;
}

# 2、功能模块拆封

TIP

新建 _mixins.scss 文件,将单行文本溢出这个功能模块独立拆分出来到单独的文件中,哪里需要用到时,直接通过 @import 导入即可使用。

src/sass/_mixins.scss

// 定义单行文本溢出隐藏的混合宏
@mixin singleline-ellipsis {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 1;
  overflow: hidden;
}

注:

未来 CSS 样式中常用的通用功能模块,都可以通过 @mixin 混合宏的方式沉淀下来,可以在任意项目中使用

src/sass/main.scss 中通过 @import 导入 _mixins.scss 文件即可

@import "mixins";

// 溢出一行隐藏,超出的部分添加 省略号
.header-title {
  min-width: 100px;
  max-width: 200px;
  // 引入混合宏
  @include singleline-ellipsis;
}

.content-title {
  min-width: 200px;
  max-width: 300px;
  // 引入混合宏
  @include singleline-ellipsis;
}

# 3、混合宏 - 传入参数

TIP

以上 main.scss 中在使用 混合宏时,还需要手动定义 min-widthmax-width 两个值就非常麻烦了。如果能这两个值也放进 mixins.scss 中做好封装,就更好了。

在定义混合宏时,可接收参数,使用时可传入参数就会更符合我们的需求。

src/sass/_mixins.scss 中定义完整的 单行文本溢出隐藏的混合宏,并可接收参数

// 定义单行文本溢出隐藏的混合宏
// $line-clamp: 1(默认值为 1,即引入混合宏时不传该参数时,就使用默认值)
@mixin singleline-ellipsis($min-width, $max-width, $line-clamp: 1) {
  min-width: $min-width;
  max-width: $max-width;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: $line-clamp;
  overflow: hidden;
}

src/sass/main.scss 中通过 @import 导入 _mixins.scss 文件

// 导入 mixins
@import "mixins";

// 溢出一行隐藏,超出的部分添加 省略号
.header-title {
  // 引入混合宏,并传递参数
  @include singleline-ellipsis(100px, 200px, 3);
}

.content-title {
  // 引入混合宏,并传递参数
  @include singleline-ellipsis(200px, 300px);
}

编译后的 CSS 代码

.header-title {
  min-width: 100px;
  max-width: 200px;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
}

.content-title {
  min-width: 200px;
  max-width: 300px;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 1;
  overflow: hidden;
}

# 4、混合宏 - 导入内容

TIP

@mixin 指令除了可以接收参数外,还可以接收样式块,也称之为内容块。

@mixin 中可以使用 @content 来声明接收的内容块,内容块是通过 {} 的方式传入的,然后会注入到 @content 所在的位置。

@mixin hover {
  &:hover {
    @content;
  }
}

.button {
  background-color: skyblue;
  @include hover {
    background-color: tomato;
  }
}

注:

从上面的代码我们可以看到在 @mixin:hover 中我们使用 @content 来接收内容块,然后在使用这个 @mixin 的时候直接跟一个以 {} 包裹的内容块,就会到 @content 的位置。

编译后的 CSS 代码

.button {
  background-color: skyblue;
}
.button:hover {
  background-color: tomato;
}

# 5、媒体查询 与 Mixin 的配合使用

TIP

在开发响应代码中,我们会经常使用 @mixin 中的 @content 语法来解决编写 CSS 样式的实际问题。

以下代码是我们常见的 响应式开发下的书写方式

.header {
  width: 1280px;
}

@media screen and (min-width: 768px) {
  .header {
    width: 600px;
  }
}

.footer {
  color: orange;
}

@media screen and (min-width: 768px) {
  .footer {
    color: red;
  }
}

注:

以上这样的代码书写方式难以维护,只要 min-width 的值发生改变,每一项都需要修改。

使用 @mixin 中的 @content 来实现

@mixin ipad {
  @media screen and (min-width: 768px) {
    @content;
  }
}

.header {
  width: 1280px;
  @include ipad {
    width: 600px;
  }
}

.footer {
  color: orange;
  @include ipad {
    color: red;
  }
}

编译后的 CSS 代码

.header {
  width: 1280px;
}
@media screen and (min-width: 768px) {
  .header {
    width: 600px;
  }
}

.footer {
  color: orange;
}
@media screen and (min-width: 768px) {
  .footer {
    color: red;
  }
}

# 6、媒体查询 与 Mixin 的配合使用 - 传参

@mixin ipad($height) {
  @media screen and (min-width: 768px) {
    height: $height;
    @content;
  }
}

.header {
  width: 1280px;
  @include ipad(100px) {
    width: 600px;
  }
}

.footer {
  color: orange;
  @include ipad(200px) {
    color: red;
  }
}

编译后的 CSS 代码

.header {
  width: 1280px;
}
@media screen and (min-width: 768px) {
  .header {
    height: 100px;
    width: 600px;
  }
}

.footer {
  color: orange;
}
@media screen and (min-width: 768px) {
  .footer {
    height: 200px;
    color: red;
  }
}

# 七、Sass 代码重用

TIP

在我们编写样式的时候,很多情况下我们几个不同的类会有相同的样式代码,同时这几个类又有其自己的样式代码,这使我们就可以通过 Sass 提供的 继承 @extend 来实现。

# 1、Sass 继承(@extend)

TIP

继承,我们也叫做代码重用,在 Sass 中支持对样式进行继承。

语法:@extend selector 也就是在 @extend 后面跟一个选择器,表示继承这个选择器的样式

.btn {
  border: 1px solid #ccc;
  padding: 6px 10px;
  font-size: 14px;
}

.btn-primary {
  background-color: #f36;
  color: #fff;
  @extend .btn;
}

.btn-second {
  background-color: orange;
  color: #fff;
  @extend .btn;
}

编译后的 CSS 代码

/*
	以上代码中,在 Sass 中的继承,可以继承类样式块中所有样式代码,而且编译出来的 CSS 会将选择器合并在一起,形成组合选择器
*/
.btn,
.btn-second,
.btn-primary {
  border: 1px solid #ccc;
  padding: 6px 10px;
  font-size: 14px;
}

.btn-primary {
  background-color: #f36;
  color: #fff;
}

.btn-second {
  background-color: orange;
  color: #fff;
}

# 2、占位符(%placeholder)

TIP

Sass 中的占位符 %placeholder 功能是一个很强大,很实用的一个功能。

它可以取代以前 CSS 中的基类造成的代码冗余的情形。因为 %placeholder 声明的代码,如果不被 @extend 调用的话,不会产生任何代码。

%mt5 {
  margin-top: 5px;
}
%pt5 {
  padding-top: 5px;
}

这段代码没有被 @extend 调用,它并没有产生任何代码块,只是静静的躺在你的某个 SCSS 文件中。只有通过 @extend 调用才会产生代码。

%mt5 {
  margin-top: 5px;
}
%pt5 {
  padding-top: 5px;
}

.btn {
  @extend %mt5;
  @extend %pt5;
}

.block {
  @extend %mt5;

  span {
    @extend %pt5;
  }
}

编译后的 CSS 代码

.block,
.btn {
  margin-top: 5px;
}

.block span,
.btn {
  padding-top: 5px;
}

注:

从编译出来的 CSS 代码可以看出,通过 @extend调用的占位符,编译出来的代码会将相同的代码合并在一起。

这也是我们希望看到的效果,也让你的代码变得更为干净。

# 3、在 @media 中使用 @extend

@media screen and (max-width: 600px) {
  .warning {
    border: 1px red solid;
    background-color: red;
  }
  .btn-warning {
    @extend .warning;
  }
}

编译后的 CSS 代码

@media screen and (max-width: 600px) {
  .warning,
  .btn-warning {
    border: 1px red solid;
    background-color: red;
  }
}

# 4、混合宏 VS 继承 VS 占位符

TIP

对于我们刚刚使用 Sass 的同学可能会纠结一个问题:到底什么时候用混合宏,什么时候用继承,什么时候使用占位符 ?其实他们各有各的优点与缺点

# 4.1、Sass 中的混合宏使用

// SCSS中混合宏使用
@mixin mt($var) {
  margin-top: $var;
}

.block {
  @include mt(10px);

  span {
    display: block;
    @include mt(10px);
  }
}

.header {
  color: skyblue;
  @include mt(10px);

  span {
    display: block;
    @include mt(10px);
  }
}

编译后的 CSS 代码

.block {
  margin-top: 10px;
}
.block span {
  display: block;
  margin-top: 10px;
}

.header {
  color: skyblue;
  margin-top: 10px;
}
.header span {
  display: block;
  margin-top: 10px;
}

总结:

从以上编译出来的结果可以看到,它不会自动合并相同的样式代码,如果在样式文件中调用同一个混合宏,会产生多个对应的样式代码,造成代码的冗余,这也是很多开发者无法忍受的一件事情。不过他并不是一无事处,他可以传参数。

建议:

如果你的代码块中涉及到变量,建议使用混合宏来创建相同的代码块。

# 4.2、Sass 中继承

TIP

将上面代码中的混合宏,使用类名来表示,然后通过继承来调用

//SCSS 继承的运用
.mt {
  margin-top: 5px;
}

.block {
  @extend .mt;

  span {
    display: block;
    @extend .mt;
  }
}

.header {
  color: orange;
  @extend .mt;

  span {
    display: block;
    @extend .mt;
  }
}

编译后的 CSS 代码

.mt,
.header span,
.header,
.block span,
.block {
  margin-top: 5px;
}

.block span {
  display: block;
}

.header {
  color: orange;
}
.header span {
  display: block;
}

总结:

使用继承后,编译出来的 CSS 会将使用继承的代码块合并到一起,通过组合选择器的方式向大家展现,比如 .mt, .block, .block span, .header, .header span 这样编译出来的代码相对于混合宏来说要干净的多,也是开发者期望看到。但是他不能传变量参数。

建议

如果你的代码块不需要专传何变量参数,而且有一个基类已在文件中存在,那么建议使用 Sass 的继承。

# 4.3、占位符

TIP

将上面代码中的基类 .mt 换成 Sass 的占位符格式

// SCSS中占位符的使用
%mt {
  margin-top: 5px;
}

.block {
  @extend %mt;

  span {
    display: block;
    @extend %mt;
  }
}

.header {
  color: skyblue;
  @extend %mt;

  span {
    display: block;
    @extend %mt;
  }
}

编译后的 CSS 代码

.header span,
.header,
.block span,
.block {
  margin-top: 5px;
}

.block span {
  display: block;
}

.header {
  color: skyblue;
}
.header span {
  display: block;
}

总结:

编译出来的 CSS 代码和使用继承基本上是相同,只是不会在代码中生成占位符 mt 的选择器。

那么占位符和继承的主要区别是

  • 占位符是独立定义,不调用的时候是不会在 CSS 中产生任何代码
  • 继承是首先有一个基类存在,不管调用与不调用,基类的样式都将会出现在编译出来的 CSS 代码中。

# 5、总结

混合宏 继承 占位符
声明方式 @mixin .class %placeholder
调用方式 @include @extend @extend
使用环境 如果相同代码块需要在不同的环境传递不同的值时,可以通过混合宏来定义重复使用的代码块。
不足: 就是编译出来的 css 代码什么多次出现调用的混合宏对应的代码块,使用文件变得臃肿,代码冗余。
如果相同代码块不需要传递不同的值,并且此代码块已在 Sass 文件中定义,此进可以通过 Sass 的继承来调用已存在的基类。使用继承将会将调用相同基类的代码合并在一起。
不足: 如果基类,并不存在于 HTML 结构时,不管调用与不调用,在编译出来的 CSS 中都将产生基类对应的样式代码。
占位和继承基本类似,唯一不同的是,相同代码块并没有在基类中存中,而是额外声明。
如果不调用已声明的占位符,将不会产生任何样式代码。
如果在不同选择器调用占位符,那么编译出来的 CSS 代码将会把相同的代码合并在一起。

# 八、Sass 插值

TIP

在很多编程器语言中都有插值这个概念,在 Sass 样式表的任何地方几乎都可以使用插值,你可以将这些包裹在 #{}中来使用。

所以只需要记住在 Sass 中使用插值的方式是 #{}

# 1、什么是插值

TIP

插值也就是可以在特定的区域插入一段表达式或者插入一个变量,以此来实现内容动态变换的需求。

# 2、插值的语法

@mixin corner-icon($name, $top-or-bottom, $left-or-right) {
  // 使用了插值(在选择器中使用)
  .icon-#{$name} {
    // 使用了插值(在属性值中使用)
    background-image: url("/images/#{$name}.png");
    position: absolute;
    #{$top-or-bottom}: 0; // 使用了插值(在属性名中使用)
    #{$left-or-right}: 0; // 使用了插值(在属性名中使用)
  }
}

@include corner-icon("logo", top, left);

编译后的 CSS 代码

.icon-logo {
  background-image: url("/images/logo.png");
  position: absolute;
  top: 0;
  left: 0;
}

# 3、Sass 插值的使用场景

TIP

Sass 插值指令的使用场景有四种

  • 在选择器中使用
  • 在属性名中使用
  • 在属性值中使用
  • 在注释中使用

# 3.1、在选择器中使用

TIP

我们一般在写页面的时候会为 DOM 元素定义一些 class 或 id ,当我们为其写样式的时候会用不同的选择器,那么在选择器中我们可以使用插值来拼接一些类名等等。

$name: item;

// 使用插值
.ul-#{$name} {
  width: 100px;
  // 使用插值
  .li-#{$name} {
    width: 100%;
  }
}

// 使用插值
.box-#{$name} {
  height: 200px;
  // 使用插值
  .#{$name} {
    height: 100%;
  }
}

注:

看到上面的代码,我制定了一个 DOM 层级结构,这种结构也是很常见的,可能很多子元素的类名我们都带有 item 。

那么我们就可以把它提取为一个变量然后通过在选择器中应用插值来拼接,这样就很方便我们维护,我们想改子元素类名的时候就不需要逐一的去更改了。

编译后的 CSS 代码

.ul-item {
  width: 100px;
}
.ul-item .li-item {
  width: 100%;
}

.box-item {
  height: 200px;
}
.box-item .item {
  height: 100%;
}

# 3.2、在属性名中使用

TIP

在 Sass 属性名上也是可以使用插值的,也就是说你在写 CSS 属性名的时候你也是可以使用插值来拼接的。

$name: color;
$position: top;

body {
  background-#{$name}: orange;
  border-#{$name}: skyblue;
  padding-#{$position}: 10px;
  margin-#{$position}: 20px;
  #{$position}: 50px;
}

注:

以上代码对 CSS 的属性名使用了插值,可以用这种方式来拼接属性名,不过在实际项目中不是很常用。

编译后的 CSS 代码

body {
  background-color: orange;
  border-color: skyblue;
  padding-top: 10px;
  margin-top: 20px;
  top: 50px;
}

# 3.3、在属性值中使用

TIP

在属性值中使用插值应该算是比较常用的,插值使你在属性值中不仅可以插入值,还可以插入表达式来计算。

$one: 50px;
$two: 5;
$family: "Yahei";

.box {
  margin: $one / $two; // 除法运算
  margin: #{$one} / #{$two}; // 分隔
  font-family: "Microsoft #{$family}"; // 带引号的字符串会转换为不带引号
  width: calc(100% - #{$one * 2 * $two}); // calc函数中插值的内容会进行运算
}

编译后的 CSS 代码

.box {
  margin: 10px;
  margin: 50px/5;
  font-family: "Microsoft Yahei";
  width: calc(100% - 500px);
}

# 3.4、在注释中使用

TIP

在 Sass 中的注释里也是可以使用插值的,而且如果插值中的内容是一段表达式,将会返回表达式的结果

/* 
 * 在注释中使用插值:
 * 3 + 5 = #{3 + 5} 
 */

/* #{5 + 6 * 6} */

注:

我们可以在注释中可以这么使用插值,具体什么时候需要使用看你的需求。

编译后的 CSS 代码

@charset "UTF-8";
/* 
 * 在注释中使用插值:
 * 3 + 5 = 8 
 */
/* 41 */

# 九、Sass 注释

TIP

注释对于一名程序员来说,是极其重要,良好的注释能帮助自己或者别人阅读源码。在 Sass 中注释有两种方式

  • 类似 CSS 的注释方式,使用/*开头,结属使用 */
  • 类似 JavaScript 的注释方式,使用 //

# 1、单行注释

TIP

单行注释是在 // 后面跟你的注释内容,直到行尾。

要记住 Sass 中的单行注释不会被编译到 CSS 中,也就是说在转换为 CSS 代码后,是不会包含你写的单行注释的。

// 这是 Sass 中的单行注释
.box {
  width: 100px;
  height: 100px;
  p {
    color: red;
  }
  .item {
    background-color: skyblue;
  }
}

编译后的 CSS 代码

.box {
  width: 100px;
  height: 100px;
}
.box p {
  color: red;
}
.box .item {
  background-color: skyblue;
}

注:

转换为 CSS 后我们在 Sass 中写的单行注释消失了

# 2、多行注释

TIP

多行注释是在/* */的两个星号中间来编写注释内容,以 /*开头,换行的话每一行都以 * 号开头,最终以 */ 结尾。

多行注释是会被编译到 CSS 中的,并且在多行注释中我们可以使用插值

/*
 * 这是 Sass 的多行注释
 * 在多行注释中,还可以使用插值
 * 1 + 5 = #{ 1 + 5 }
 * 2 + 8 = #{ 2 + 8 }
 */
.box {
  width: 100px;
  height: 100px;
  p {
    color: red;
  }
  .item {
    background-color: skyblue;
  }
}

编译后的 CSS 代码

@charset "UTF-8";
/*
 * 这是 Sass 的多行注释
 * 在多行注释中,还可以使用插值
 * 1 + 5 = 6
 * 2 + 8 = 10
 */
.box {
  width: 100px;
  height: 100px;
}
.box p {
  color: red;
}
.box .item {
  background-color: skyblue;
}

# 3、以 ! 开头的注释内容

TIP

我们都知道压缩工具会删除所有的注释,有些时候为了保留一些版权声明的注释说明,可以采取以下方式进行注释

/*! 注释内容 */

也就是说在注释内容前面加上一个 ! 感叹号,这种压缩工具就不会删除这条注释信息了。不过这种注释方式用得很少,一般在 CSS 文件顶部为了声明版权信息才会使用。

/*! jQuery v3.6.4 | (c) OpenJS Foundation and other contributors | jquery.org/license */

注:

在 jQuery 压缩后的 CDN 文件中可查看到,https://www.bootcdn.cn/jquery/ (opens new window)

# 4、Sass 注释的书写规范

TIP

况来选择你使用上面哪种注释方式,其余的一些注释规范不同的团队可能有不同的标准,遵循你的团队的代码规范即可。如果没有的话你可以遵照 CSS 的注释规范即可。

给出常见的注释书写规范作为参考:

  • 注释不允许嵌套
  • 两条注释间使用换行分隔
  • 函数必须编写注释来写明函数的作用、入参和出参
  • mixin 必须编写注释写明作用
  • 公共变量必须编写注释写明作用
  • 公共样式必须编写注释写明作用
  • 用于继承的文件必须编写注释写明使用场景
  • 如有某些代码需要在后期修改或优化,需要编写注释,其注释中的内容需要以 TODO 开头有

除了上面这些规范建议在每个文件的头部注释当前文件的创建时间、作者和对于当前文件内容的描述

/*
 * Author: Arry
 * Date: 2028-06-01 19:00:00
 * Desc: This is common scss
 */

header {
  width: 1280px;
  height: 200px;
  .item {
    font-size: 12px;
    color: #333;
    &:hover {
      color: red;
    }
  }
}

编译后的 CSS 代码

/*
 * Author: Arry
 * Date: 2028-06-01 19:00:00
 * Desc: This is common scss
 */
header {
  width: 1280px;
  height: 200px;
}
header .item {
  font-size: 12px;
  color: #333;
}
header .item:hover {
  color: red;
}

# 十、微信小程序中使用 Sass

TIP

在微信小程序开发中,原生支持 Sass、Less、Typescript。

如果我们希望使用 TypeScript 或 less、Sass 去开发小程序,在微信开发者工具 1.05.2109101 以上版本开始,内置了编译模块,支持以编译插件的形式,扩展编译功能。

即:微信开发者工具会自动将 .ts 文件或 less、Sass 文件编译成对应的 js 文件 或 wxss 文件。无需我们自行配置 TS 或 Sass、Less 的编译环境。

微信开发者工具内置编译模块的好处:

  • 项目内只需要创建 .ts 文件即可,无需再生成同名的 js 文件。less、Sass 文件同理。
  • 编译流程由开发者工具控制,按需编译,开发体验更好。

详细查阅,微信小程序官方文档 - 原生支持 TypeScript、Sass、Less (opens new window)

# 1、新项目中

TIP

可在创建小程序项目时,选择对应的语言模板。目前支持的语言模板有

  • TypeScript
  • TypeScript + Less
  • TypeScript + Sass

image-20230603181323568

# 2、在旧项目中(之前未使用 Sass、Typescript)

project.config.json 文件中,修改或增加 setting 下的 useCompilerPlugins 字段为 ["typescript"],即可开启工具内置的 typescript 编译插件。

{
  "setting": {
    "useCompilerPlugins": ["typescript"]
  }
}

如需同时开启 less、Sass 编译插件,可将该字段修改为 ["typescript", "less"]。 目前支持三个编译插件:typescript、less、sass

{
  "setting": {
    "useCompilerPlugins": ["typescript", "sass"]
  }
}

如只需要用到 sass 编译插件,配置如下

{
  "setting": {
    "useCompilerPlugins": ["sass"]
  }
}

# 3、在 JavaScript 基础模板中使用 Sass

TIP

微信小程序原生支持 sass ,不需要额外安装任何其他的环境。

只需要按照下图中的步骤操作,然后就正常在页面的 .sass.scss 文件中用 sass 的语法书写代码即可自动编译并作用于页面的渲染。使用非常的高效简洁 !

image-20230603182521924

按照我们上边学习 Sass 语法完成正常的页面布局即可

image-20230603183240335

上次更新时间: 6/8/2023, 9:23:17 PM

大厂最新技术学习分享群

大厂最新技术学习分享群

微信扫一扫进群,获取资料

X