传送门:Sass中文网 传送门:Sass 教程 | 菜鸟教程
关于@use和@import的区别
功能/特性 | @import | @use |
---|---|---|
作用域 | 共享同一个作用域 | 创建命名空间,具有隔离性 |
重复加载 | 可能导致重复加载 | 保证每个模块只加载一次 |
推荐版本 | 较旧版本的导入方式 | 新版本 Sass 推荐的导入方式 |
命名空间 | 无 | 可以自定义命名空间 |
模块化支持 | 较弱 | 提供更好的模块化支持 |
性能 | 可能存在性能问题 | 更优化的性能 |
避免全局污染 | 不提供隔离性 | 提供隔离性 |
导入方式 | 使用 @import 导入 | 使用 @use 导入 |
上面表格就列出了二者的区别,然后我们来重点看一下重复加载和命名空间。
重复加载
当使用 @import
导入模块时,如果在多个文件中多次导入同一个文件,可能会导致重复加载的问题。这意味着被导入的文件将在每个使用了 @import
的文件中都被加载一次,导致样式表中包含多份相同的样式,从而影响性能和增加文件大小。
让我们通过一个示例来说明重复加载的问题:
假设有以下两个 SCSS 文件:
文件:_variables.scss
// _variables.scss $primary-color: #007bff; $secondary-color: #6c757d;
文件:styles1.scss
// styles1.scss @import 'variables'; body { background-color: $primary-color; }
文件:styles2.scss
// styles2.scss @import 'variables'; button { background-color: $secondary-color; }
在这个示例中,我们有两个样式文件 styles1.scss
和 styles2.scss
,它们分别使用 @import
导入了同一个 _variables.scss
文件。由于 styles1.scss
和 styles2.scss
都导入了 _variables.scss
,在编译这两个样式文件时,_variables.scss
将被加载两次。
编译后的结果如下所示:
编译后的 styles1.css
:
/* _variables.scss 中的内容被导入到这里 */ body { background-color: #007bff; }
编译后的 styles2.css
:
/* _variables.scss 中的内容被导入到这里 */ button { background-color: #6c757d; }
可以看到,styles1.css
和 styles2.css
中都包含了 _variables.scss
中定义的样式,而实际上 _variables.scss
中的内容只需要加载一次,然后在多个样式文件中共享。重复加载会增加 CSS 文件的大小,影响性能,并可能导致样式冲突问题。
而使用 @use
导入方式可以避免重复加载问题,因为它会确保每个模块只加载一次,即使在多个文件中导入。这样可以优化性能,并保持样式表的精简和一致性。
命名空间
@import是没有命名空间的,我们来介绍一下@use的命名空间是如何作用的。
1. 不使用as,则直接将文件名当作命名空间
在 SCSS 中,当在 @use
后面直接跟上文件路径,并且没有使用 as
关键字指定命名空间,表示将导入的模块内容整体作为一个命名空间,并且使用被导入文件的名称作为命名空间的标识。
假设有以下两个 SCSS 文件:
文件:_variables.scss
// _variables.scss $primary-color: #007bff; $secondary-color: #6c757d;
文件:styles.scss
// styles.scss @use 'variables.scss'; body { background-color: variables.$primary-color; } button { background-color: variables.$secondary-color; }
在这个示例中,styles.scss
使用 @use
直接导入了 variables.scss
文件,而没有使用 as
关键字指定命名空间。这意味着 _variables.scss
中的所有内容将被合并到 styles.scss
中,并且使用 variables
作为命名空间的标识。
注意,因为 @use
创建了命名空间,所以我们在 styles.scss
中需要使用 variables.$primary-color
和 variables.$secondary-color
来访问 _variables.scss
中定义的变量。
2. 使用as xxx,则以后面命名的变量xxx作为命名空间
还是用刚刚的例子,假设有以下两个 SCSS 文件:
文件:_variables.scss
// _variables.scss $primary-color: #007bff; $secondary-color: #6c757d;
文件:styles.scss
// styles.scss @use 'variables.scss' as customVars; body { background-color: customVars.$primary-color; } button { background-color: customVars.$secondary-color; }
在这个示例中,styles.scss
使用 @use
导入了 _variables.scss
文件,并使用 as customVars
为导入的模块创建了一个命名空间 customVars
。然后,我们使用 +
后面加上 customVars
来指定变量名作为命名空间的标识。
在 styles.scss
中,我们可以通过 customVars.$primary-color
和 customVars.$secondary-color
来访问 _variables.scss
中定义的变量。这样的用法可以避免变量冲突,并提供更清晰的命名空间标识,增加代码的可读性。
但是有一种特殊情况,就是通过 as * 来导入
如果在 @use
后面使用 as *
,表示将导入的模块的所有内容直接合并到当前文件中,并且不会创建一个命名空间。这样可以让导入的模块的所有变量、mixin、函数等直接在当前文件中使用,而不需要使用命名空间来访问它们。
让我们继续使用上面的示例:
文件:_variables.scss
// _variables.scss $primary-color: #007bff; $secondary-color: #6c757d;
文件:styles.scss
// styles.scss @use 'variables.scss' as *; body { background-color: $primary-color; } button { background-color: $secondary-color; }
在这个示例中,styles.scss
使用 @use
导入了 _variables.scss
文件,并使用 as *
表示导入模块的所有内容,而不为它们创建一个命名空间。
常见的函数使用,@mixin @include @extends @each 等使用
继承(@extends)
@extend 指令告诉 Sass 一个选择器的样式从另一选择器继承。如果一个样式与另外一个样式几乎相同,只有少量的区别,则使用 @extend 就显得很有用
.contanier1{
font-size: 24px;
font-weight: bold;
color: green;
}
.contanier2{
@extend .contanier1;
color: red;
}
.contanier3{
@extend .contanier1;
font-size: 30px;
}
---
.contanier1, .contanier3, .contanier2 {
font-size: 24px;
font-weight: bold;
color: green;
}
.contanier2 {
color: red;
}
.contanier3 {
font-size: 30px;
}
占位符 % placeholder
它可取代以前 CSS 中的基类造成的代码冗余的情形。 因为 %placeholder 声明的代码,如果不被 @extend 调用的话,不会产生任何代码。
%fz20{
font-size: 20px;
}
%red{
color: red;
}
.wrap{
@extend %fz20;
@extend %red;
}
.contanier1{
@extend %fz20;
.content{
@extend %red;
}
}
---
.wrap, .contanier1{
font-size: 20px;
}
.wrap, .contanier1 .content{
color: red;
}
如果仅是想提取部分公共的css出来,建议用%**
混入(@mixin)
语法: @mixin name { property: value; property: value; ... }
@mixin link {
line-height: 36px;
}
@mixin basis-text{
font-size: 24px;
font-weight: bold;
color: green;
@include link; // 混入中也可以包含混入
}
.contanier1{
@include basis-text;
}
---
.contanier1 {
font-size: 24px;
font-weight: bold;
color: green;
line-height: 36px;
}
向混入传递变量
@mixin basis-text($width: 2px,$color: red){
font-size: 20px;
color: green;
border: $width solid $color;
}
.contanier1{
@include basis-text;
}
.contanier2{
@include basis-text(5px,blue);
}
---
.contanier1 {
font-size: 20px;
color: green;
border: 2px solid red;
}
.contanier2 {
font-size: 20px;
color: green;
border: 5px solid blue;
}
可变参数
有时,不能确定一个混入(mixin)或者一个函数(function)使用多少个参数,这时就可使用 ... 来设置可变参数。 如:创建盒子阴影(box-shadow)的一个混入(mixin)可采取任何数量的 box-shadow 作为参数。
@mixin box-shadow($shadows...) {
-moz-box-shadow: $shadows;
-webkit-box-shadow: $shadows;
box-shadow: $shadows;
}
.shadows {
@include box-shadow(0px 4px 5px #666, 2px 6px 10px #999);
}
---
.shadows {
-moz-box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
-webkit-box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
}
控制指令
条件语句( @if )
当 @if 的表达式返回值不是 false 或者 null 时,条件成立,输出 {} 内的代码:
p {
@if 1 + 1 == 2 { border: 1px solid; }
@if 5 < 3 { border: 2px dotted; }
@if null { border: 3px double; }
}
---
p {
border: 1px solid;
}
搭配@else if 和@mixin
@mixin txt($weight) {
color: white;
@if $weight == bold {
font-weight: bold;
}
@else if $weight == light {
font-weight: 100;
}
@else {
font-weight: normal;
}
}
.txt1 {
@include txt(bold);
}
---
.txt1 {
color: white;
font-weight: bold;
}
循环语句
@for
@for 指令可在限制的范围内重复输出格式,每次按要求(变量的值)对输出结果做出变动。
包含两种格式:@for $var from <start> through <end>,或 @for $var from <start> to <end>;
区别: through 与 to 的含义:当使用 through 时,条件范围包含 <start> 与 <end> 的值,
而使用 to 时条件范围只包含 <start> 的值不包含 <end> 的值。
另外,$var 可以是任何变量,如 $i;<start> 和 <end> 必须是整数值。
@for $i from 1 through 3 {
.item-#{$i} { width: 2em * $i; }
}
---
.item-1 {
width: 2em;
}
.item-2 {
width: 4em;
}
.item-3 {
width: 6em;
}
@while
@while 指令重复输出格式直到表达式返回结果为 false。这样可以实现比 @for 更复杂的循环,只是很少会用到。
$i: 6;
@while $i > 0 {
.item-#{$i} { width: 2em * $i; }
$i: $i - 2;
}
---
.item-6 {
width: 12em;
}
.item-4 {
width: 8em;
}
.item-2 {
width: 4em;
}
@each
@each 指令的格式是 $var in <list>, $var 可以是任何变量名。如 $length 或 $name,而 <list> 是一连串的值,也就是值列表。
@each 将变量 $var 作用于值列表中的每一个项目,然后输出结果。
@each $animal in puma, sea-slug, egret, salamander {
.#{$animal}-icon {
background-image: url('/images/#{$animal}.png');
}
}
---
.puma-icon {
background-image: url('/images/puma.png');
}
.sea-slug-icon {
background-image: url('/images/sea-slug.png');
}
.egret-icon {
background-image: url('/images/egret.png');
}
.salamander-icon {
background-image: url('/images/salamander.png');
}
// 嵌套
$colors: (
primary: red,
success: green,
);
@each $name,$color in $colors {
.text-#{$name} {
color: $color;
}
}
---
.text-primary {
color: red;
}
.text-success {
color: green;
}