CSS如何在幕后工作?

Posted 前端之巅

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CSS如何在幕后工作?相关的知识,希望对你有一定的参考价值。

作者 | Manisha Basra
译者 | 王强
编辑 | 张之栋、Yonie
html 和 CSS 在浏览器中是怎样处理的?在本文中,我们将探索在浏览器中处理 HTML 和 CSS 的上层机制。

首先我们来探讨 CSS 的解析阶段。

CSS如何在幕后工作?Jonas Schmedtmann 作图

我们先来快速回顾一下 CSS 规则中出现的术语。一条规则是由一个选择器和一个声明块组成的:

CSS如何在幕后工作?

选择器用来选择我们要设置样式的一个或多个 HTML 元素。每个声明都包含一个 CSS 属性及其对应的值。我们赋给属性的值称为声明值。

现在开始具体研究 CSS 的解析阶段。

解决 CSS 的声明冲突:级联

当有某个元素适用多条规则时,将多个样式表组合在一起并解决不同 CSS 规则和声明之间冲突的过程就叫做级联。

例如,font-size 属性可以出现在多个样式表中,也可以在一个样式表中出现多次。

CSS 的来源可以有以下几种:
  1. 作者声明(开发人员写的 CSS)。
  2. 用户声明(用户在浏览器中创建的设置,例如在浏览器中设置 font-size)。
  3. 浏览器声明(也称为用户代理默认浏览器声明)。

级联就是要把所有这些不同来源的 CSS 声明结合在一起。

但是级联到底是怎样解决各种冲突的呢?它是先查看出现冲突的各个声明的重要性、特异性和来源顺序,再据此来确定哪一个更优先的。

以下就是匹配规则的重要性、特异性和来源顺序的具体排序:

CSS如何在幕后工作?Jonas Schmedtmann 作图

重要性

具有!important 指令的规则会始终应用,无论该规则出现在 CSS 文档中的哪个位置都不影响。

最重要的声明是用 important 关键字标记的用户声明;重要性排在第二的是标记为 important 的作者声明;排在第三的是普通的作者声明;最后,最不重要的是默认的浏览器声明。实际应用中这很有意义,因为我们可以轻松地覆盖来自浏览器默认设置的这些声明。

下面来看一个例子加深理解:
.btn{
  padding: 10px 20px;
  font-size: 20px;
  background-color: #000 !important;
}

.para .login .btn{
  background-color: #fff;
}

我们在这里有两条规则。这两条规则都适用于.btn 类,于是我们就对 background-color 有了两个相互矛盾的声明。两者都是作者声明,但是如果仔细查看第一个规则声明会发现,background-color: #000 包含 important 关键字,因此我们根据上面的原则可以知道这条声明更重要。这意味着这条声明将获得更高优先级。

特异性

还有很多时候,我们的作者样式表中只有一堆互相冲突的规则,没有任何 important 关键字。在这种情况下,所有声明都是同等重要的。出现这种情况的时候,级联会计算并比较声明选择器的特异性。

我们用四个类别来定义一个选择器的特异性级别:
  • 内联样式(特异性最高):内联样式直接附加到要设置样式的元素。示例: <h1 style =“color: #ffffff;”>
  • ID:ID 是页面元素的唯一标识符,例如 #navbar。
  • 类,属性和伪类:这个类别包括.classes、[attributes] 和伪类,例如 :hover、:focus 等。
  • 元素和伪元素(特异性最低):这个类别包括元素名称和伪元素,诸如 h1、div、::before 和::after 等。

我们有四个插槽,每个插槽都从零开始:

CSS如何在幕后工作?

  • 第一个选择器:0 0 1 0 特异性,因为它只有一个类选择器。

  • 第二个选择器:0 1 2 2 特异性,因为它有一个 ID 选择器、两个类选择器和两个元素选择器。
  • 第三个选择器:0 0 0 1 特异性,因为它有一个元素选择器。
  • 第四个选择器:0 1 2 1 特异性,因为它有一个 ID 选择器、一个类选择器、一个伪元素和一个元素选择器。
/* we are styling an anchore tag which has class btn */

/* first selector */
.btn{
  font-size: 20px;
  color: #ff23a1;
  background-color: white;
}

/* second selector */
nav#nav div.pull-right .btn{
  background-color: blue;
}

/* third selector */
a{
  background-color: green;
}

/* forth selector */
#nav a.btn:hover{
  background-color: orange;
}

现在我们有了四个特异性级别,我们从左到右来比较它们。先从内联样式开始对比(最特异)。如果一个选择器带有内联样式,则这个选择器将胜出所有其他选择器,因为它是最特异的类别。

但这里并不是这种情况,所以我们转到 ID 来继续分析。在这里我们可以看到第二个和第四个选择器具有一个 ID 特异性。因此,读数为零的选择器就出局了,因为它们比第二个和第四个的选择器特异性要低。由于两个选择器都在这个类别中有一个读数,我们必须继续前进并检查下一个类别。在类这个类别中,第二个和第四个选择器都有两个读数,所以我们移动到下一个类别。

在选择器类别中,第二个选择器具有比第四个选择器更高的特异性。第二个选择器是所有选择器中最特异的,因此 background-color: blue。

来源顺序

如果所有声明选择器都具有相同的特异性,那么就使用最后一个声明。代码中的最后一个声明将覆盖所有其他声明,只应用它自己。

    小结    

  • 标有 !important 标记的 CSS 声明的优先级是最高的(但是 !important 是最后的保留手段)。
  • 内联样式始终优先于外部样式表中的样式。
  • 通用选择器 * 具有最小的特异性值(0,0,0,0)。
  • 更多地依赖于特异性而不是选择器的顺序来排序。
  • 使用第三方样式表时,请始终将作者样式表放在最后。

我希望这篇文章能帮到大家。感谢阅读,好好学习,天天向上!

英文原文: https://medium.com/better-programming/how-does-css-works-behind-the-scenes-aca7152b4e7e

以上是关于CSS如何在幕后工作?的主要内容,如果未能解决你的问题,请参考以下文章

带有块的 UIView 动画如何在幕后工作

了解 Java 调试如何真正在幕后工作

C ++参考如何在幕后工作[重复]

CUDA 分析如何“在幕后”工作?

Meteor 的反应在幕后是如何工作的?

css3pie 是如何工作的?