CSS 的工作原理

我们已经学习了 CSS 的基础知识,包括它的用途以及如何编写简单的样式表。在本课中,我们将探讨浏览器如何将 CSS 和 HTML 结合起来,最终呈现为网页。

先决条件 已安装基本软件,了解文件操作的基础知识,以及 HTML 基础知识(学习HTML 简介)。
目标 了解浏览器解析 CSS 和 HTML 的基本原理,以及浏览器遇到无法理解的 CSS 时会发生什么。

CSS 到底是如何工作的?

当浏览器显示文档时,它必须将文档的内容与其样式信息结合起来。它会分多个阶段处理文档,我们将在下面列出这些阶段。请记住,这只是浏览器加载网页时发生情况的简化版本,不同的浏览器会以不同的方式处理此过程。但大体上会发生以下步骤。

  1. 浏览器加载 HTML(例如从网络接收)。
  2. 它将HTML转换为DOM文档对象模型)。DOM 在计算机内存中表示文档。DOM 在下一节中将作更详细的说明。
  3. 然后,浏览器会获取 HTML 文档中链接的大多数资源,例如嵌入的图像、视频,甚至链接的 CSS!JavaScript 在此过程的稍后阶段处理,为了简化,我们在此不做介绍。
  4. 浏览器解析获取的 CSS,并将不同的规则根据其选择器类型分类到不同的“桶”中,例如元素、类、ID 等等。根据找到的选择器,它确定应将哪些规则应用于 DOM 中的哪些节点,并在需要时将样式附加到它们(此中间步骤称为渲染树)。
  5. 渲染树按照在应用规则后应出现的结构进行布局。
  6. 页面在屏幕上显示其视觉效果(此阶段称为绘制)。

下图也简单地展示了该过程。

Rendering process overview

关于 DOM

DOM 具有树状结构。标记语言中的每个元素、属性和文本片段都会成为树状结构中的DOM 节点。节点由它们与其他 DOM 节点的关系定义。某些元素是子节点的父节点,而子节点具有兄弟节点。

了解 DOM 有助于您设计、调试和维护 CSS,因为 DOM 是 CSS 与文档内容相遇的地方。当您开始使用浏览器开发者工具时,您将在选择项目以查看哪些规则适用时浏览 DOM。

真实的 DOM 表示

与其长篇大论,不如通过一个示例来看看如何将实际的 HTML 代码片段转换为 DOM。

请看以下 HTML 代码

html
<p>
  Let's use:
  <span>Cascading</span>
  <span>Style</span>
  <span>Sheets</span>
</p>

在 DOM 中,与我们的<p>元素对应的节点是父节点。它的子节点是文本节点和与我们的<span>元素对应的三个节点。SPAN 节点也是父节点,其子节点为文本节点

P
├─ "Let's use:"
├─ SPAN
|  └─ "Cascading"
├─ SPAN
|  └─ "Style"
└─ SPAN
    └─ "Sheets"

这就是浏览器解释上述 HTML 代码片段的方式 - 它渲染上面的 DOM 树,然后在浏览器中输出它,如下所示

将 CSS 应用到 DOM

假设我们向文档添加一些 CSS 来对其进行样式设置。再次,HTML 如下所示

html
<p>
  Let's use:
  <span>Cascading</span>
  <span>Style</span>
  <span>Sheets</span>
</p>

假设我们对它应用以下 CSS

css
span {
  border: 1px solid black;
  background-color: lime;
}

浏览器解析 HTML 并从中创建 DOM。接下来,它解析 CSS。由于 CSS 中唯一可用的规则具有span 选择器,因此浏览器会非常快地对 CSS 进行排序!它将该规则应用于三个<span>中的每一个,然后将最终的视觉表示绘制到屏幕上。

更新后的输出如下所示

在下一模块中的调试 CSS 文章中,我们将使用浏览器开发者工具来调试 CSS 问题,并更多地了解浏览器如何解释 CSS。

如果浏览器遇到它不理解的 CSS 会发生什么?

"什么是 CSS" 文章中的"浏览器支持信息" 部分提到,浏览器并不一定同时实现新的 CSS 功能。此外,许多人并没有使用最新版本的浏览器。鉴于 CSS 不断发展,并且领先于浏览器所能识别的范围,您可能会想知道如果浏览器遇到无法识别的 CSS 选择器或声明会发生什么。

答案是,它什么也不做,只是继续处理下一个 CSS 部分!

如果浏览器正在解析您的规则,并且遇到无法理解的属性或值,它会忽略它并继续处理下一个声明。如果您在拼写属性或值时出错,或者属性或值太新,浏览器尚不支持,它就会这样做。

同样,如果浏览器遇到无法理解的选择器,它会忽略整个规则并继续处理下一个规则。

在下面的示例中,我使用了“颜色”的英式拼写,这使得该属性无效,因为它无法识别。因此,我的段落没有变为蓝色。但是,所有其他 CSS 都已应用;仅忽略无效行。

html
<p>I want this text to be large, bold and blue.</p>
css
p {
  font-weight: bold;
  colour: blue; /* incorrect spelling of the color property */
  font-size: 200%;
}

这种行为非常有用。这意味着您可以使用新的 CSS 作为增强功能,因为您知道如果它不被理解,就不会发生错误 - 浏览器要么获得新功能,要么不获得。这使您可以实现基本的回退样式。

当您想要使用一个非常新且并非处处都支持的值时,这种方法特别有效。例如,某些旧版浏览器不支持calc() 作为值。我可能会用像素为一个框设置一个回退宽度,然后继续用calc()100% - 50px 设置一个宽度。旧版浏览器将使用像素版本,忽略关于calc() 的行,因为它们不理解它。新版浏览器将使用像素解释该行,但随后将使用calc() 的行覆盖它,因为该行在级联中位于后面。

css
.box {
  width: 500px;
  width: calc(100% - 50px);
}

我们将在后面的课程中学习更多关于支持各种浏览器的方法。

总结

您已经快要完成本模块了 - 我们只差最后一步。在样式设置传记页面评估中,您将使用新学到的知识重新设置示例的样式,并在此过程中测试一些 CSS。