SASS @extend官方文档剖析

@extend用法剖析

提醒:建议继承那些干净的无后代写法的样式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; }
相关文章
相关标签/搜索