一种比较CSS规则特异性的有效算法

Dar*_*ius 7 css sorting css-specificity

我想知道在以下场景中有效的算法是什么:

给出一组解析的css规则,例如.

     p.pStyle{margin-bottom:20px;font-family:Arial;}
     p{font-family:Verdana;}
     p.anotherPStyle{margin-bottom:10px;}
Run Code Online (Sandbox Code Playgroud)

从css样式表中,有几个规则集可能适用于给定元素(比如<p class="pStyle anotherPStyle">hello</p>我的文档中的a).

我需要首先确定样式表中的哪些规则适用于给定元素(所以就是这样p, pStyle and anotherPStyle),然后创建一个能够按特定性(从最具体到最常规)对适用规则进行排序的比较器.注意:我已经设计了一个算法,一旦排序就应用规则,因此您无需有效地解决该问题.

我一直在玩弄几个想法,即涉及确定给定规则特定的DOM树中的级别的想法......虽然我不确定这是否是正确的方法?

浏览器引擎如何有效地执行此操作?我希望用Java复制它,但我对许多其他语言很满意,所以你能提供的任何代码都是最受欢迎的.

谢谢

Mad*_*iha 10

这是由特异性决定的.在这种情况下,由于它们都是同等特定的,因此文件中最后的声明会获胜.

特异性计算

通过对选择器的不同部分进行排名来计算特异性.

排名从最具体到最少:

  1. 样式属性 - 如果在样式属性中找到规则,则此等级为1.
  2. ID - 对于在选择器中找到的每个ID,此等级获得额外的1.
  3. 类,伪类,属性选择器 - 对于在选择器中找到的每个类,此等级获得额外的1.
  4. 元素 - 对于在选择器中找到的每个元素,此等级获得额外的1.

rank n > rank n+1无论每个等级有多少分,都在哪里.

ul#nav li.active a
Run Code Online (Sandbox Code Playgroud)

要点是:

  1. 0 - 不是样式属性.
  2. 找到1 - 1个ID.
  3. 找到1 - 1个类名.
  4. 找到3 - 3个元素.

因此,该选择器中的每个属性都具有特定值[0,0,1,1,3](我们将在一分钟内达到额外的零).该值比任何选择器更具体,只要它可能没有ID,例如.

比较算法:

  1. 从左到右排在队伍中.
  2. 比较两个选择器的排名.
  3. 具有较高点数的等级获胜.
  4. 如果等级相等,则继续直到下一个(不太具体)等级.
  5. 如果所有等级都相等,则CSS文档中稍后出现的等级将获胜.

更重要的说明:

  • 通用选择器(*)没有特异性值(0,0,0,0)伪元素(例如:first-line)0,0,0,1与它们的
    伪类兄弟不同0,0,1,0
  • 伪类:not()本身没有添加任何特异性,只有它内部的括号内容.
  • !important指令可以应用于单个声明,并将一个点添加到"0"排名,这比其他任何更具体
    .因此,在上面的示例中,添加!important任何规则只会使该规则
    的特异性值受到影响, 从而在没有任何其他规则的情况下立即获胜.[1,0,1,1,2]
    !important

额外参考

看到这篇关于这个主题的精彩文章


如何确定哪些样式转到哪个元素

浏览器的工作方式是从右到左遍历选择器,并在DOM中过滤元素.

回到上一个例子:

    ul#nav li.active a
Run Code Online (Sandbox Code Playgroud)

浏览器执行以下操作:

  1. 拿一个a元素.
  2. 现在检查它是否有一个祖先是一个li具有.active类的元素(这是通过后代组合器:) ancestor descendant.
  3. 现在检查它是否具有更高的祖先,ul其ID是#nav(同样,使用了后代组合子).

如果某个元素满足所有这些条件,则将样式应用于它.

你可以读它:

选择 具有类的祖先的任何a元素
,该类.active也是a li,
而该元素又具有ID为的祖先,该祖先#nav也是a ul.

您需要具有完整功能和完整的DOM树才能成功确定哪个元素具有哪些CSS样式.