如何在SCSS中否决@extend指令?

时间:2016-06-17 19:16:14

标签: html css twitter-bootstrap sass css-specificity

按钮组内有按钮。按钮组有不同的大小,例如button-group-large。我的目标是避免在按钮组中的每个按钮上显式设置大小,方法是让它从按钮组中推断出大小。也就是说,而不是

<div class="button-group-large">
  <button class="button-large">Foo</button>
  <button class="button-large">Bar</button>
</div>

我宁愿写这个:

<div class="button-group-large">
  <button>Foo</button>
  <button>Bar</button>
</div>

我可以这样做(在SASS中):

.button-group-large {
  button { @extend .button-large; }
}

这有效,但会产生以下问题。如果我的某个按钮有一个特殊类,则.button-large类将优先。也就是说,如果我这样做

<div class="button-group-large">
  <button class="special">Foo</button>
  <button>Bar</button>
</div>

然后,.special.button-large之间不同的任何属性都会获得.button-large值,而不是.special值。我希望这是相反的; .special应该在这里获胜。 (作为一个真实的例子,.special可能会设置一个“主要”按钮颜色。

这是一个说明问题的方法:https://jsfiddle.net/wwr63qmv/3/

作为参考点,Bootstrap button groups通过要求在每个按钮上单独设置类而不是按钮组来避免此问题。这可能是唯一的答案。还有其他方法可以让.special课程在这里获胜吗?

1 个答案:

答案 0 :(得分:1)

您遇到的问题不是由于Sass或@extend指令。这是CSS的工作原理。如果多个选择器指向同一个元素,则最具体的选择器获胜(或)如果特异性相同,则文件中定义的最新选择器获胜。

编译时,小提琴中的SCSS代码将产生以下输出:

.button, ul.button-group li button { /* check this selector */
  border: 1px solid black;
  color: black;
  border-radius: 2px;
}
.special-button { /* and this */
  border: 1px solid green;
  color: green;
}
ul.button-group {
  margin: 10px;
}
ul.button-group li {
  list-style-type: none;
  display: inline-block;
  padding: 5px;
}
p {
  font-family: monospace;
}

这两个选择器 - ul.button-group li button.special-button都会定位类为.special-button的按钮。第一个选择器的特异性是013(因为它有1个类和3个类型选择器作为完整复杂选择器的一部分),而第二个选择器的特性是010(因为它只有一个类选择器)。因此,本质上第一个选择器获胜,只有在其下指定的属性才适用于该元素。

为了应用.special-button个样式,应该增加该选择器的特异性。这可以通过将选择器更改为ul.button-group li button.special-button来完成,但这意味着选择器现在仅定位button class='special-button',其li范围内ul class='button-group' } parent有button.special-button。这使得它非常具体,意味着如果ul.button-group li.special-button之外,则属性将不适用。

另一种选择是将li扩展到ul.button-group { margin: 10px; li { list-style-type: none; display: inline-block; padding: 5px; button { @extend .button; &.special-button { /* note this */ @extend .special-button; } } } } 范围内,如下所示:

{{1}}

Fiddle Demo