提醒:建议继承那些干净的无后代写法的样式css
咱们常常会遇到这样的状况,当咱们在开发页面时候一个class须要包含前一个class的全部样式,可是又必须有他本身特殊新增的样式。可是这两个class其实都是相差无几的,只是有细微的差异。好比错误提示的样式(.error和.specialerror),既而后着只是比前者多一两句样式,为什么还要写两个class呢,由于咱们不想把前者.error的样式从新在写一遍,无聊极了。可是这样带来一个问题,就是html标签上会多出好几个class。html
为了解决这个问题,sass里提供了@extend的解决方法
先看一个例子:sass
<div class="error specialerror"> Oh no! You've been hacked! </div>
咱们的css以下url
.error { border: 1px #f00; background-color: #fdd; } .specialerror { border-width: 3px; }
这里就出现咱们刚说的问题了,其实咱们内心是十万个不肯意就这么在后面唐突的加个specialerror的,由于若是只写specialerror,就丢失了前面的样式(为何呢,由于咱们没有在specialerror里复写error的样式,只是新增了)code
经过Sass的@extend,一个选择器将继承另外一个选择器的样式
例如:htm
.error { border: 1px #f00; background-color: #fdd; } .specialerror { @extend .error; border-width: 3px; }
被编译为:继承
.error, .specialerror { border: 1px #f00; background-color: #fdd; } .specialerror { border-width: 3px; }
意味着.error全部的样式都会加到.specialerror上,这样.specialerror就会有.error的样式了。这样咱们就能够只写.specialerror了。目前就先这样理解,其实这个@extend实现的方式是跟咱们现实逻辑颠倒的。ip
可是若是改为这样:ci
.error { border: 1px #f00; background-color: #fdd; } .specialerror { @extend .error; border-width: 3px; } .error.intrusion { background-image: url("/image/hacked.png"); }
加上面这段样式后<div class="specialerror intrusion"> 就会加上和<div class="error intrusion">同样的背景开发
怎么作到的呢
.error { border: 1px #f00; background-color: #fdd; } .error.intrusion { background-image: url("/image/hacked.png"); } .specialerror { @extend .error; border-width: 3px; }
被编译为:
.error, .specialerror { border: 1px #f00; background-color: #fdd; } .error.intrusion, .specialerror.intrusion { background-image: url("/image/hacked.png"); } .specialerror { border-width: 3px; }
这里须要重点讲解下,其实咱们正常理解增长扩充添加就是copy而后paste,是的,这样思考其实也是对的,就像文章一开始那个最简单的例子。可是为了不没必要要的重复。@extend的逻辑稍稍不一样。你能够这样认为,使用@extend时候sass会将.error相关样式先拷贝一份,
.specialerror { @extend .error; border-width: 3px; }
而后把字符“specialerror”存储在@extend里,遇到”error“字符就进行替换,这样.specialerror就有了.error的样式啦!这也就能解释,为何会出现下面.specialerror.intrusion的缘由了。
.error.intrusion, .specialerror.intrusion { background-image: url("/image/hacked.png"); }
当组合选择器的样式时, @extend 可以很聪明得避免没必要要的重复,例如.seriousError.seriousError会被转换成.seriousError。不会生成相似#main#footer的不可用选择器。
求证例子:
.hoverlink { @extend a:hover; } a:hover { text-decoration: underline; }
被编译为:
a:hover, .hoverlink { text-decoration: underline; }
就像上面的.error.intrusion ,任何使用 a:hover 都会替换为 .hoverlink,即便中间包含其余选择器。例如:
.hoverlink { @extend a:hover; } .comment a.user:hover { font-weight: bold; }
被编译为:
.comment a.user:hover, .comment .user.hoverlink { font-weight: bold; }
Multiple Extends
一个选择器还能够扩充多个选择器的样式例如:
.error { border: 1px #f00; background-color: #fdd; } .attention { font-size: 3em; background-color: #ff0; } .seriousError { @extend .error; @extend .attention; border-width: 3px; }
被编译为:
.error, .seriousError { border: 1px #f00; background-color: #fdd; } .attention, .seriousError { font-size: 3em; background-color: #ff0; } .seriousError { border-width: 3px; }
对于下面这种只需注意下就行,就是.criticalError内 “@extend .seriousError”这句话。在运行这句语句时候,sass会检测到.seriousError内有“@extend .error”。
因此.criticalError既有.error的样式也有.seriousError的样式,故criticalError须要替换的是error和seriousError。
.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%; }
被编译为:
.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%; }
选择器序列
例如.foo .bar或者 .foo + .bar, 目前还不能被扩展. 可是对于嵌套的选择器仍是可使用@extend添加到其余选择器的 例如:
#fake-links .link { @extend a; } a { color: blue; &:hover { text-decoration: underline; } }
编译为:
a, #fake-links .link { color: blue; } a:hover, #fake-links .link:hover { text-decoration: underline; }
当两个没有共同点的序列扩充组合时候, 将会产生两个不一样的选择器: 一种是第一个序列在前,另外一种是第二个序列在前例如: #admin .tabbar会和#demo .overview调换位置。
#admin .tabbar a { font-weight: bold; } #demo .overview .fakelink { @extend a; }
被编译为:
#admin .tabbar a, #admin .tabbar #demo .overview .fakelink, #demo .overview #admin .tabbar .fakelink { font-weight: bold; }
若是另个序列有一些共同的选择器,这些选择器将会被组合在一块儿并且只有不一样的将会保留下来。下面这个例子中, 每一个写都包含id #admin, 因此产生的选择器就会合并这两个#admin。#admin .tabbar和 #admin .overview会调换位置,换完以后在省略重复的。
#admin .tabbar a { font-weight: bold; } #admin .overview .fakelink { @extend a; }
这被编译为:
#admin .tabbar a, #admin .tabbar .overview .fakelink, #admin .overview .tabbar .fakelink { font-weight: bold; }