跳至内容

@extend

Stylus @extend 指令的灵感来自(并且基本上与)SASS 实现相同,但有一些细微差别。此功能极大地简化了继承自其他语义规则集的语义规则集的维护。

使用 mixin 进行“扩展”

尽管你可以使用 mixin 来实现类似的效果,但这会导致重复的 CSS。一个典型的模式是按如下所示定义多个类,然后在元素上组合它们,例如“警告消息”。

虽然此技术工作正常,但难以维护。

.message,
.warning {
  padding: 10px;
  border: 1px solid #eee;
}

.warning {
  color: #E2E21E;
}
.message,
.warning {
  padding: 10px;
  border: 1px solid #eee;
}

.warning {
  color: #E2E21E;
}

使用 @extend

要使用 @extend 生成相同的输出,只需将所需选择器传递给它(请注意,@extend@extends 相等,一个只是另一个的别名)。然后,Stylus 将 .warning 选择器追加到现有的 .message 规则集。然后,.warning 类将从 .message 继承属性。

.message {
  padding: 10px;
  border: 1px solid #eee;
}

.warning {
  @extend .message;
  color: #E2E21E;
}
.message {
  padding: 10px;
  border: 1px solid #eee;
}

.warning {
  @extend .message;
  color: #E2E21E;
}

这是一个更复杂的示例,演示了 @extend 如何级联

red = #E33E1E
yellow = #E2E21E

.message
  padding: 10px
  font: 14px Helvetica
  border: 1px solid #eee

.warning
  @extends .message
  border-color: yellow
  background: yellow + 70%

.error
  @extends .message
  border-color: red
  background: red + 70%

.fatal
  @extends .error
  font-weight: bold
  color: red
red = #E33E1E
yellow = #E2E21E

.message
  padding: 10px
  font: 14px Helvetica
  border: 1px solid #eee

.warning
  @extends .message
  border-color: yellow
  background: yellow + 70%

.error
  @extends .message
  border-color: red
  background: red + 70%

.fatal
  @extends .error
  font-weight: bold
  color: red

产生以下 CSS

.message,
.warning,
.error,
.fatal {
  padding: 10px;
  font: 14px Helvetica;
  border: 1px solid #eee;
}
.warning {
  border-color: #e2e21e;
  background: #f6f6bc;
}
.error,
.fatal {
  border-color: #e33e1e;
  background: #f7c5bc;
}
.fatal {
  font-weight: bold;
  color: #e33e1e;
}
.message,
.warning,
.error,
.fatal {
  padding: 10px;
  font: 14px Helvetica;
  border: 1px solid #eee;
}
.warning {
  border-color: #e2e21e;
  background: #f6f6bc;
}
.error,
.fatal {
  border-color: #e33e1e;
  background: #f7c5bc;
}
.fatal {
  font-weight: bold;
  color: #e33e1e;
}

Stylus 当前与 SASS 的不同之处在于,SASS 不允许 @extend 嵌套选择器

form
  button
    padding: 10px

a.button
  @extend form button
Syntax error: Can't extend form button: can't extend nested selectors
        on line 6 of standard input
  Use --trace for backtrace.
form
  button
    padding: 10px

a.button
  @extend form button
Syntax error: Can't extend form button: can't extend nested selectors
        on line 6 of standard input
  Use --trace for backtrace.

使用 Stylus,只要选择器匹配,它就能工作!

form
  input[type=text]
    padding: 5px
    border: 1px solid #eee
    color: #ddd

textarea
  @extends form input[type=text]
  padding: 10px
form
  input[type=text]
    padding: 5px
    border: 1px solid #eee
    color: #ddd

textarea
  @extends form input[type=text]
  padding: 10px

产生

form input[type=text],
textarea {
  padding: 5px;
  border: 1px solid #eee;
  color: #ddd;
}
textarea {
  padding: 10px;
}
form input[type=text],
textarea {
  padding: 5px;
  border: 1px solid #eee;
  color: #ddd;
}
textarea {
  padding: 10px;
}

扩展多个选择器

Stylus 允许你一次扩展多个选择器,只需用逗号编写它们即可

.a
  color: red

.b
  width: 100px

.c
  @extend .a, .b
  height: 200px
.a
  color: red

.b
  width: 100px

.c
  @extend .a, .b
  height: 200px

产生

.a,
.c {
  color: #f00;
}
.b,
.c {
  width: 100px;
}
.c {
  height: 200px;
}
.a,
.c {
  color: #f00;
}
.b,
.c {
  width: 100px;
}
.c {
  height: 200px;
}

扩展占位符选择器

Stylus 具有与 Sass 中类似的功能——占位符选择器。

这些选择器应以 $ 符号开头(例如,$foo),并且不会在生成的 CSS 中产生。但你仍然可以扩展它们

$foo
  color: #FFF

$foo2
  color: red

.bar
  background: #000
  @extends $foo

.baz
  @extends $foo
$foo
  color: #FFF

$foo2
  color: red

.bar
  background: #000
  @extends $foo

.baz
  @extends $foo

产生

.bar,
.baz {
  color: #fff;
}
.bar {
  background: #000;
}
.bar,
.baz {
  color: #fff;
}
.bar {
  background: #000;
}

请注意,如果未扩展选择器,它将不会出现在生成的 CSS 中,因此这是创建可扩展代码库的强大方式。虽然你可以通过 mixin 插入代码,但每次使用它们时它们都会插入相同的代码,而扩展占位符将为你提供紧凑的输出。

可选扩展

有时,根据上下文,能够扩展可能存在或不存在的内容可能很有用。你可以使用 !optional 为任何选择器添加后缀以实现此目的

$specialDesign
  color: #FFF

.btn
  @extend .design !optional, $specialDesign !optional
$specialDesign
  color: #FFF

.btn
  @extend .design !optional, $specialDesign !optional

产生

.btn {
  color: #fff;
}
.btn {
  color: #fff;
}