《WebKit 技术内幕》之六(2): CSS解释器和样式布局

2 CSS解释器和规则匹配

        在了解了CSS的基本概念之后,下面来理解WebKit如何来解释CSS代码并选择相应的规则。通过介绍WebKit的主要设施帮助理解WebKit的内部工作原理和机制。

2.1 样式的WebKit表示类

        在DOM树中,CSS样式可以包含在“style”元素中或者使用“link”来引用一个CSS文档。对于CSS样式表,不管是内嵌还是外部文档,WebKit都使用CSSStyleSheet类来表示。图描述了WebKit内部是如何表示CSS文档的。

                                         图CSS的内部结构主要类和关系

        一切的起源都是从DOM中的Document类开始。先看Document类之外的左上部分:包括一个DocumentStyleSheetCollection类,该类包含了所有CSS样式表;还包括WebKit的内部表示类CSSStyleSheet,它包含CSS的href、类型、内容等信息。CSS的内容就是样式信息StyleSheetContents,包含了一个样式规则(StyleRuleBase)列表。样式规则被用在CSS的解释器的工作过程中。

        下面的部分WebKit主要是将解释之后的规则组织起来,用于为DOM中的元素匹配相应的规则,从而应用规则中的属性值序列。这一过程的主要负责者是StyleSheetResolver类,它属于Document类,并包含了一个DocumentRuleSets类用来表示多个规则集合(RuleSet)。每个规则集合都是将之前解释之后的结果合并起来,并进行分类,例如id类规则、标签类规则等。至于为什么是多个规则集合,是因为这些规则集合可能源自于默认的规则集合(前面提到过WebKit使用默认的CSS样式信息),或者网页自定义的规则集合等。

        下面让我们更进一步重点介绍样式规则。样式规则是解释器的输出结构,是样式匹配的输入数据。样式规则有很多类型,图描述了这些类和继承关系。

                                图StyleRuleBase和它的子类们

  • Style: 这个是基本类型,大多数规则属于这个类型。
  • lmport: 是WebKit中为了方便而引入的,其对应的是一个导入CSS文件的Style元素。
  • Media: 对应于CSS标准中的@media类型。
  • Fontface: CSS3新引入的自定义字体的规则类型。
  • Page: 对应于CSS标准中的@page类型。
  • Keyframes: 对应于WebKit中的@-webkit-key-frames类型,可以用来定制特定帧的样式属性信息。
  • Region: 对CSS标准正在进行中的Regions的支持,这方便了开发者对页面进行分区域排版。

        这些类基本上跟CSS的标准相对应,当然也有特例,那就是StyleRuleImport,它是WebKit引入的一个新的类型,主要对应的是导入CSS文件的元素。

        接下来剖析规则的内部是如何组成和表示的。图描述的是一个CSS规则(从示例代码中获取)和WebKit的内部结构表示类。

                                图CSS样式规则和WebKit的内部结构表示类

        首先最外层的是样式规则,通常一个样式表可能包括一个或者多个样式规则,这里描述的样式规则对应于图中的StyleRule类。

        然后是选择器部分,图的上半部分是一个选择器列表,这在现实中是比较常见的,因为选择的条件可能有多个。举个例子,“a[class=abc]”其实是两个选择器合起来的,第一个是“a”,它是一个标签选择器;第二个是“[class=abc]”,它是一个属性选择器。这两个选择器合起来的含义就是匹配元素是“a”的标签并且它的类别为“abc”。选择器在WebKit的内部表示是CSSSelector类。在规则中,CSSSelector类使用一个对象列表来表示它们。

        最后是这个规则对应的属性集合CSSPropertySet。WebKit使用了一些类来分别表示属性名字CSSPropertyID (1) 、属性值CSSValue。图6-7清晰地描述了它们的结构。

2.2 解释过程

        CSS解释过程是指从CSS字符串经过CSS解释器处理后变成渲染引擎的内部规则表示的过程。在WebKit中,这一过程如图所示。

                                图CSS解释器的工作过程

        这一过程并不复杂,基本的思想是由CSSParser类负责。CSSParser类其实也是桥接类,实际的解释工作是由CSSGrammer.y.in来完成。CSSGrammer.y.in是Bison的输入文件,Bison是一个生成解释器的工具。Bison根据CSSGrammer.y.in生成CSS解释器——CSSGrammer类。当然CSSGrammer类需要调用CSSParser类来处理解释结果,例如需要使用CSSParser类创建选择器对象、属性、规则等。

        图描述的正是这一过程。当WebKit需要解释CSS内容的时候,它调用CSSParser对象来设置CSSGrammer对象等,解释过程中需要的回调函数由CSSParser来负责处理,最后WebKit将创建好的结果直接设置到StyleSheetContents对象中,这一过程显得直接而且简单。

        在解释网页中自定义的CSS样式之前,实际上WebKit渲染引擎会为每个网页设置一个默认的样式,这决定了网页所没有设置的元素属性及其属性默认值和将要显示的效果。一般来讲,不同的WebKit移植可以设置不同的默认样式。下面是Chrome浏览器使用的默认样式,这些样式决定了默认的网页显示效果。

"html,body,div{display:block}head{display:none}body{margin:8px}div:focus, span:focus{outline:auto 5px-webkit-focus-ring-color}a:-webkit-any-link{color:-webkit-link;text-decoration:underline}a:-webkit-any-link:active{color:-webkit-activelink}"

2.3 样式规则匹配

        样式规则建立完成之后,WebKit保存规则结果在DocumentRuleSets对象类中。当DOM的节点建立之后,WebKit会为其中的一些节点(只限于可视节点,在第7章中介绍)选择合适的样式信息。根据前面的描述,这些工作都是由StyleResolver来负责的。当然,实际的匹配工作还是在DocumentRuleSets类中完成的。

        图描述了参与样式规则匹配的WebKit主要相关类。基本的思路是使用StyleResolver类来为DOM的元素节点匹配样式。StyleResolver类根据元素的信息,例如标签名、类别等,从样式规则中查找最匹配的规则,然后将样式信息保存到新建的RenderStyle对象中。最后,这些RenderStyle对象被RenderObject类所管理和使用。

                                图CSS样式规则匹配使用的主要WebKit类

        规则的匹配则是由ElementRuleCollector类来计算并获得,它根据元素的属性等信息,并从DocumentRuleSets类中获取规则集合,依次按照ID、类别、标签等选择器信息逐次匹配获得元素的样式。那么具体的过程如何呢?图为我们描述了WebKit如何为HTML元素获取样式并从规则集合中匹配的过程。

                        图为HTML元素获取样式和WebKit的样式规则匹配过程

        首先,当WebKit需要为HTML元素创建RenderObject类的时候,首先StyleResolver类负责获取样式信息,并返回RenderStyle对象,RenderStyle对象包含了匹配完的结果样式信息。

        其次,根据实际需求,每个元素可能需要匹配不同来源的规则,依次是用户代理(浏览器)规则集合、用户规则集合和HTML网页中包含的自定义规则集合。这三个规则的匹配方式是类似的,这里是以自定义规则的匹配为例加以说明的。

        再次,对于自定义规则集合,它先查找ID规则,检查有无匹配的规则,之后依次检查类型规则、标签规则等。如果某个规则匹配上该元素,WebKit把这些规则保存到匹配结果中。

        最后,WebKit对这些规则进行排序。对于该元素需要的样式属性,WebKit选择从高优先级规则中选取,并将样式属性值返回。

2.4 实践:样式匹配

为了理解样式的实际匹配过程和结果,以网页“http://lab.hakim.se/reveal-js/”为例,详细的步骤如下。

        首先,打开Chrome浏览器输入上述网页地址,并打开开发者工具,单击“Elements”按钮。

        其次,在开发者工具中单击“打开网页的源代码”按钮,选择“body”元素,在开发者工具的右侧,读者会看到如图6-11左边部分所示经过计算的该元素的匹配结果样式(Computed Style)。用户甚至可以直接在开发者工具中修改属性值,看看它们是如何影响布局的。

                                        图网页的样式计算和规则匹配

               最后,查看一下“styles”中的“Matched CSS Rules”,这些规则能够匹配上该节点的规则列表,但是不同的属性可能来源于不同的规则。在本例中,读者可以看到图中右边的部分就是当前匹配上的各个样式规则,它们来源于不同的CSS样式表中不同的规则。前面四个规则来源于网页自定义的样式表,最后一个“user agent stylesheet”来源于浏览器默认样式表。这些规则中有些对属性的设置有冲突,当然规则按照CSS标准定义的优先级来选择。图中被线划掉的表示该属性没有对当前元素起作用,这包含了两种情形:第一是属性设置错误;第二是被更高优先级的规则属性覆盖。开发者通过元素的具体匹配规则可以调试和修改自己的样式规则。

2.5 JavaScript设置样式

        CSSOM定义了JavaScript访问样式的能力和方式。示例代码6-1中的第29行所示的是使用CSSOM接口来更改属性值的。在WebKit中,这需要JavaScript引擎和渲染引擎协同完成。为了描述这一过程,可能会涉及到一些JavaScript引擎的调用,目前比较难以理解,所以读者只需要有一个大致的印象即可,在第9章的JavaScript引擎中会有更详细和系统的介绍。

        大致的过程是,JavaScript引擎调用设置属性值的公共处理函数,然后该函数调用属性值解析函数,在这个例子中则是CSS的JavaScript绑定函数。而后WebKit将解析后的信息设置到元素的“style”属性的样式“webkitTransform”中,然后设置标记表明该元素需要重新计算样式,并触发重新计算布局。最后就是WebKit的重新绘图,图6-12描述了其中的主要过程。

                                       图WebKit引擎和JavaScript引擎设置样式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/422020.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uniapp组件库SwipeAction 滑动操作 使用方法

目录 #平台差异说明 #基本使用 #修改按钮样式 #点击事件 #API #Props #Event 该组件一般用于左滑唤出操作菜单的场景,用的最多的是左滑删除操作。 注意 如果把该组件通过v-for用于左滑删除的列表,请保证循环的:key是一个唯一值,可以…

【Linux】Linux开发工具 - vim的基本操作

IDE例子 Linux编辑器-vim使用 vi/vim的区别简单点来说,它们都是多模式编辑器,不同的是vim是vi的升级版本,它不仅兼容vi的所有指令,而且还有一些新的特性在里面。例如语法加亮,可视化操作不仅可以在终端运行&#xff…

NVM (Node Version Manager) 安装使用

博文目录 文章目录 管理工具安装使用 管理工具 GitHub, nvm-windows nvm-windows: Similar (not identical) to nvm, but for Windows 管理 Node.js 版本有多种工具可选择, 其中使用最广泛的是 nvm, 目前 72.3k Star, 不支持 Windows 系统, nvm-windows, 是其他大佬为 Windows…

恒创科技:香港服务器内存不足有哪些原因?

内存是服务器中非常重要的组件之一,它直接影响服务器的运行速度和稳定性。然而,在使用香港服务器的过程中,有时候会出现内存不足的情况,导致服务器性能下降,甚至出现宕机等问题。那么,香港服务器内存不足的…

伪原创文章生成器软件免费使用的方法

写文章不仅消耗时间,而且还容易出现写不出内容的问题,随着技术的发展,越来越多的人开始不再亲历亲为的去写文章了,而是用起了伪原创文章生成器软件,对于还不了解自动生成文章软件的人,可不要小瞧这个它了&a…

Linux服务部署,遇到的各种问题之一(测试篇)

最近服务器需要搬迁,所有的服务都需要迁移,从初始化数据盘,到服务部署的各种细节,下面我们一一来说 初始化数据盘就不用说了,大概率,作为测试接触不到。 今天来说是ubuntu显示的中文文件乱码问题如何解决…

np.argsort排序问题(关于位次)-含GitHub上在numpy项目下提问的回复-总结可行方案

np.argsort 与获取位相关问题 位次: 数组中的数据在其排序之后的另一个数组中的位置 [1,0,2,3] 中 0的位次是1 1的位次是2 2的位次是3 3的位次是4 这里先直接给出结论,np.argsort()返回的索引排序与实际位次在确实在某些情况下会出现一致,但后来numpy的开…

Gitee Reward让开源作者不再为爱发电

一、什么是Gitee Reward? Gitee Reward是Gitee为改善开源开发生命周期提出的新策略。开源项目的支持者们可以更轻松地为其喜爱的项目提供资金,贡献者们也可以因为其不懈的开源贡献得到奖励。 二、Gitee Reward上允许哪些类型的项目? 允许任…

【数据结构与算法】之字符串系列-20240121

这里写目录标题 一、344. 反转字符串二、125. 验证回文串三、205. 同构字符串四、242. 有效的字母异位词五、290. 单词规律 一、344. 反转字符串 简单 编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额…

javaWeb三层架构之学生管理系统

一 系统架构 三层架构 为了实现代码的层次清晰,分工明确,通常会将一个应用划分成三层架构:表示层、业务逻辑层、数据访问层。 * 表示层(web):主要接收前端发送的请求,并响应数据* 业务逻辑层(service): 负责处理具体的…

Excel 动态可视化图表分享

AIGC ChatGPT 职场案例 AI 绘画 与 短视频制作 PowerBI 商业智能 68集 数据库Mysql 8.0 54集 数据库Oracle 21C 142集 Office 2021实战应用 Python 数据分析实战, ETL Informatica 数据仓库案例实战 Excel 2021实操 100集, Excel 2021函数大全 80集 Exc…

数据结构与算法:图

文章目录 图1) 概念有向 vs 无向度权路径环图的连通性 2) 图的表示3) Java 表示4) DFS5) BFS6) 拓扑排序7) 最短路径DijkstraBellman-FordFloyd-Warshall 8) 最小生成树PrimKruskal 图 1) 概念 图是由顶点(vertex)和边(edge)组成…