Sass 扩展了 CSS 的 @import
规则,能够导入 Sass 和 CSS 样式表,提供对 mixins的访问 、functions 和 variables 并将多个样式表的 CSS 组合在一起。 与需要浏览器在呈现页面时发出多个 HTTP 请求的纯 CSS 导入不同,Sass 导入完全在编译期间处理。
Sass 导入与 CSS 导入具有相同的语法,不同之处在于它们允许多个导入用逗号分隔,而不是要求每个导入都有自己的“@import”。 此外,在 缩进语法 中,导入的 URL 不需要有引号。
⚠️ Heads up!
Sass 团队不鼓励继续使用@import
规则。 Sass 将在未来几年内逐步淘汰,并最终将其从语言中完全移除。 更喜欢 @use
规则。 (请注意,目前只有 Dart Sass 支持@use
。其他实现的用户必须改用@import
规则。)
@import
有什么问题?
@import
规则有很多严重的问题:
@import
使所有变量、mixin 和函数都可以全局访问。 这使得人们(或工具)很难分辨任何东西的定义位置。- 因为一切都是全球性的,图书馆必须为其所有成员添加前缀以避免命名冲突。
@extend
规则 也是全局的,这使得很难预测将扩展哪些样式规则。- 每个样式表都被执行,并且它的 CSS 发出 每次 它是
@import
过的,这会增加编译时间并产生臃肿的输出。 - 无法定义下游样式表无法访问的私有成员或占位符选择器。
新的模块系统和@use
规则解决了所有这些问题。
How Do I Migrate?
我们已经编写了一个迁移工具,它可以在瞬间自动将大多数基于@import
的代码转换为基于@use
的代码。 只需将它指向您的入口点并让它运行!
当 Sass 导入一个文件时,该文件被评估为好像它的内容直接出现在 @import
的位置。 导入文件中的任何 mixins、functions 和 variables 都是 可用,并且其所有 CSS 都包含在写入“@import”的确切位置。 此外,在“@import”(包括来自其他“@import”)之前定义的任何混入、函数或变量都可以在导入的样式表中使用。
⚠️ 注意!
如果多次导入同一个样式表,则每次都会重新评估。 如果它只是定义函数和混合,这通常没什么大不了的,但如果它包含样式规则,它们将被多次编译为 CSS。
查找文件
为您导入的每个样式表写出绝对 URL 不会有任何乐趣,因此 Sass 用于查找要导入的文件的算法使它更容易一些。 对于初学者,您不必明确写出要导入的文件的扩展名; @import "variables"
将自动加载 variables.scss
、variables.sass
或 variables.css
。
⚠️ 注意!
为确保样式表适用于每个操作系统,Sass 通过_URL 而不是 文件路径_导入文件。 这意味着您需要使用正斜杠,而不是反斜杠,即使您在 Windows 上也是如此。
加载路径
所有 Sass 实现都允许用户提供 加载路径 :Sass 在解析导入时将查找的文件系统路径。 例如,如果您将 node_modules/susy/sass
作为加载路径传递,则可以使用 @import "susy"
加载 node_modules/susy/sass/susy.scss
。
不过,导入总是首先相对于当前文件进行解析。 只有在不存在与导入匹配的相关文件时才会使用加载路径。 这可确保您在添加新库时不会不小心弄乱您的相关导入。
💡 有趣的事实:
与其他一些语言不同,Sass 不要求您使用 ./
进行相对导入。 相对导入始终可用。
部分
按照惯例,仅用于导入而非自行编译的 Sass 文件以“_”开头(如“_code.scss”)。 这些称为 partials,它们告诉 Sass 工具不要尝试自行编译这些文件。 导入部分时,您可以省略 _
。
Index Files
兼容性: Dart Sass ✓ | LibSass since 3.6.0 | Ruby Sass since 3.6.0
如果您在文件夹中编写 _index.scss
或 _index.sass
,当导入文件夹本身时,该文件将加载到它的位置。
// foundation/_code.scss
code {
padding: .25em;
line-height: 0;
}
// foundation/_lists.scss
ul, ol {
text-align: left;
& & {
padding: {
bottom: 0;
left: 0;
}
}
}
// foundation/_index.scss
@import 'code', 'lists';
// style.scss
@import 'foundation';
自定义进口商
所有 Sass 实现都提供了一种定义自定义导入器的方法,它控制 @import
如何定位样式表:
- Node Sass 和 npm 上的 Dart Sass 提供了一个 [
importer
选项](https ://github.com/sass/node-sass#importer--v200---experimental)作为他们 JS API 的一部分。 - Dart Sass on pub 提供了一个抽象的
Importer
类,可以由自定义导入器扩展。 - Ruby Sass 提供了一个抽象的
Importers::Base
类 可以由自定义导入器扩展。
嵌套
导入通常写在样式表的顶层,但并非必须如此。 它们也可以嵌套在 style rules 或 plain CSS at-rules 中。 导入的 CSS 嵌套在该上下文中,这使得嵌套导入对于将 CSS 块限定为特定元素或媒体查询非常有用。 请注意,顶级 mixins、functions 和 variables 已定义 不过,在嵌套导入中,它们仍然是全局定义的。
// _theme.scss
pre, code {
font-family: 'Source Code Pro', Helvetica, Arial;
border-radius: 4px;
}
// style.scss
.theme-sample {
@import "theme";
}
💡 Fun fact:
嵌套导入对于确定第三方样式表的范围非常有用,但如果您是要导入的样式表的作者,通常最好在 mixin 并将该 mixin 包含在嵌套上下文中。 mixin 可以以更灵活的方式使用,并且在查看导入的样式表时会更清楚它的用途。
⚠️ 注意!
嵌套导入中的 CSS 像混合一样被评估,这意味着任何 父选择器 将引用样式表嵌套在其中的选择器。
// _theme.scss
ul li {
$padding: 16px;
padding-left: $padding;
[dir=rtl] & {
padding: {
left: 0;
right: $padding;
}
}
}
// style.scss
.theme-sample {
@import "theme";
}
导入 CSS
LibSass 支持导入扩展名为 .css 的文件,但与规范相反,它们被视为 SCSS 文件而不是被解析为 CSS。 此行为已被弃用,并且正在进行更新以支持下述行为。
除了导入 .sass 和 .scss 文件外,Sass 还可以导入普通的旧 .css 文件。 唯一的规则是导入_不得_显式包含 .css
扩展名,因为它用于指示 plain CSS @import
.
// code.css
code {
padding: .25em;
line-height: 0;
}
// style.scss
@import 'code';
Sass 导入的 CSS 文件不允许任何特殊的 Sass 特性。 为了确保作者不会不小心在他们的 CSS 中编写 Sass,所有不是有效 CSS 的 Sass 特性都会产生错误。 否则,CSS 将按原样呈现。 它甚至可以扩展!
纯CSS导入
默认情况下,LibSass 会正确处理纯 CSS 导入。 但是,任何自定义导入器都将错误地应用于纯 CSS @import 规则,从而使这些规则可以加载 Sass 文件。
因为 @import
也在 CSS 中定义,Sass 需要一种编译纯 CSS @import
的方法,而无需在编译时尝试导入文件。 为了实现这一点,并确保 SCSS 尽可能多地成为 CSS 的超集,Sass 会将具有以下特征的任何“@import”编译为纯 CSS 导入:
- 导入 URL 以
.css
结尾的位置。 - 导入 URL 以“http://”或“https://”开头的位置。
- 导入 URL 写为
url()
的地方。 - 具有媒体查询的导入。
@import "theme.css";
@import "http://fonts.googleapis.com/css?family=Droid+Sans";
@import url(theme);
@import "landscape" screen and (orientation: landscape);
Interpolation
Although Sass imports can’t use interpolation (to make sure it’s always possible to tell where mixins, functions, and variables come from), plain CSS imports can. This makes it possible to dynamically generate imports, for example based on mixin parameters.
@mixin google-font($family) {
@import url("http://fonts.googleapis.com/css?family=#{$family}");
}
@include google-font("Droid Sans");
导入和模块
目前只有 Dart Sass 支持@use。 其他实现的用户必须改用@import 规则。
Sass 的 模块系统 与 @import
无缝集成,无论您是导入包含 @use
规则的文件还是加载包含作为模块导入的文件。 我们希望从“@import”到“@use”的过渡尽可能顺利。
导入模块系统文件
当您导入包含“@use”规则的文件时,导入文件可以访问直接在该文件中定义的所有成员(甚至私有成员),但_不能_来自该文件加载的模块的任何成员。 但是,如果该文件包含 @forward
规则,则导入文件将有权访问转发的成员。 这意味着您可以导入一个库,该库是为与模块系统一起使用而编写的。
⚠️ 注意!
当导入带有“@use”规则的文件时,所有由这些文件传递加载的 CSS 都会包含在生成的样式表中,即使它已经被另一个导入包含在内。 如果你不小心,这可能会导致 CSS 输出臃肿!
只导入文件
对 @use
有意义的 API 可能对 @import
没有意义。 例如,@use
默认为所有成员添加命名空间,因此您可以安全地使用短名称,但 @import
不会,因此您可能需要更长的名称。 如果您是图书馆作者,您可能会担心,如果您更新您的图书馆以使用新的模块系统,您现有的基于 @import
\ 的用户将会中断。
为了使这更容易,Sass 还支持 import-only files。 如果您将文件命名为<name>.import.scss
,它只会为导入加载,而不是为“@use”加载。 通过这种方式,您可以保持对“@import”用户的兼容性,同时仍然为新模块系统的用户提供一个不错的 API。
// _reset.scss
// Module system users write `@include reset.list()`.
@mixin list() {
ul {
margin: 0;
padding: 0;
list-style: none;
}
}
// _reset.import.scss
// Legacy import users can keep writing `@include reset-list()`.
@forward "reset" as reset-*;
Configuring Modules Through Imports
兼容性: Dart Sass since 1.24.0 | LibSass ✗ | Ruby Sass ✗
您可以 配置模块 通过在首先加载该模块的 @import
之前定义全局变量来通过 @import
加载。
// _library.scss
$color: blue !default;
a {
color: $color;
}
// _library.import.scss
@forward 'library' as lib-*;
// style.sass
$lib-color: green;
@import "library";
⚠️ 注意!
模块只加载一次,因此如果您在第一次@import
模块后更改配置(即使是间接的),如果您再次@import
模块,更改将被忽略。
加载包含导入的模块
当您使用“@use”(或“@forward”)加载一个使用@import
的模块时,该模块将包含您加载的样式表定义的所有公共成员_以及_样式表传递导入的所有内容。 换句话说,导入的所有内容都被视为是在一个大样式表中编写的。
这使得在样式表中使用“@use”开始转换变得容易,甚至在您依赖的所有库都转换为新模块系统之前。 但是请注意,如果他们确实转换了,他们的 API 很可能会发生变化!