@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.scssvariables.sassvariables.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 如何定位样式表

嵌套嵌套 永久链接

导入通常写在样式表的顶层,但不必这样。它们也可以嵌套在 样式规则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 @importCSS @import 永久链接

兼容性
Dart Sass
LibSass
部分
Ruby Sass

默认情况下,LibSass 正确处理纯 CSS 导入。但是,任何 自定义导入器 将不正确地应用于纯 CSS @import 规则,从而使这些规则能够加载 Sass 文件。

因为 @import 也在 CSS 中定义,所以 Sass 需要一种方法来编译纯 CSS @import,而不会在编译时尝试导入这些文件。为了实现这一点,并确保 SCSS 尽可能地成为 CSS 的超集,Sass 将把具有以下特征的任何 @import 编译为纯 CSS 导入

  • 导入的 URL.css 结尾。
  • 导入的 URLhttp://https:// 开头。
  • 导入的 URL 写成 url()
  • 具有媒体查询的导入。
Playground

SCSS 语法

@import "theme.css";
@import "http://fonts.googleapis.com/css?family=Droid+Sans";
@import url(theme);
@import "landscape" screen and (orientation: landscape);
Playground

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 参数。

Playground

SCSS 语法

@mixin google-font($family) {
  @import url("http://fonts.googleapis.com/css?family=#{$family}");
}

@include google-font("Droid Sans");
Playground

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,它们很可能会更改!