重大变化:扩展复合选择器

LibSass 目前允许像 .message.info 这样的复合选择器成为 扩展,但它的扩展方式与 @extend 的工作方式不匹配。

兼容性:
Dart Sass
LibSass
Ruby Sass

当一个选择器扩展另一个选择器时,Sass 会对与扩展器匹配的所有元素进行样式设置,就像它们也与正在扩展的类匹配一样。换句话说,如果你编写 .heads-up {@extend .info},它的工作原理就像你将 HTML 中的 class="heads-up" 替换为 class="heads-up info" 一样。

¥When one selector extends another, Sass styles all elements that match the extender as though they also match the class being extended. In other words, if you write .heads-up {@extend .info}, it works just like you replaced class="heads-up" in your HTML with class="heads-up info".

按照这个逻辑,你会期望 .heads-up {@extend .message.info} 的工作方式就像用 class="heads-up info message" 替换 class="heads-up" 一样。但这不是它现在在 LibSass 和 Ruby Sass 中的工作方式 - 它不是将 .heads-up 添加到每个具有 .info.message 的选择器,而是仅将其添加到同时具有 .info.message 的选择器。

¥Following that logic, you’d expect that .heads-up {@extend .message.info} to work like replacing class="heads-up" with class="heads-up info message". But that’s not how it works right now in LibSass and Ruby Sass–instead of adding .heads-up to every selector that has either .info or .message, it only adds it to selectors that have .info.message together.

SCSS Syntax

// These should both be extended, but they won't be.
.message {
  border: 1px solid black;
}
.info {
  font-size: 1.5rem;
}

.heads-up {
  @extend .message.info;
}

Sass Syntax

// These should both be extended, but they won't be.
.message
  border: 1px solid black

.info
  font-size: 1.5rem


.heads-up
  @extend .message.info

为了解决这个问题,避免更多的混乱,并保持实现的干净和高效,Dart Sass 不支持扩展复合选择器的功能,并且将在 LibSass 的未来版本中删除。为了兼容性,用户应该单独扩展每个简单的选择器:

¥To fix this issue, avoid more confusion, and keep the implementation clean and efficient the ability to extend compound selectors is unsupported in Dart Sass and will be removed in a future version of LibSass. For compatibility, users should extend each simple selector separately instead:

SCSS Syntax

.message {
  border: 1px solid black;
}
.info {
  font-size: 1.5rem;
}

.heads-up {
  @extend .message, .info;
}

Sass Syntax

.message
  border: 1px solid black

.info
  font-size: 1.5rem


.heads-up
  @extend .message, .info

CSS Output

.message, .heads-up {
  border: 1px solid black;
}

.info, .heads-up {
  font-size: 1.5rem;
}



⚠️ Heads up!

因为 Sass 不知道 CSS 将要设置样式的 HTML 的详细信息,所以任何 @extend 都可能需要生成不适用于你的 HTML 的额外选择器。当不再使用扩展复合选择器时尤其如此。

¥Because Sass doesn’t know the details of the HTML the CSS is going to style, any @extend might need to generate extra selectors that won’t apply to your HTML in particular. This is especially true when switching away from extending compound selectors.

大多数时候,这些额外的选择器不会造成任何问题,只会向 gzip 压缩的 CSS 添加几个额外的字节。但某些样式表可能更多地依赖于旧的行为。在这种情况下,我们建议将复合选择器替换为 占位符选择器

¥Most of the time, these extra selectors won’t cause any problems, and will only add a couple extra bytes to gzipped CSS. But some stylesheets might be relying more heavily on the old behavior. In that case, we recommend replacing the compound selector with a placeholder selector.

SCSS Syntax

// Instead of just `.message.info`.
%message-info, .message.info {
  border: 1px solid black;
  font-size: 1.5rem;
}

.heads-up {
  // Instead of `.message.info`.
  @extend %message-info;
}

Sass Syntax

// Instead of just `.message.info`.
%message-info, .message.info
  border: 1px solid black
  font-size: 1.5rem


.heads-up
  // Instead of `.message.info`.
  @extend %message-info

CSS Output

.heads-up, .message.info {
  border: 1px solid black;
  font-size: 1.5rem;
}