CSS标签限定(例如h1.some-class)有什么问题?

有人可以向我解释为什么标签合格是CSS不良做法的原因吗?为什么在带有自解释元素的情况下tag.class不好?例如

<section class="carousel-item">

  <header class="header of-carousel">
    <h2 class="heading of-carousel">Services</h2>
  </header>
  <footer class="footer of-carousel">
  </footer>

</section>

为什么它比带有上下文修饰符的DRY和简洁代码更好?

<section class="carousel-item">

  <header class="of-carousel">
    <h2 class="of-carousel">Services</h2>
  </header>
  <footer class="of-carousel">
  </footer>

</section>

.of-carousel {
  header.& {…}
  h2.& {…}
  footer.& {…}
}

甚至

section.carousel-item
  header
    h2
  footer

.carousel-item {
  header {…}
      h2 {…}
  footer {…}
}

我看到很多人沉迷于BEM,但是我不明白为什么?他们的选择器非常丑陋,尤其是在HTTP-2时代。

阳光米亚2020/03/24 15:31:22

BEM背后的原理是删除CSS文档中的所有实际层次结构,并对要设置样式的每个元素只有一个明确的规则。这就是效率高的原因-渲染器无需遍历DOM来处理子规则,也不必尝试与多个限定符进行匹配(这就是为什么将标记限定符与类选择器一起使用被认为是“不好的” )。但是我确实同意,BEM的标准命名约定非常难看。您可以根据自己的喜好进行更改。

您需要了解CSS规则是从右到左处理的。以您的示例为例:

.carousel-item {
    header {…}
    h2 {…}
    footer {…}
}

这将导致渲染器来匹配所有的 <header><h2><footer>元素第一。使用这些匹配项,它将尝试找到匹配的父项.carousel-item,并一路迭代到文档的根目录,直到找到一个为止。如果将这种样式应用于深层嵌套的文档,<h2>文档中<header>没有包含多个元素,则.carousel-item意味着浪费大量的查找内容。简单地说:这不是很有效。

您可以通过使用直接子选择器(>)来减轻这种影响,因为它不会尝试遍历整个DOM;它只会尝试第一个父母。BEM完全避免了此问题。

实际上,现在这是一个非常小的问题,与非最佳CSS相比,处理客户端JavaScript可能花费更多的CPU周期。但是,如果要构建更大的东西,请牢记这是一件好事。

2020/03/24 15:31:22

您应该避免嵌套,这样可以最大程度地减少其他规则相互冲突的机会。确保我们的CSS模块在任何情况下看起来都一样。

.block__elem-如果不使用多个嵌套元素,则修饰符语法并不难看。