Skip to content
大纲

样式复用

@extend

Sass 提供 @extend <selector> 用于继承指定选择器的全部样式,同时会继承其组合选择器的样式

  • @extend 允许继承任意合法的选择器,通常用于继承 class 选择器
  • @extend 允许在同一个选择器中被多次调用
    • 后定义的样式享有优先权(按照被继承样式定义顺序而非继承时的调用顺序)
    • 可以使用逗号分隔选择器进行简写,如 @extend .a, .b
  • @extend 允许连续继承
  • @extend 不支持选择器列,如 .foo .bar.foo + .bar
  • @extend 继承一个选择器列中的某个元素
    • 应当避免这种情况的使用
    • 如果未包含相同的选择器则生成两个新的选择器
      • 第一列出现在第二列之前
      • 第二列出现在第一列之前
    • 如果两个列包含相同的选择器,相同部分将合并,其他部分交替输出
  • 占位符选择器
    • 格式: %selector ,类似于 idclass 选择器,但自身不会被编译到 css 中
    • 使用: 通过 @extend 使用
  • !optional 声明
    • @extend 继承一个不存在的选择器时,编译将报错
    • 使用该声明将忽略错误处理
    • 示例: @extend .inexistent !optional
  • 一些限制: 不允许将 @media 层外的 css 规则在 @media 层内使用

示例

sass
%normal
    width: 200px
    height: 200px
%large
    width: 300px
    height: 300px
.card
    @extend %normal
    &:hover
        border: 1px solid grey
    > .img
        cursor: pointer
.card-large
    @extend .card, %large

编译为

css
.card,
.card-large {
  width: 200px;
  height: 200px;
}

.card-large {
  width: 300px;
  height: 300px;
}

.card:hover,
.card-large:hover {
  border: 1px solid grey;
}

.card > .img,
.card-large > .img {
  cursor: pointer;
}

@mixin@include

该指令为混合指令,用于定义可重复使用的样式,用于避免无语义的 class

  • 定义与引用
    • @mixin 用于定义一组混合样式
      • 无参数定义: @mixin mixinName
      • 含参数定义: @mixin mixinName($attr1: <default>, $attr2, ...),可以指定默认值
    • @include 用于引用一组混合样式
      • 无参数引用: @include mixinName
      • 传参数引用
        • 按顺序传参: @include mixinName($val1, $val2, ...)
        • 按关键字传参: @include mixinName($attr: $val, $att2: $val2),可打乱顺序
  • 导入内容
    • @mixin 中可以使用 @content 标志需要导入样式的地方(类似于 vue 中 slot 标签)
    • @include 中可以使用换行(scss 则使用花括号)添加导入的内容
  • 使用注意
    • @mixin
      • 混合样式中允许使用 &引用父选择器,但应当只定义后代选择器
      • @mixin 定义混合样式中可以 @include 其他混合样式
    • @include
      • 可以在最外层引用混合样式
        • 不可直接定义属性,需要混合样式中指定选择器
        • 不可使用父选择器
    • 传递参数为 list 时,使用 $attr... 进行处理,此时会将 $attr 视为 list
  • 使用简写
    • @mixin mixName 可以简写为 =mixName 这里可以有空格
    • @include mixName 可以简写为 +mixName 这里不能有空格

示例

sass
@mixin equidistance-margin($vertial: 0, $horizontal: auto)
    margin:
        top: $vertial
        bottom: $vertial
        left: $horizontal
        right: $horizontal
    @content
.rect
    @include equidistance-margin($horizontal: 20px)
        color: red

编译为

css
.rect {
  margin-top: 0;
  margin-bottom: 0;
  margin-left: 20px;
  margin-right: 20px;
  color: red;
}