@import
Sass 扩展了 CSS 的 @import
规则,使其能够导入 Sass 和 CSS 样式表,提供对 mixin、函数 和 变量 的访问,并结合多个样式表的 CSS。与需要浏览器在渲染页面时发出多个 HTTP 请求的普通 CSS 导入不同,Sass 导入在编译期间完全处理。
Sass 导入的语法与 CSS 导入相同,只是允许用逗号分隔多个导入,而不是要求每个导入都使用自己的 @import
。此外,在 缩进语法 中,导入的 URL 不需要引号。
⚠️ 注意!
Sass 团队不鼓励继续使用 @import
规则。Sass 将在未来几年 逐步淘汰它,最终完全从语言中删除它。建议改为使用 @use
规则。(请注意,目前只有 Dart Sass 支持 @use
。其他实现的使用者必须使用 @import
规则。)
@import
的问题是什么?
@import
规则存在一些严重问题
-
@import
使所有变量、mixin 和函数在全局范围内可用。这使得人们(或工具)很难确定任何东西是在哪里定义的。 -
由于一切都处于全局范围内,库必须为所有成员添加前缀,以避免命名冲突。
-
@extend
规则 也是全局的,这使得很难预测哪些样式规则会被扩展。 -
每次导入样式表时都会执行它并发出其 CSS,这会增加编译时间并产生臃肿的输出。
-
以前无法定义私有成员或对下游样式表不可访问的占位符选择器。
新的模块系统和 @use
规则解决了所有这些问题。
如何迁移?
我们编写了一个 迁移工具,可以自动将大多数基于 @import
的代码转换为基于 @use
的代码。只需将其指向您的入口点,然后运行它即可!
SCSS 语法
// foundation/_code.scss
code {
padding: .25em;
line-height: 0;
}
// foundation/_lists.scss
ul, ol {
text-align: left;
& & {
padding: {
bottom: 0;
left: 0;
}
}
}
// style.scss
@import 'foundation/code', 'foundation/lists';
Sass 语法
// foundation/_code.sass
code
padding: .25em
line-height: 0
// foundation/_lists.sass
ul, ol
text-align: left
& &
padding:
bottom: 0
left: 0
// style.sass
@import foundation/code, foundation/lists
CSS 输出
code {
padding: .25em;
line-height: 0;
}
ul, ol {
text-align: left;
}
ul ul, ol ol {
padding-bottom: 0;
padding-left: 0;
}
当 Sass 导入文件时,该文件会被评估,就像其内容直接出现在 @import
的位置一样。来自导入文件的任何 mixin、函数 和 变量 都可用,并且所有 CSS 都包含在编写 @import
的确切位置。更重要的是,在 @import
之前定义的任何 mixin、函数或变量(包括来自其他 @import
的变量)都可以在导入的样式表中使用。
⚠️ 注意!
如果同一个样式表被导入多次,它将每次都被重新评估。如果它只是定义了函数和 mixin,这通常不是什么大问题,但如果它包含样式规则,那么它们将被编译成 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
)。这些被称为部分,它们告诉 Sass 工具不要尝试单独编译这些文件。在导入部分时,您可以省略 _
。
索引文件索引文件 永久链接
- Dart Sass
- ✓
- LibSass
- 自 3.6.0 起
- Ruby Sass
- 自 3.6.0 起
如果您在文件夹中编写了 _index.scss
或 _index.sass
,则当导入文件夹本身时,该文件将被加载到其位置。
SCSS 语法
// 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 语法
// foundation/_code.sass
code
padding: .25em
line-height: 0
// foundation/_lists.sass
ul, ol
text-align: left
& &
padding:
bottom: 0
left: 0
// foundation/_index.sass
@import code, lists
// style.sass
@import foundation
CSS 输出
code {
padding: .25em;
line-height: 0;
}
ul, ol {
text-align: left;
}
ul ul, ol ol {
padding-bottom: 0;
padding-left: 0;
}
自定义导入器自定义导入器 永久链接
所有 Sass 实现都提供了一种定义自定义导入器的方法,它控制 @import
如何定位样式表
-
Node Sass 和 npm 上的 Dart Sass 在其 JS API 中提供了一个
importer
选项。 -
pub 上的 Dart Sass 提供了一个抽象
Importer
类,可以通过自定义导入器扩展该类。 -
Ruby Sass 提供了一个抽象
Importers::Base
类,可以通过自定义导入器扩展该类。
嵌套嵌套 永久链接
导入通常写在样式表的顶层,但不必这样。它们也可以嵌套在 样式规则 或 纯 CSS at-rules 中。导入的 CSS 在该上下文中嵌套,这使得嵌套导入对于将一组 CSS 限制在特定元素或媒体查询中非常有用。在嵌套导入中定义的顶层 mixin、函数 和 变量 仅在嵌套的上下文中可用。
SCSS 语法
// _theme.scss
pre, code {
font-family: 'Source Code Pro', Helvetica, Arial;
border-radius: 4px;
}
// style.scss
.theme-sample {
@import "theme";
}
Sass 语法
// _theme.sass
pre, code
font-family: 'Source Code Pro', Helvetica, Arial
border-radius: 4px
// style.sass
.theme-sample
@import theme
CSS 输出
.theme-sample pre, .theme-sample code {
font-family: 'Source Code Pro', Helvetica, Arial;
border-radius: 4px;
}
💡 有趣的事实
嵌套导入对于限制第三方样式表非常有用,但是如果您是正在导入的样式表的作者,那么通常最好将您的样式写在一个 mixin 中,并将该 mixin 包含在嵌套的上下文中。Mixin 可以更灵活地使用,并且在查看导入的样式表时可以更清楚地了解其预期用途。
⚠️ 注意!
嵌套导入中的 CSS 的评估方式类似于 mixin,这意味着任何 父选择器 都将引用嵌套样式表的选择器。
SCSS 语法
// _theme.scss
ul li {
$padding: 16px;
padding-left: $padding;
[dir=rtl] & {
padding: {
left: 0;
right: $padding;
}
}
}
// style.scss
.theme-sample {
@import "theme";
}
Sass 语法
// _theme.sass
ul li
$padding: 16px
padding-left: $padding
[dir=rtl] &
padding:
left: 0
right: $padding
// style.sass
.theme-sample
@import theme
CSS 输出
.theme-sample ul li {
padding-left: 16px;
}
[dir=rtl] .theme-sample ul li {
padding-left: 0;
padding-right: 16px;
}
导入 CSS导入 CSS 永久链接
- Dart Sass
- 自 1.11.0 起
- LibSass
- 部分
- Ruby Sass
- ✗
LibSass 支持导入扩展名为 .css
的文件,但与规范相反,它们被视为 SCSS 文件,而不是被解析为 CSS。此行为已被弃用,并且正在进行更新以支持下面描述的行为。
除了导入 .sass
和 .scss
文件之外,Sass 还能够导入普通的 .css
文件。唯一的规则是导入不能显式包含 .css
扩展名,因为该扩展名用于指示 纯 CSS @import
。
SCSS 语法
// code.css
code {
padding: .25em;
line-height: 0;
}
// style.scss
@import 'code';
Sass 语法
// code.css
code {
padding: .25em;
line-height: 0;
}
// style.sass
@import code
CSS 输出
code {
padding: .25em;
line-height: 0;
}
Sass 导入的 CSS 文件不允许使用任何特殊的 Sass 功能。为了确保作者不会意外地在他们的 CSS 中编写 Sass,所有不是有效 CSS 的 Sass 功能都会产生错误。否则,CSS 将按原样呈现。它甚至可以被 扩展!
纯 CSS @import
纯 CSS @import 永久链接
- Dart Sass
- ✓
- LibSass
- 部分
- Ruby Sass
- ✓
默认情况下,LibSass 正确处理纯 CSS 导入。但是,任何 自定义导入器 将不正确地应用于纯 CSS @import
规则,从而使这些规则能够加载 Sass 文件。
因为 @import
也在 CSS 中定义,所以 Sass 需要一种方法来编译纯 CSS @import
,而不会在编译时尝试导入这些文件。为了实现这一点,并确保 SCSS 尽可能地成为 CSS 的超集,Sass 将把具有以下特征的任何 @import
编译为纯 CSS 导入
- 导入的 URL 以
.css
结尾。 - 导入的 URL 以
http://
或https://
开头。 - 导入的 URL 写成
url()
。 - 具有媒体查询的导入。
SCSS 语法
@import "theme.css";
@import "http://fonts.googleapis.com/css?family=Droid+Sans";
@import url(theme);
@import "landscape" screen and (orientation: landscape);
Sass 语法
@import "theme.css"
@import "http://fonts.googleapis.com/css?family=Droid+Sans"
@import url(theme)
@import "landscape" screen and (orientation: landscape)
CSS 输出
@import "theme.css";
@import "http://fonts.googleapis.com/css?family=Droid+Sans";
@import url(theme);
@import "landscape" screen and (orientation: landscape);
插值插值永久链接
尽管 Sass 导入不能使用 插值(为了确保始终能够知道 mixin、函数 和 变量 来自哪里),但纯 CSS 导入可以。这使得动态生成导入成为可能,例如基于 mixin 参数。
SCSS 语法
@mixin google-font($family) {
@import url("http://fonts.googleapis.com/css?family=#{$family}");
}
@include google-font("Droid Sans");
Sass 语法
@mixin google-font($family)
@import url("http://fonts.googleapis.com/css?family=#{$family}")
@include google-font("Droid Sans")
CSS 输出
@import url("http://fonts.googleapis.com/css?family=Droid Sans");
导入和模块导入和模块永久链接
- Dart Sass
- 自 1.23.0 起
- LibSass
- ✗
- Ruby Sass
- ✗
目前只有 Dart Sass 支持 @use
。其他实现的用户必须使用 @import
规则。
Sass 的 模块系统 与 @import
无缝集成,无论您是导入包含 @use
规则的文件还是加载包含导入作为模块的文件。我们希望让从 @import
到 @use
的过渡尽可能地平滑。
导入模块系统文件导入模块系统文件永久链接
当您导入包含 @use
规则的文件时,导入文件可以访问该文件中直接定义的所有成员(包括私有成员),但不包括该文件加载的模块中的任何成员。但是,如果该文件包含 @forward
规则,则导入文件将可以访问转发成员。这意味着您可以导入一个专门用于模块系统而编写的库。
⚠️ 注意!
当导入包含 @use
规则的文件时,这些规则间接加载的所有 CSS 都将包含在生成的样式表中,即使它已经被另一个导入包含了。如果您不小心,这会导致 CSS 输出膨胀!
仅导入文件仅导入文件永久链接
对 @use
有意义的 API 可能对 @import
不起作用。例如,@use
默认情况下会为所有成员添加命名空间,因此您可以安全地使用短名称,但 @import
不会,因此您可能需要更长的名称。如果您是库作者,您可能会担心,如果您将库更新为使用新的模块系统,您的现有 @import
用户将出现问题。
为了简化此操作,Sass 还支持仅导入文件。如果您将文件命名为 <name>.import.scss
,它将只加载用于导入,而不是用于 @use
。这样,您可以为 @import
用户保留兼容性,同时为新的模块系统用户提供一个不错的 API。
SCSS 语法
// _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-*;
Sass 语法
// _reset.sass
// Module system users write `@include reset.list()`.
@mixin list()
ul
margin: 0
padding: 0
list-style: none
// _reset.import.sass
// Legacy import users can keep writing `@include reset-list()`.
@forward "reset" as reset-*
通过导入配置模块通过导入配置模块永久链接
- Dart Sass
- 自 1.24.0 起
- LibSass
- ✗
- Ruby Sass
- ✗
您可以 配置 通过 @import
加载的模块,方法是在第一个加载该模块的 @import
之前定义全局变量。
SCSS 语法
// _library.scss
$color: blue !default;
a {
color: $color;
}
// _library.import.scss
@forward 'library' as lib-*;
// style.sass
$lib-color: green;
@import "library";
Sass 语法
$color: blue !default
a
color: $color
// _library.import.sass
@forward 'library' as lib-*
// style.sass
$lib-color: green
@import "library"
CSS 输出
a {
color: green;
}
⚠️ 注意!
模块只加载一次,因此如果您在第一次 @import
模块(即使是间接的)之后更改配置,那么如果您再次 @import
该模块,该更改将被忽略。
加载包含导入的模块加载包含导入的模块永久链接
当您使用 @use
(或 @forward
)加载使用 @import
的模块时,该模块将包含您加载的样式表定义的所有公共成员以及该样式表间接导入的所有内容。换句话说,所有导入的内容都将被视为在一个大型样式表中编写。
这使得即使在您依赖的所有库都转换为新的模块系统之前,也更容易开始在样式表中使用 @use
。但是请注意,如果它们确实转换了它们的 API,它们很可能会更改!