现在的位置: 首页 > 综合 > 正文

sass之extend

2019年07月26日 ⁄ 综合 ⁄ 共 3803字 ⁄ 字号 评论关闭

首先我们从一段代码开始入手。如下代码所示,先通过下文的介绍再回头分析这段代码。

$cicc-red: red;
@mixin setRadius($radius) {
  -webkit-border-radius: $radius;
     -moz-border-radius: $radius;
          border-radius: $radius;
}
%btn-display {
        display: block;
        color: #ffffff;
        font-size: 20px;
        padding: 5px 20px;
        margin-bottom: 10px;
        &:hover {
          text-decoration: none;
        }
      }
.buy-btn {
        background: $cicc-red;
        @include setRadius(5px);
        @extend %btn-display;
      }

@extend拓展


@extend的作用可以让开发者不用通过添加类名给某个节点增加特殊样式。例如:
html代码
<div class="error seriousError">
  Oh no! You've been hacked!
</div>

css代码

.error
{
  border: 1px #f00;
  background-color: #fdd;
}
.seriousError {
  border-width: 3px;
}

这样的结构和样式的耦合性比较强,需要另外添加seriousError的类名。可以使用sass解决这个问题,如下:

.error {
  border: 1px #f00;
  background-color: #fdd;
}
.seriousError {
  @extend .error;
  border-width: 3px;
}

编译后的css代码为

.error, .seriousError {
  border: 1px #f00;
  background-color: #fdd;
}

.seriousError {
  border-width: 3px;
}

工作原理

@extend会将被扩展的类名下所嵌套的样式都给包含进来,如下:
sass代码:
.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?1410339978);
}

.seriousError {
  border-width: 3px;
}

合并选择器时,@extend会避免无谓的重复,.seriousError.seriousError将编译为.seriousError,不会产生多余的选择器,不能匹配多个元素的选择器(比如#main#footer)。

扩展复杂的选择器

class类名不是唯一可以被扩展的,还可以扩展单个元素,比如a:hover,例如:同class元素一样,a:hover的样式将继承给.hoverlink。
    sass代码:
.hoverlink {
  @extend a:hover;
}
a:hover {
  text-decoration: underline;
}	
	

编译后的css代码为:

a:hover, .hoverlink {
  text-decoration: underline; }	

    

多重延伸


    一个选择器可以同时延伸给多个选择器,它所包含的属性将继承给所有被延伸的选择器:
sass代码
.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; }

链式继承


一个选择器被延伸给第二个后,可以继续将第二个选择器延伸给第三个。
sass代码
.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%;
}

编译后的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%; }	

选择器序列

类似.foo.bar或者.foo+.bar这样的选择器序列不能被单个选择器继承。但是,却可以将选择器延伸给选择器列。
sass代码
#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;
}

合并选择器列


当两个列合并时,如果没有包含相同的选择器,将生产两个新选择器。例子如下:
sass代码
.meng a {
	font-weight:bold;
}

.long .link {
	@extend a;
}

编译后的css代码为:

.meng a, .meng .long .link, .long .meng .link {
  font-weight: bold;
}


从上面的例子不难看出,类名".meng"中的"a"选择器被类名".long"中的类名".link"继承了,但是由于没有在同一个父级下,会生产交叉合并的编译结果。解决这个问题比较简单,可将父级元素修改成一样,或者将.meng a修改成一个类名。


extend-only选择器


有时,需要定义一套样式并不是给某个元素用,而是通过@extend指令使用。如果使用普通的css规则,最后会编译出很多用不到的样式,也容易与其他样式冲突,所以,sass引入了”占位符选择器",看起来像普通的id或class选择器,只是"#"或"."被替换成了%。可以像class或者id选择器那样使用,当它们单独使用时,不会被编译到css文件中。

#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; }

在指令中延伸


  在指令(比如在@media中),使用@extend时有一些限制:sass不可以将指令层外的css规则延申给指令层内的css。也就是说,如果在指令中使用@extend,必须延伸给相同指令层中的选择器。下例是个错误的代码:
sass代码
.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;
  }
}

编译的css代码为:

.error, .seriousError {
  border: 1px #f00;
  background-color: #fdd;
}

@media print {
  .seriousError {
    border-width: 3px;
  }
}

以下的代码才是正确的


@media print {
  .error {
    border: 1px #f00;
    background-color: #fdd;
  }
  .seriousError {
    @extend .error;
    border-width: 3px;
  }
}

编译后的css代码为

@media print {
  .error, .seriousError {
    border: 1px #f00;
    background-color: #fdd;
  }

  .seriousError {
    border-width: 3px;
  }
}

【上篇】
【下篇】

抱歉!评论已关闭.