为什么 12 个元素选择器不覆盖 CSS 中的单个 class 选择器?

Why do 12 element selectors not override single class selector in CSS?

所以我一直在努力思考 CSS 特异性,在我看来,公式的工作方式是:

10^0 * (# of element + pseudo element selectors) + 10^1 * (# of classes + attributes + pseudo class 选择器) + 10^2 * (# id 选择器的数量)+ 10^3 *(内联选择器)

因此,为了进行实验,我创建了一个 HTML 页面,其中有 12 个嵌套元素选择器应用于一段文本,还有一个 class 选择器。在这种情况下,许多元素选择器似乎应该覆盖单个 class 选择器,但事实并非如此。如果元素选择器获胜,此示例将文本呈现为红色,如果 class 选择器获胜,则将文本呈现为绿色。

这是怎么回事?我误解了特异性公式吗?单个 class 选择器是否总能胜过任意数量的元素选择器?这就是为什么 id 选择器被认为是代码味道的原因,因为它们会覆盖任意数量的属性和 class 选择器?

html > body > main > article > section > form > div > figcaption > div > p > span > em {
      color: red;
    }

    html body main article section form div figcaption div p span em {
      color: red;
    }
    
    .test {
      color: green;
    }
<!doctype html>
<html>
  <head>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
  </head>

  <body>
    <main>
      <article>
        <section>
          <form>
            <div>
              <figcaption>
                <div>
                  <p>
                    <span>
                      <em class="test">TESTING 123</em>
                    </span>
                  </p>
                </div>
              </figcaption>
            </div>
          </form>
        </section>
      </article>
    </main>
  </body>
</html>

你把事情弄糊涂了,

您的选择器的特殊性是:

html > body > main > article > section > form > div > figcaption > div > p > span > em 

0,0,0,12


html body main article section form div figcaption div p span em

0,0,0,12


.test

0,0,1,0


揭穿这 4 个级别:0,0,0,0

  • 第 1 级 - 内联样式
  • 二级 -ID
  • 第 3 级 - 类、属性和伪classes
  • 第 4 级 - 元素和伪元素

为什么文本是绿色的?

因为你只有在使用HTML元素,这在特异性级别中是最低重要的(第4)。 因此 class 更具体,使文本始终为绿色

看看:

计算特异性here

查看更多关于特异性的信息 W3C

Does a single class selector always win over an arbitrary number of element selectors?

就是这样。从本质上讲,您必须在带有 "arbitrarily large base" 的数字系统中思考。也就是说,12 个元素选择器为您提供了一个可以描述为“0-0-0-12”的特性,它不会转换为“0-0-1-2”,因为数字系统的基础不是10.

是的,这是人们建议避免使用 ID 选择器的原因之一。

Here 是一段相关规范,虽然我真的不认为他们的例子对澄清这个问题有任何帮助...

想想奥运会。更好的是:

  • 五枚铜牌还是一枚银牌?
  • 三枚银牌还是一枚金牌?

就我个人而言,我会选择一银一金。

这就是特异性点的分类方式。

来自规范:

9. Calculating a selector's specificity

A selector's specificity is calculated as follows:

  • count the number of ID selectors in the selector (= a)
  • count the number of class selectors, attributes selectors, and pseudo-classes in the selector (= b)
  • count the number of type selectors and pseudo-elements in the selector (= c)

Concatenating the three numbers a-b-c (in a number system with a large base) gives the specificity.

emphasis mine

换句话说,数字和串联都很重要。

因此,元素选择器:

 0 0 12

小于class选择器:

 0 1 0

class 获胜(1 银 vs 12 铜)。

您可以有 100 个元素选择器,class 仍然会获胜。