@import
Sass 扩展了 CSS 的 @import
规则, 能够导入 Sass 和 CSS 样式表,提供对 mixins、 函数 和 变量 的访问, 并将多个样式表的 CSS 组合在一起。与需要浏览器在渲染页面时发出多个 HTTP 请求的纯 CSS 导入不同, Sass 导入在编译期间完全处理。
Sass 导入的语法与 CSS 导入相同,不同之处在于允许用逗号分隔多个导入,而不是每个导入都需要单独的 @import
。
另外,在缩进语法中,导入的 URL 不需要使用引号。
⚠️ Heads up!
从 Dart Sass 1.80.0 开始,@import
规则已被弃用,并将在 Dart Sass 3.0.0 中从语言中移除。建议使用 @use
规则代替。
为什么 @import
有问题?
@import
规则存在许多严重问题:
-
@import
使所有变量、mixins 和函数都全局可访问。这使得很难(对于人或工具)追踪它们的定义位置。 -
由于一切都是全局的,库必须为其所有成员添加前缀以避免命名冲突。
-
@extend
规则也是全局的,这使得很难预测哪些样式规则会被扩展。 -
每个样式表在每次
@import
时都会被执行并输出其 CSS,这会增加编译时间并产生臃肿的输出。 -
无法定义私有成员或对下游样式表不可访问的占位选择器。
新的模块系统和 @use
规则解决了所有这些问题。
如何迁移?
我们编写了一个迁移工具,可以快速自动地将大多数基于 @import
的代码转换为基于 @use
的代码。只需指向你的入口点并运行即可!
SCSS Syntax
// 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 Syntax
// 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 Output
code {
padding: .25em;
line-height: 0;
}
ul, ol {
text-align: left;
}
ul ul, ol ol {
padding-bottom: 0;
padding-left: 0;
}
当 Sass 导入一个文件时,就好像该文件的内容直接出现在 @import
的位置。导入文件中的任何 mixins、函数和变量都可用,
并且所有的 CSS 都包含在编写 @import
的确切位置。更重要的是,在 @import
之前定义的任何 mixins、函数或变量(包括来自其他 @import
的)在导入的样式表中也是可用的。
⚠️ Heads up!
如果同一个样式表被多次导入,它将每次都被重新评估。如果它仅定义函数和 mixins,这通常不是什么大问题,但如果包含样式规则,它们将被多次编译为 CSS。
查找文件查找文件 permalink
为了避免为每个要导入的样式表都写出绝对 URL,Sass 提供了一种更简单的文件查找算法。首先,你不必明确写出要导入文件的扩展名;@import "variables"
将自动加载 variables.scss
、variables.sass
或 variables.css
。
⚠️ Heads up!
为确保样式表在每个操作系统上都能正常工作,Sass 通过 URL 而非文件路径导入文件。这意味着即使在 Windows 上,也需要使用正斜杠,而不是反斜杠。
加载路径加载路径 permalink
所有 Sass 实现都允许用户提供加载路径:Sass 在解析导入时将查找的文件系统路径。例如,如果你传递 node_modules/susy/sass
作为加载路径,你可以使用 @import "susy"
来加载 node_modules/susy/sass/susy.scss
。
不过,导入将始终首先相对于当前文件解析。只有在没有匹配的相对文件时,才会使用加载路径。这确保了在添加新库时不会意外破坏相对导入。
💡 Fun fact:
与某些其他语言不同,Sass 不要求对相对导入使用 ./
。相对导入始终可用。
局部文件局部文件 permalink
按照惯例,仅用于导入且不单独编译的 Sass 文件以 _
开头(如 _code.scss
)。这些被称为局部文件,它们告诉 Sass 工具不要尝试单独编译这些文件。导入局部文件时可以省略 _
。
索引文件索引文件 permalink
- Dart Sass
- ✓
- LibSass
- since 3.6.0
- Ruby Sass
- since 3.6.0
如果在文件夹中创建 _index.scss
或 _index.sass
,当导入该文件夹本身时,将加载该文件。
SCSS Syntax
// 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 Syntax
// 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 Output
code {
padding: .25em;
line-height: 0;
}
ul, ol {
text-align: left;
}
ul ul, ol ol {
padding-bottom: 0;
padding-left: 0;
}
自定义导入器自定义导入器 permalink
所有 Sass 实现都提供了定义自定义导入器的方法,用于控制 @import
如何定位样式表:
-
Node Sass 和 Dart Sass on npm 在其 JS API 中提供了 [
importer
选项][]。 -
Dart Sass on pub 提供了一个可由自定义导入器扩展的抽象 [
Importer
类][]。 -
Ruby Sass 提供了一个可由自定义导入器扩展的抽象 [
Importers::Base
类][]。
NestingNesting permalink
Imports are usually written at the top level of a stylesheet, but they don’t have to be. They can nested within style rules or plain CSS at-rules as well. The imported CSS is nested in that context, which makes nested imports useful for scoping a chunk of CSS to a particular element or media query. Top-level mixins, functions, and variables defined in the nested import are only available in the nested context.
SCSS Syntax
// _theme.scss
pre, code {
font-family: 'Source Code Pro', Helvetica, Arial;
border-radius: 4px;
}
// style.scss
.theme-sample {
@import "theme";
}
Sass Syntax
// _theme.sass
pre, code
font-family: 'Source Code Pro', Helvetica, Arial
border-radius: 4px
// style.sass
.theme-sample
@import theme
CSS Output
.theme-sample pre, .theme-sample code {
font-family: 'Source Code Pro', Helvetica, Arial;
border-radius: 4px;
}
💡 Fun fact:
Nested imports are very useful for scoping third-party stylesheets, but if you’re the author of the stylesheet you’re importing, it’s usually a better idea to write your styles in a mixin and include that mixin in the nested context. A mixin can be used in more flexible ways, and it’s clearer when looking at the imported stylesheet how it’s intended to be used.
⚠️ Heads up!
The CSS in nested imports is evaluated like a mixin, which means that any parent selectors will refer to the selector in which the stylesheet is nested.
SCSS Syntax
// _theme.scss
ul li {
$padding: 16px;
padding-left: $padding;
[dir=rtl] & {
padding: {
left: 0;
right: $padding;
}
}
}
// style.scss
.theme-sample {
@import "theme";
}
Sass Syntax
// _theme.sass
ul li
$padding: 16px
padding-left: $padding
[dir=rtl] &
padding:
left: 0
right: $padding
// style.sass
.theme-sample
@import theme
CSS Output
.theme-sample ul li {
padding-left: 16px;
}
[dir=rtl] .theme-sample ul li {
padding-left: 0;
padding-right: 16px;
}
Importing CSSImporting CSS permalink
- Dart Sass
- since 1.11.0
- LibSass
- partial
- Ruby Sass
- ✗
LibSass supports importing files with the extension .css
, but contrary to
the specification they’re treated as SCSS files rather than being parsed as
CSS. This behavior has been deprecated, and an update is in the works to
support the behavior described below.
In addition to importing .sass
and .scss
files, Sass can import plain old
.css
files. The only rule is that the import must not explicitly include the
.css
extension, because that’s used to indicate a plain CSS @import
.
SCSS Syntax
// code.css
code {
padding: .25em;
line-height: 0;
}
// style.scss
@import 'code';
Sass Syntax
// code.css
code {
padding: .25em;
line-height: 0;
}
// style.sass
@import code
CSS Output
code {
padding: .25em;
line-height: 0;
}
CSS files imported by Sass don’t allow any special Sass features. In order to make sure authors don’t accidentally write Sass in their CSS, all Sass features that aren’t also valid CSS will produce errors. Otherwise, the CSS will be rendered as-is. It can even be extended!
Plain CSS @import
sPlain CSS @imports permalink
- Dart Sass
- ✓
- LibSass
- partial
- Ruby Sass
- ✓
By default, LibSass handles plain CSS imports correctly. However, any custom
importers will incorrectly apply to plain-CSS @import
rules, making it
possible for those rules to load Sass files.
Because @import
is also defined in CSS, Sass needs a way of compiling plain
CSS @import
s without trying to import the files at compile time. To accomplish
this, and to ensure SCSS is as much of a superset of CSS as possible, Sass will
compile any @import
s with the following characteristics to plain CSS imports:
- Imports where the URL ends with
.css
. - Imports where the URL begins
http://
orhttps://
. - Imports where the URL is written as a
url()
. - Imports that have media queries.
SCSS Syntax
@import "theme.css";
@import "http://fonts.googleapis.com/css?family=Droid+Sans";
@import url(theme);
@import "landscape" screen and (orientation: landscape);
Sass Syntax
@import "theme.css"
@import "http://fonts.googleapis.com/css?family=Droid+Sans"
@import url(theme)
@import "landscape" screen and (orientation: landscape)
CSS Output
@import "theme.css";
@import "http://fonts.googleapis.com/css?family=Droid+Sans";
@import url(theme);
@import "landscape" screen and (orientation: landscape);
InterpolationInterpolation permalink
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.
SCSS Syntax
@mixin google-font($family) {
@import url("http://fonts.googleapis.com/css?family=#{$family}");
}
@include google-font("Droid Sans");
Sass Syntax
@mixin google-font($family)
@import url("http://fonts.googleapis.com/css?family=#{$family}")
@include google-font("Droid Sans")
CSS Output
@import url("http://fonts.googleapis.com/css?family=Droid Sans");
Import and ModulesImport and Modules permalink
- Dart Sass
- since 1.23.0
- LibSass
- ✗
- Ruby Sass
- ✗
Only Dart Sass currently supports @use
. Users of other implementations must
use the @import
rule instead.
Sass’s module system integrates seamlessly with @import
, whether you’re
importing a file that contains @use
rules or loading a file that contains
imports as a module. We want to make the transition from @import
to @use
as
smooth as possible.
Importing a Module-System FileImporting a Module-System File permalink
When you import a file that contains @use
rules, the importing file has access
to all members (even private members) defined directly in that file, but not
any members from modules that file has loaded. However, if that file contains
@forward
rules, the importing file will have access to forwarded members.
This means that you can import a library that was written to be used with the
module system.
⚠️ Heads up!
When a file with @use
rules is imported, all the CSS transitively loaded by
those is included in the resulting stylesheet, even if it’s already been
included by another import. If you’re not careful, this can result in bloated
CSS output!
Import-Only FilesImport-Only Files permalink
An API that makes sense for @use
might not make sense for @import
. For
example, @use
adds a namespace to all members by default so you can safely use
short names, but @import
doesn’t so you might need something longer. If you’re
a library author, you may be concerned that if you update your library to use
the new module system, your existing @import
-based users will break.
To make this easier, Sass also supports import-only files. If you name a file
<name>.import.scss
, it will only be loaded for imports, not for @use
s. This
way, you can retain compatibility for @import
users while still providing a
nice API for users of the new module system.
SCSS Syntax
// _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 Syntax
// _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-*
Configuring Modules Through ImportsConfiguring Modules Through Imports permalink
- Dart Sass
- since 1.24.0
- LibSass
- ✗
- Ruby Sass
- ✗
You can configure modules that are loaded through an @import
by defining
global variables prior the @import
that first loads that module.
SCSS Syntax
// _library.scss
$color: blue !default;
a {
color: $color;
}
// _library.import.scss
@forward 'library' as lib-*;
// style.sass
$lib-color: green;
@import "library";
Sass Syntax
$color: blue !default
a
color: $color
// _library.import.sass
@forward 'library' as lib-*
// style.sass
$lib-color: green
@import "library"
CSS Output
a {
color: green;
}
⚠️ Heads up!
Modules are only loaded once, so if you change the configuration after you
@import
a module for the first time (even indirectly), the change will be
ignored if you @import
the module again.
Loading a Module That Contains ImportsLoading a Module That Contains Imports permalink
When you use @use
(or @forward
) load a module that uses @import
, that
module will contain all the public members defined by the stylesheet you load
and everything that stylesheet transitively imports. In other words,
everything that’s imported is treated as though it were written in one big stylesheet.
This makes it easy to convert start using @use
in a stylesheet even before all
the libraries you depend on have converted to the new module system. Be aware,
though, that if they do convert their APIs may well change!