CSS 是一种美丽且复杂的技术,我们每天在工作中都会用到。然而,包括我在内的许多开发者都忽略了它的一些重要方面。
这很明显,因为在互联网上很难找到关于 CSS 的新知识或高级内容。大多数内容创作者只写一些热门话题,比如新语言、框架和库。
个人对 CSS 的了解仅限于让它正常工作。而这特别令人遗憾,因为我们从未尝试深入研究这个主题。认识到这一点后,做了一些研究,并列出了一些新发现的内容。
CSS 性能
CSS 性能是一个非常重要的话题,因为它直接影响网站的效率。由于现代应用程序包含大量的 CSS 代码,即使是微小的错误也可能导致显著的性能下降。
子选择器
首先,下面赂你展示一些令我惊讶的东西。只需看看下面的例子,试着找出可能的问题。
正如你所看到的,这个例子一点都不复杂。这段 CSS 代码移除了中所有段落内链接的文本装饰。这不是普通的 CSS 吗?
但你知道使用这样的选择器会导致浏览器执行大量额外工作吗?这个问题适用于我们代码中所有类似的子选择器。
这是因为浏览器在解析 CSS 时,从右向左读取选择器。有了这个新知识,我们将这个过程分解成几个步骤:
- 浏览器找到页面上所有的 标签。
- 然后它找到包含在段落中的所有锚点。
- 最后,它将找到的集合缩小到仅包含在 #header 元素内的锚点。
通过使用更具体的选择器,我们可以帮助浏览器避免所有这些额外的工作。我们可以将 .header__link 类应用于锚元素,并用它替换选择器 #header p a。这样,浏览器会更快地找到所需的元素。
昂贵的 CSS 属性
所谓昂贵的 CSS 属性,是指这些属性在我们的应用程序中可能会耗费大量性能。但这并不意味着你完全不能使用它们。你只需要理解,如果元素使用了这些属性并且经常渲染——它肯定会影响性能。
需要注意的一件棘手事情是,改变某些 CSS 属性需要更新整个布局。几何属性如宽度、高度、顶部等可能导致整个树的重新绘制。
还有一些属性很难渲染。虽然这些属性的清单很短,但你可以在这里了解更多关于它们的信息。
- border-radius
- box-shadow
- filter
- :nth-child
- position: fixed
重绘和重排
重绘(Repaint)和重排(Reflow)是在浏览器中渲染网页过程中两个重要的概念。当页面加载或更新时,浏览器会通过一系列步骤将内容显示在屏幕上,而重绘和重排在这个过程中起着重要作用。
为了更好地理解这个过程,我们可以将其分解为几个精确的步骤:
- 从服务器下载的 HTML 文档用于构建文档对象模型(DOM)。
- 样式被加载和识别,创建 CSS 对象模型(CSSOM)。
- 基于 DOM 和 CSSOM,形成一个渲染树,这是一个渲染对象的集合。渲染树复制了 DOM 的结构,但不可见的元素(例如 或 display: none 的元素)不包含在内。换句话说,渲染树描述了 DOM 的视觉表示。
- 对于渲染树中的每个元素,计算其在页面上的位置,并进行布局。浏览器使用流方法,通常一个操作就足以放置所有元素。例如,表格需要更多的操作。
- 最后,所有元素在浏览器中被渲染,并且绘制完成。
当页面首次加载时,如果不是空的,至少会执行一次重排和重绘。但它们也会在以下情况下继续发生:
- 当由于节点的宽度、高度或其他坐标的变化,树的一部分需要重新计算时,会触发重排事件。
- 当由于变化,一些显示的内容必须更新时,这主要适用于诸如背景颜色、半径等样式属性,会触发重绘事件。
- 此外,当发生重排事件时,总是会伴随一个重绘事件。而重绘则可以独立于重排触发。
关于重排
重排是计算网页上元素布局的过程。它根据元素的内容和样式来确定每个元素的大小和位置。
在现代应用程序中,特别是页面上有成千上万个元素和频繁的布局更新时,它很快会变成一个资源消耗大的操作。即使是对文档中单个元素的重排,也可能需要重排其父元素和随后的任何其他元素。
由于它是一个用户阻塞操作,了解如何改进重排以及各种文档属性对其持续时间的影响是非常有用的。典型的引发重排过程的情况通常有:
- 对 DOM 的不同操作。例如,添加、删除和更改节点。
- 元素内容的变化,甚至包括表单字段中的文本。
- 计算(getComputedStyle)或修改 CSS 属性。
- 对元素类的操作。
- 浏览器窗口的操作(调整大小、滚动)。
- 伪类的激活。:hover 就是一个很好的例子。
关于重绘
重绘是将像素绘制到屏幕上的简单过程。在重排期间确定布局后,浏览器将每个元素绘制到屏幕上。
重绘通常比重排消耗的资源少,但它仍然会影响网页的性能。
最典型的情况是当元素样式的变化不影响其在屏幕上的大小或位置时。例如,当背景颜色改变时,浏览器只需用新样式重新绘制(或重绘)节点。
以下是一些会触发重绘的操作的例子:
- 改变元素的可见性。
- 改变元素的轮廓。
- 改变背景。
CSS 可以替代 JS 的地方
JavaScript 和 CSS 是非常棒的技术,尤其是在一起使用时。每种技术都有其独特的优势,结合使用时可以创造出令人难以置信的效果。
然而,我可以自信地说,UI 控制中使用 CSS 越多,Web 应用程序就越容错和可靠。
观点很简单:
- CSS 本身是一种安全技术。当 CSS 解析器遇到无效属性时,它会简单地忽略并继续。
- JavaScript 不是一种安全技术。JS 代码中的单个语法错误可能导致整个应用程序失败。换句话说,当使用 JS 控制样式时,确保相应构造的功能正常工作是至关重要的。
现在让我们考虑一些你可以轻松用 CSS 替代 JS 的情况。
平滑滚动
以前,要实现平滑滚动,需要使用几行 JavaScript 代码。但现在,这个任务可以完全通过 CSS 的力量来解决。
现在你可以通过使用 CSS 属性 scroll-behavior 来实现平滑滚动。
文本处理
CSS 提供了两个很棒的属性:text-overflow 和 line-clamp。它们允许我们修剪文本,同时让我们摆脱使用 JavaScript 代码或其他复杂方法来执行此类任务。这两个属性虽然不是新的,但非常有用。
text-overflow 属性
这个属性控制文本在不适合一行的情况下如何显示。这个属性的一个完美例子是在卡片中使用 text-overflow: ellipsis,它会在被截断的文本末尾显示一个 Unicode 字符 …。
请记住,text-overflow: ellipsis 只有在与 white-space: nowrap 和 overflow: hidden 属性配合使用时才有效。
line-clamp 属性
line-clamp 属性在需要处理多行文本时非常有用。上面示例中的卡片描述展示了它的效果。
这个属性是 CSS Overflow Module Level 3 标准的一部分,虽然目前还处于草案阶段,但已经有大约 95% 的浏览器支持这个属性,但需要加上 -webkit- 前缀。
在使用它之前,重要的是要提到它不允许控制显示字符的数量。但它仍然非常有用。
要使用 line-clamp 属性,我们需要将其与 display: -webkit-box 和 -webkit-box-orient: vertical 结合使用。示例如下:
总结
现代前端开发的世界正在迅速变化,我们不断得到新的机会来帮助我们更快、更好地完成工作。尝试使用 CSS 是非常有趣且有帮助的。如果在不使用 JS 的情况下可以实现相同的结果,请考虑使用 CSS。