赞
踩
原文网址:Scss--@extend--使用/实例_IT利刃出鞘的博客-CSDN博客
本文介绍Scss的@extend的用法。
在设计网页的时候常常遇到这种情况:一个元素使用的样式与另一个元素完全相同,但又添加了额外的样式。通常会在 HTML 中给元素定义两个 class,一个通用样式,一个特殊样式。假设现在要设计一个普通错误样式与一个严重错误样式,一般会这样写:
- <div class="error seriousError">
- Oh no! You've been hacked!
- </div>
样式如下
- .error {
- border: 1px #f00;
- background-color: #fdd;
- }
- .seriousError {
- border-width: 3px;
- }
麻烦的是,这样做必须时刻记住使用 .seriousError 时需要参考 .error 的样式,带来了很多不变:智能比如加重维护负担,导致 bug,或者给 HTML 添加无语意的样式。使用 @extend 可以避免上述情况,告诉 Sass 将一个选择器下的所有样式继承给另一个选择器。
- .error {
- border: 1px #f00;
- background-color: #fdd;
- }
- .seriousError {
- @extend .error;
- border-width: 3px;
- }
上面代码的意思是将 .error 下的所有样式继承给 .seriousError,border-width: 3px; 是单独给 .seriousError 设定特殊样式,这样,使用 .seriousError 的地方可以不再使用 .error。
其他使用到 .error 的样式也会同样继承给 .seriousError,例如,另一个样式 .error.intrusion 使用了 hacked.png 做背景,<div class="seriousError intrusion"> 也同样会使用 hacked.png 背景。
- .error.intrusion {
- background-image: url("/image/hacked.png");
- }
@extend 的作用是将重复使用的样式 (.error) 延伸 (extend) 给需要包含这个样式的特殊样式(.seriousError),刚刚的例子:
Scss:
- .error {
- border: 1px #f00;
- background-color: #fdd;
- }
- .error.intrusion {
- background-image: url("/image/hacked.png");
- }
- .seriousError {
- @extend .error;
- border-width: 3px;
- }
编译后的CSS:
- .error, .seriousError {
- border: 1px #f00;
- background-color: #fdd;
- }
-
- .error.intrusion, .intrusion.seriousError {
- background-image: url("/image/hacked.png");
- }
-
- .seriousError {
- border-width: 3px;
- }
合并选择器时,@extend 会很聪明地避免无谓的重复,.seriousError.seriousError 将编译为 .seriousError,不能匹配任何元素的选择器(比如 #main#footer )也会删除。
Class 选择器并不是唯一可以被延伸 (extend) 的,Sass 允许延伸任何定义给单个元素的选择器,比如 .special.cool,a:hover 或者 a.user[href^="http://"] 等。
Scss
- a:hover {
- text-decoration: underline;
- }
-
- .hoverlink {
- @extend a:hover;
- }
编译为
- a:hover, .hoverlink {
- text-decoration: underline;
- }
与上面 .error.intrusion 的例子一样,所有 a:hover 的样式将继承给 .hoverlink,包括其他使用到 a:hover 的样式。
Scss
- .comment a.user:hover {
- font-weight: bold;
- }
-
- .hoverlink {
- @extend a:hover;
- }
编译为
- .comment a.user:hover, .comment .user.hoverlink {
- font-weight: bold;
- }
说明
同一个选择器可以延伸给多个选择器,它所包含的属性将继承给所有被延伸的选择器。
示例
Scss
- .error {
- border: 1px #f00;
- background-color: #fdd;
- }
- .attention {
- font-size: 3em;
- background-color: #ff0;
- }
- .seriousError {
- @extend .error;
- @extend .attention;
- border-width: 3px;
- }
编译后的CSS:
- .error, .seriousError {
- border: 1px #f00;
- background-color: #fdd;
- }
-
- .attention, .seriousError {
- font-size: 3em;
- background-color: #ff0;
- }
-
- .seriousError {
- border-width: 3px;
- }
每个 .seriousError 将包含 .error 与 .attention 下的所有样式,这时,后定义的样式享有优先权:.seriousError 的背景颜色是 #ff0 而不是 #fdd,因为 .attention 在 .error 之后定义。
多重延伸可以使用逗号分隔选择器名,比如 @extend .error, .attention; 与 @extend .error; @extend.attention 有相同的效果。
说明
当一个选择器继承给第二个后,可以继续将第二个选择器继承给第三个。
示例
SCSS
- .error {
- border: 1px #f00;
- background-color: #fdd;
- }
- .seriousError {
- @extend .error;
- border-width: 3px;
- }
- .criticalError {
- @extend .seriousError;
- position: fixed;
- top: 10%;
- bottom: 10%;
- left: 10%;
- right: 10%;
- }

现在,每个 .seriousError 选择器将包含 .error 的样式,而 .criticalError 不仅包含 .seriousError 的样式也会同时包含 .error 的所有样式
编译后的CSS:
- .error, .seriousError, .criticalError {
- border: 1px #f00;
- background-color: #fdd;
- }
-
- .seriousError, .criticalError {
- border-width: 3px;
- }
-
- .criticalError {
- position: fixed;
- top: 10%;
- bottom: 10%;
- left: 10%;
- right: 10%;
- }

说明
暂时不可以将选择器列 (Selector Sequences),比如 .foo .bar 或 .foo + .bar,延伸给其他元素,但是,却可以将其他元素延伸给选择器列。
示例
Scss
- #fake-links .link {
- @extend a;
- }
-
- a {
- color: blue;
- &:hover {
- text-decoration: underline;
- }
- }
编译后的CSS:
- a, #fake-links .link {
- color: blue;
- }
-
- a:hover, #fake-links .link:hover {
- text-decoration: underline;
- }
需要合并的场景
有时会遇到复杂的情况,比如选择器列中的某个元素需要延伸给另一个选择器列,这种情况下,两个选择器列需要合并,比如:
- #admin .tabbar a {
- font-weight: bold;
- }
- #demo .overview .fakelink {
- @extend a;
- }
技术上讲能够生成所有匹配条件的结果,但是这样生成的样式表太复杂了,上面这个简单的例子就可能有 10 种结果。所以,Sass 只会编译输出有用的选择器。
示例1:不包含相同的选择器
当两个列 (sequence) 合并时,如果没有包含相同的选择器,将生成两个新选择器:第一列出现在第二列之前,或者第二列出现在第一列之前。
Scss
- #admin .tabbar a {
- font-weight: bold;
- }
- #demo .overview .fakelink {
- @extend a;
- }
编译后的CSS:
- #admin .tabbar a,
- #admin .tabbar #demo .overview .fakelink,
- #demo .overview #admin .tabbar .fakelink {
- font-weight: bold;
- }
示例2:包含相同的选择器
如果两个列 (sequence) 包含了相同的选择器,相同部分将会合并在一起,其他部分交替输出。在下面的例子里,两个列都包含 #admin,输出结果中它们合并在了一起。
SCSS:
- #admin .tabbar a {
- font-weight: bold;
- }
- #admin .overview .fakelink {
- @extend a;
- }
编译后的CSS:
- #admin .tabbar a,
- #admin .tabbar .overview .fakelink,
- #admin .overview .tabbar .fakelink {
- font-weight: bold;
- }
说明
有时,需要定义一套样式并不是给某个元素用,而是只通过 @extend 指令使用,尤其是在制作 Sass 样式库的时候,希望 Sass 能够忽略用不到的样式。
如果使用普通的 CSS 规则,最后会编译出很多用不到的样式,也容易与其他样式名冲突,所以,Sass 引入了“占位符选择器” (placeholder selectors),看起来很像普通的 id 或 class 选择器,只是 # 或 . 被替换成了 %。可以像 class 或者 id 选择器那样使用,当它们单独使用时,不会被编译到 CSS 文件中。
占位符选择器需要通过延伸指令使用,用法与 class 或者 id 选择器一样,被延伸后,占位符选择器本身不会被编译。
示例
SCSS:
- // This ruleset won't be rendered on its own.
- #context a%extreme {
- color: blue;
- font-weight: bold;
- font-size: 2em;
- }
- .notice {
- @extend %extreme;
- }
编译后的CSS:
- #context a.notice {
- color: blue;
- font-weight: bold;
- font-size: 2em;
- }
如果 @extend 失败会收到错误提示。比如: a.important {@extend .notice},当没有 .notice 选择器时将会报错,只有 h1.notice 包含 .notice 时也会报错,因为 h1 与 a 冲突,会生成新的选择器。
如果要求 @extend 不生成新选择器,可以通过 !optional 声明达到这个目的,例如:
- a.important {
- @extend .notice !optional;
- }
在指令中使用 @extend 时(比如在 @media 中)有一些限制:Sass 不可以将 @media 层外的 CSS 规则继承给指令层内的 CSS,这样会生成大量的无用代码。也就是说,如果在 @media (或者其他 CSS 指令)中使用 @extend,必须继承给相同指令层中的选择器。
正确用法
- @media print {
- .error {
- border: 1px #f00;
- background-color: #fdd;
- }
- .seriousError {
- @extend .error;
- border-width: 3px;
- }
- }
错误用法
- .error {
- border: 1px #f00;
- background-color: #fdd;
- }
-
- @media print {
- .seriousError {
- // INVALID EXTEND: .error is used outside of the "@media print" directive
- @extend .error;
- border-width: 3px;
- }
- }
希望有一天,浏览器可以原生支持 @extend 指令,这样就可以在任何指令中使用延伸功能,不再受限制了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。