解决 @import
痛点的替代品
与 @import
的主要区别
虽然 @use
是用来替代 @import
的,但它被设计成了不同的工作方式,这是有意的。以下是两者之间主要的不同点:
@use
仅使变量、函数和混入可以在当前文件范围使用。它不会将这些东西放到全局作用域。这意味着你可以更容易判断这些东西引用自哪里,并且也意味着你能够用更短的变量名而不用担心名称冲突。
@use
对每一个文件都只加载一次。这可以确保不会生成多余的 CSS 代码。
@use
只能出现在文件开头。并且不能写在嵌套的样式规则中。
对于每个 @use
命令,都只能拥有一个引入的 URL。@import
可以引入多个。
@use
不论是使用 sass
还是 scss
语法,其 URL 都必须添加引号。
基本使用
可以使用 @use
从其它 Sass
样式表中加载混入(mixin)、函数(function)和变量,并且将多个样式表的 css
组合到一起。被 @use
加载的样式表被称作“模块(modules)”。同时 Sass
内部也提供了一系列有用的模块。
最基础的使用方法是 @use "<url>"
,通过 URL 来加载模块。任何通过这种方式加载的样式不论被加载多少次,在编译后输出的 CSS 中只会出现一次,避免了 @import
中多次出现的冗余问题。
@use
必须放在除了 @forward
以外规则的上方,包括样式规则。但是在配置模块时可以在 @use
前定义变量。
1 2 3 4 5
| .code { padding: 0.25em; line-height: 0; }
|
1 2 3 4 5 6 7 8 9 10 11
| ul, ol { text-align: left; & & { padding: { bottom: 0; left: 0; } } }
|
1 2 3
| @use 'foundation/code'; @use 'foundation/lists';
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| code { padding: 0.25em; line-height: 0; }
ul, ol { text-align: left; } ul ul, ol ol { padding-bottom: 0; padding-left: 0; }
|
加载成员
你可以通过 <namespace>.<name>
的形式来使用混入(mixin)、函数(function)和变量。在默认情况下,模块链接名就是 namespace
命名空间。
被加载的成员(变量、函数、混入)只能在加载它们的地方使用。其它样式表需要编写其自身的 @use
规则来使用他们。这有助于判断引用的成员来自哪里。如果你想一次性从多个文件中加载成员,你可以使用 @forward
将需要的成员全部转发到一个文件中。
因为使用了命名空间,我们可以安心的使用简单的变量命名例如 $width
, $height
。这与使用 @import
不同,它避免了使用像 $foo-bar-width
这样繁琐的命名来防止名称冲突。且能让你的代码更加简洁易懂。
1 2 3 4 5 6
| $radius: 3px;
@mixin rounded { border-radius: $radius; }
|
1 2 3 4 5 6 7
| @use 'src/corners';
.button { @include corners.rounded; padding: 5px + corners.$radius; }
|
1 2 3 4
| .button { border-radius: 3px; padding: 8px; }
|
自定义命名空间
默认情况下,命名空间是 URL 最后一个部分,且不带扩展名。然而你可能想要选择一个不同的命名空间,比如更短的命名空间,又或者需要加载多个文件名相同的模块。此时你可以通过 @use "<url>" as <namespace>
来自定义命名空间。
1 2 3 4 5 6
| $radius: 3px;
@mixin rounded { border-radius: $radius; }
|
1 2 3 4 5 6 7
| @use 'src/corners' as c;
.button { @include c.rounded; padding: 5px + c.$radius; }
|
1 2 3 4
| .button { border-radius: 3px; padding: 8px; }
|
甚至还可以通过 @use "<url>" as *
来忽略命名空间。不过我们只建议在编写个人使用的样式表时这样做;否则他人使用时可能会发生命名冲突!
1 2 3 4 5 6
| $radius: 3px;
@mixin rounded { border-radius: $radius; }
|
1 2 3 4 5 6 7
| @use 'src/corners' as *;
.button { @include rounded; padding: 5px + $radius; }
|
1 2 3 4
| .button { border-radius: 3px; padding: 8px; }
|
私有成员
作为一个样式表作者,你可能希望用户在样式表外部只能访问你让他们访问的成员。Sass
提供了一种简单的方式来定义私有成员,成员名称以 -
或者 _
都视为私有成员。在你的样式表内部可以正常访问这些成员,但这些成员不会存在于向外部公开的模块接口中。这意味着加载你模块的样式表看不见他们。
如果你想让模块对整个包而不是单个模块不可见,你只需要避免在你包的任意入口(你告知用户的包入口)转发(forward
)模块即可。当然也可以在转发模块时隐藏部分成员
1 2 3 4 5 6
| $-radius: 3px;
@mixin rounded { border-radius: $-radius; }
|
1 2 3 4 5 6 7 8 9
| @use 'src/corners';
.button { @include corners.rounded;
padding: 5px + corners.$-radius; }
|
配置模块
定义变量时,通过 !default
这个 flag 使其变为可配置的。使用 @use <url> with ( <variable>: <value>, <variable>: <value> )
在加载模块时应用配置。配置中的值会覆盖模块中对应变量的默认值。
1 2 3 4 5 6 7 8 9
| $black: #000 !default; $border-radius: 0.25rem !default; $box-shadow: 0 0.5rem 1rem rgba($black, 0.15) !default;
code { border-radius: $border-radius; box-shadow: $box-shadow; }
|
1 2 3 4 5
| @use 'library' with ( $black: #222, $border-radius: 0.1rem );
|
1 2 3 4
| code { border-radius: 0.1rem; box-shadow: 0 0.5rem 1rem rgba(34, 34, 34, 0.15); }
|
使用 mixin
使用 @use ... with
配置模块非常方便,尤其是在使用一开始用 @import
编写的库时。但它并不是特别灵活,我们不建议将其用于更高级的用例。如果您发现自己想将 Map
作为配置传递从而一次配置多个变量,或者在模块加载后更新配置,请考虑编写一个 mixin
来设置您的变量,然后再编写一个 mixin
来注入您的样式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| $-black: #000; $-border-radius: 0.25rem; $-box-shadow: null;
@function -box-shadow() { @return $-box-shadow or (0 0.5rem 1rem rgba($-black, 0.15)); }
@mixin configure($black: null, $border-radius: null, $box-shadow: null) { @if $black { $-black: $black !global; } @if $border-radius { $-border-radius: $border-radius !global; } @if $box-shadow { $-box-shadow: $box-shadow !global; } }
@mixin styles { code { border-radius: $-border-radius; box-shadow: -box-shadow(); } }
|
1 2 3 4 5 6 7 8
| @use 'library';
@include library.configure($black: #222, $border-radius: 0.1rem);
@include library.styles;
|
1 2 3 4
| code { border-radius: 0.1rem; box-shadow: 0 0.5rem 1rem rgba(34, 34, 34, 0.15); }
|
重新定义变量
加载一个模块后,你可以重新定义其变量。
1 2 3
| @use 'library'; library.$color: blue;
|
1 2 3 4
| @use 'library'; @use 'override'; @debug library.$color;
|
在使用 as *
时这种方法依然有效
1 2 3
| @use 'library' as *; $color: blue;
|
1 2 3 4
| @use 'library'; @use 'override'; @debug library.$color;
|
模块加载
你可以在引入时省略扩展名 @use "variables"
,Sass
会自动加载 variables.scss
,variables.sass
或 variables.css
。
加载路径
用户可以提供加载路径给 Sass
解析,Sass
在定位模块时将使用加载路径。例如 node_modules/susy/sass
作为一个加载路径,你可以通过 @use "susy"
来加载 node_modules/susy/sass/susy.scss
。
Sass
会优先加载当前文件目录下的模块,如果不存在才会使用加载路径。这可以确保在添加新库时不会出现错误的引入。
块
作为一个约定,以 _
开头的 Sass
文件被认作为一个模块。这种文件被称为“块”,Sass
会避免单独编译这些文件。在引入块时可以忽略 _
。同时
主文件
如果在某个文件夹中有一个 _index.scss
或 _index.sass
文件,在以该文件夹为路径加载时,该主文件会被自动载入。
1 2 3 4 5
| code { padding: 0.25em; line-height: 0; }
|
1 2 3 4 5 6 7 8 9 10 11 12
| ul, ol { text-align: left;
& & { padding: { bottom: 0; left: 0; } } }
|
1 2 3
| @use 'code'; @use 'lists';
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| code { padding: 0.25em; line-height: 0; }
ul, ol { text-align: left; } ul ul, ol ol { padding-bottom: 0; padding-left: 0; }
|