理解 Sass 的选择占位符 %placeholder
Sass 中提供多种方法来共用相同的 CSS 代码。你可以使用 @include
定义好的 @mixin 在你的CSS样式中插入新的CSS样式,你也可以使用@extend
定义好的CSS类选择器,向你的CSS样式中插入新的 CSS 样式。在 Sass 3.2 中引入了一个新的特性——选择器占位符 %placeholder,能过 @extend
可以得到更有效的输出。
在开始介绍 %placeholder
之前,我们先来了解一下 Sass 中 @extend
是如何工作的。
@extend 如何工作
使用 @extend
我们可以使用CSS中的定义好的选择器,下面的例子可以很好的说明一切:
.icon {
transition: background-color ease .2s;
margin: 0 .5em;
}
.error-icon {
@extend .icon;
/*错误图标指定的样式... */
}
.info-icon {
@extend .icon;
/* 信息图标指定的样式... */
}
上面的SCSS代码将编译的CSS代码如下:
.icon, .error-icon, .info-icon {
transition: background-color ease .2s;
margin: 0 .5em;
}
.error-icon {
/*错误图标指定的样式... */
}
.info-icon {
/* 信息图标指定的样式... */
}
这是怎么回事?通过 @extend
可以直接在.error-icon
和.info-icon
中插入定义好的.icon
属性。只要你修改了.icon
样式,.error-icon
和.info-icon
也会做出对应的变化。非常完美,对不对?
很有兴的一个地方。如果我们在HTML中从来不使用.icon
,其存在的唯一目的就是为了扩展吗?这似乎比我们需要的基本样式稍大些,因为我们将永远不会使用.icon
对应的样式。其实在Sass3.2开始,我们可以通过使用选择器占位符%placeholder
来解决这种现象。
使用选择器占位符 %placeholder
选择器占位符%placeholder
可以很好的解决上面提到的问题。选择器占位符很类似于CSS的类,不同的是他不是使用(.)
开始,而是使用(%)
开始,而且编译出来的CSS代码中并不会包括%placeholder
规则中的样式,除非是通过@extend
对其进行调用。
回到当初的示例,如果我们定义的图标样式如下:
%icon {
transition: background-color ease .2s;
margin: 0 .5em;
}
.error-icon {
@extend %icon;
/*错误图标指定的样式... */
}
.info-icon {
@extend %icon;
/* 信息图标指定的样式... */
}
编译出的CSS:
.error-icon, .info-icon {
transition: background-color ease .2s;
margin: 0 .5em;
}
.error-icon {
/*错误图标指定的样式... */
}
.info-icon {
/* 信息图标指定的样式... */
}
请注意,编译出来的CSS代码中将不再包括.icon
了。
@extend VS @include
乍一看,选择器占位符%placeholder
看起来和具有相同参数的@mixin
一样。虽然从功能上来说(在浏览器上渲染的效果是完全相同的)他们是相同,但编译出来的CSS却大大的不同。
请考虑使用@mixin .icon
来实现上面示例的效果:
@mixin icon {
transition: background-color ease .2s;
margin: 0 .5em;
}
.error-icon {
@include icon;
/*错误图标指定的样式... */
}
.info-icon {
@include icon;
/* 信息图标指定的样式... */
}
编译出来的CSS:
.error-icon {
transition: background-color ease .2s;
margin: 0 .5em;
/*错误图标指定的样式... */
}
.info-icon {
transition: background-color ease .2s;
margin: 0 .5em;
/* 信息图标指定的样式... */
}
仅从维护的角度来说,这是一个很好的扩展的示例,但编译出来的CSS实在是糟糕,因为编译出来的CSS样式,没有把相同的样式合并在一起。
选择器占位符的限制
使用@extend
调用定义好的选择器占位符%placeholder
有所限制,他不能在不同的@media
中运行。
如下面的示例:
%icon {
transition: background-color ease .2s;
margin: 0 .5em;
}
@media screen {
.error-icon {
@extend %icon;
}
.info-icon {
@extend %icon;
}
}
此时编译你的SCSS文件时,编译器将会报错:
>>> Sass is watching for changes. Press Ctrl-C to stop.
error test.scss (Line 3: You may not @extend an outer selector from within @media.
You may only @extend selectors within the same directive.
From "@extend %icon" on line 10 of test.scss.
)
当我第一次碰到这个限制时,我以为这是一个错误。然而有一个很好的理由,Sass为什么要这样工作。
因为@extend
是将一个选择器样式扩展到另一个选择器当中,而实际上在不同的@media
中却无需复制这些样式。
虽然他可以通过其他的方式来工作,在@media
块中定义选择器占位符,在@extend
调用时,将会将整个样式包含在@media
区块中:
@media screen {
%icon {
transition: background-color ease .2s;
margin: 0 .5em;
}
}
.error-icon {
@extend %icon;
}
.info-icon {
@extend %icon;
}
编译出的CSS:
@media screen {
.error-icon, .info-icon {
transition: background-color ease .2s;
margin: 0 .5em;
}
}
总结
@extend
和 @include
都具有强大的功能,尽管细节上有一些差别,这就要问你自己,编译出来的 CSS 样式,接近重用的样式对你是不是很重要。在某些情况下,@extend
可以大大的减化你的 CSS 输出,并且显著的提高你的 CSS 性能。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论