004-继承与占位符

Sass 继承机制详解

@extend 继承规则

@extend 是 Sass 中强大的功能,允许一个选择器继承另一个选择器的样式。

基本用法

1
2
3
4
5
6
7
8
9
.error {
border: 1px solid #f00;
background-color: #fee;
}

.serious-error {
@extend .error;
border-width: 3px;
}

编译结果为:

1
2
3
4
5
6
7
8
.error, .serious-error {
border: 1px solid #f00;
background-color: #fee;
}

.serious-error {
border-width: 3px;
}

继承嵌套选择器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.button {
padding: 10px 15px;

&.disabled {
opacity: 0.5;
}
}

.submit-button {
@extend .button;

&.disabled {
cursor: not-allowed;
}
}

多重继承

1
2
3
4
5
6
7
8
9
10
11
12
13
.alert {
padding: 15px;
}

.warning {
color: #8a6d3b;
background-color: #fcf8e3;
}

.alert-warning {
@extend .alert;
@extend .warning;
}

%placeholder 占位符选择器

占位符选择器以 % 开头,只用于被继承,不会被编译到最终 CSS 中。

基本用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
%button-base {
padding: 10px 15px;
border-radius: 4px;
display: inline-block;
}

.primary-button {
@extend %button-base;
background-color: blue;
color: white;
}

.secondary-button {
@extend %button-base;
background-color: gray;
color: black;
}

编译结果为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.primary-button, .secondary-button {
padding: 10px 15px;
border-radius: 4px;
display: inline-block;
}

.primary-button {
background-color: blue;
color: white;
}

.secondary-button {
background-color: gray;
color: black;
}

占位符的优势

  1. 不会生成多余的 CSS 代码
  2. 提供清晰的抽象层
  3. 使代码结构更清晰

继承与混合的适用场景对比

适用继承(@extend)的场景:

  1. 共享基础样式:当多个选择器需要共享完全相同的样式时

    1
    2
    3
    4
    5
    6
    7
    8
    %form-control {
    padding: 8px;
    border: 1px solid #ddd;
    }

    .text-input, .select-input, .textarea-input {
    @extend %form-control;
    }
  2. 语义化关系:当选择器之间有明显的”是一种”关系时

    1
    2
    3
    4
    5
    6
    7
    8
    .animal {
    color: black;
    }

    .cat {
    @extend .animal;
    sound: "meow";
    }
  3. 减少重复代码:当需要减少生成的 CSS 体积时

适用混合(@mixin)的场景:

  1. 需要参数化样式:当样式需要根据不同参数变化时

    1
    2
    3
    4
    5
    6
    7
    @mixin box-shadow($x, $y, $blur, $color) {
    box-shadow: $x $y $blur $color;
    }

    .card {
    @include box-shadow(0, 2px, 4px, rgba(0,0,0,0.1));
    }
  2. 生成动态样式:当需要基于计算生成样式时

    1
    2
    3
    @mixin responsive-font($min-size, $max-size) {
    font-size: clamp(#{$min-size}, 2vw, #{$max-size});
    }
  3. 需要厂商前缀:当需要生成带前缀的样式时

    1
    2
    3
    4
    5
    @mixin transform($property) {
    -webkit-transform: $property;
    -ms-transform: $property;
    transform: $property;
    }

对比总结

特性 @extend @mixin
编译结果 合并选择器 复制样式到每个调用处
参数支持 不支持 支持
代码输出 更紧凑 可能更冗长
适用场景 静态样式共享 动态样式生成
选择器关系 建立选择器之间的关系 不建立选择器关系
性能考虑 可能生成复杂的选择器组 可能导致代码重复

最佳实践建议

  1. 优先使用占位符:当不需要单独使用基础样式时,使用 %placeholder 而不是普通类名
  2. 混合用于动态样式:当样式需要参数化或计算时使用 @mixin
  3. 避免过度继承:深度继承链会使 CSS 难以维护
  4. 注意选择器顺序@extend 受 CSS 层叠规则影响
  5. 考虑输出大小:对于大量重复的静态样式,@extend 通常能生成更小的 CSS