# Sass速通(四):继承、混合与函数

2021-10-13 17:49:14 浏览数 (1)

在 Sass 中,我们可以使用继承、混合和函数来复用一些 CSS 样式和功能。

继承

@extend

继承使用 @extend 指令实现,如

代码语言:javascript复制
.error {
    border: 1px solid red;
    background-color: #fdd;
}
.seriousError {
    @extend .error;
    border-width: 3px;
}

编译后

代码语言:javascript复制
.error, .seriousError {
  border: 1px solid red;
  background-color: #fdd;
}
.seriousError {
  border-width: 3px;
}

实际上,Sass 是将使用 @extend 的 .seriousError 和 .error 编译为了组合选择器 .error, .seriousError。以往我们在 CSS 中复用一段样式时,也会使用 组合选择器 这种形式。

在了解了继承的编译原理之后,我们来看几种复杂情况。

多重继承 (Multiple Extends)

一个选择器可以继承多个选择器。

代码语言:javascript复制
.error {
    border: 1px #f00;
    background-color: #fdd;
}
.attention {
    font-size: 3em;
    background-color: #ff0;
}
.seriousError {
    @extend .error;
    @extend .attention;
    border-width: 3px;
}

编译后

代码语言:javascript复制
.error, .seriousError {
  border: 1px #f00;
  background-color: #fdd;
}
.attention, .seriousError {
  font-size: 3em;
  background-color: #ff0;
}
.seriousError {
  border-width: 3px;
}

多重继承,会被编译为多个组合选择器。

继承嵌套的选择器列(Selector Sequences)
代码语言:javascript复制
.inner {
    p {
        font-size: 14px;
    }
    &:hover {
        color: red;
    }
}
.spec-inner {
    @extend .inner;
}

编译后

代码语言:javascript复制
.inner p, .spec-inner p {
  font-size: 14px;
}
.inner:hover, .spec-inner:hover {
  color: red;
}

显然,.spec-inner 在继承 .inner 的时候,也继承了 .inner 的嵌套结构。

继承链 (Chaining Extends)

当出现选择器 C 继承 B,B 继承 A 的情况时,会从 继承链末端 C 开始向上与 B 组合,之后 C、B 再和 A 组合。

代码语言:javascript复制
.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%;
}

编译后

代码语言:javascript复制
.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%;
}

@extend-only

由于 @extend 可以复用 CSS 的特性,有时我们可能会专门写一些样式给其它选择器继承,而不是为了给具体的元素使用。这时可以使用 占位符选择器,这些选择器不会被编译到 CSS 中。 我们可以使用 % 来标识一个占位符,如

代码语言:javascript复制
#context a%extreme {
    color: blue;
    font-weight: bold;
    font-size: 2em;
}
.notice {
    @extend %extreme;
}

编译后

代码语言:javascript复制
#context a.notice {
  color: blue;
  font-weight: bold;
  font-size: 2em;
}

可以看到,选择器 #context a 并没有被编译输出。

!optional

当我们不确定继承的选择器是否存在时,可以使用 !optional 标识,如

代码语言:javascript复制
a.important {
    @extend .notice !optional;
}

此时可以成功编译,但由于 .notice 不存在,所以没有任何输出。 如果不加 !optional,编译时会报错:

代码语言:javascript复制
"a.important" failed to @extend ".notice"
The selector ".notice" was not found.
Use "@extend .notice !optional" if the extend should be able to fail.

混合

@mixin、@include

在 Sass 中,可以使用 @mixin 封装一段 CSS 代码,之后通过 @include 引入。

代码语言:javascript复制
@mixin large-text { // 定义
    font: {
        family: Arial;
        size: 20px;
        weight: bold;
    }
    color: #ff0000;
}
.page-title {
    @include large-text; // 引入
    padding: 4px;
    margin-top: 10px;
}

编译后

代码语言:javascript复制
.page-title {
  font-family: Arial;
  font-size: 20px;
  font-weight: bold;
  color: #ff0000;
  padding: 4px;
  margin-top: 10px;
}

参数

我们可以定义接收参数的 mixin,并为参数设置默认值,如

代码语言:javascript复制
@mixin sexy-border($color, $width: 1px) {
    border: {
        color: $color;
        width: $width;
        style: dashed;
    }
}

在引入 mixin 时,可以按顺序传参,也可以指定传入值给哪个参数,如

代码语言:javascript复制
h1 {
    @include sexy-border(blue, 1px); 
}
p {
    @include sexy-border($width: 1px, $color: red);
}

编译后

代码语言:javascript复制
h1 {
  border-color: blue;
  border-width: 1px;
  border-style: dashed;
}
p {
  border-color: red;
  border-width: 1px;
  border-style: dashed;
}

@content

在使用 mixin 时,我们可以先向 mixin 中导入一段代码,然后再输出混合样式,导入的代码将出现在 @content 标识的位置,这和一些语言和框架中“插槽(slot)”的用法相似。

代码语言:javascript复制
@mixin apply-to-ie6-only {
    * html {
        @content;
    }
}
@include apply-to-ie6-only {
    #logo {
        background-image: url(/logo.gif);
    }
}

编译后

代码语言:javascript复制
* html #logo {
  background-image: url(/logo.gif);
}

编译后,选择器 #logo 及其样式替换了 @content 并插入到了相应的位置。

函数

@function

在 Sass 中,可以使用 @function 定义一个函数,如

代码语言:javascript复制
@function grid-width($grid-width, $gutter-width, $n: 5) {
    @return $n * $grid-width   ($n - 1) * $gutter-width;
}

与 mixin 相似,function 可以接收多个参数,并为参数设置默认值。 在调用时,也可以为指定参数赋值,如

代码语言:javascript复制
#sidebar {
    width: grid-width($gutter-width: 10px, $grid-width: 40px)
}

编译后

代码语言:javascript复制
#sidebar {
    width: 240px;
}

mixin 适用于封装一段 CSS 代码,而 function 则更适用于封装一段逻辑或计算过程。

0 人点赞