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

news2024/11/25 22:52:37

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.coloradmin.cn/o/1405405.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

依托物联网、互联网,建立云端大数据管理平台,形成“端+云+大数据”的智慧工地

概述: 智慧工地,是将物联网应用到建筑工地中,从施工现场源头抓起,最大程度的收集人员、安全、环境、材料等关键业务数据,依托物联网、互联网,建立云端大数据管理平台,的业务体系和新的管理模式…

Linux下用树莓派DS18B20温度传感器读取温度并上传至服务端

目录 一、DS18B20温度传感器 二、逻辑分析 三、实战操作 1、服务端 2、客户端 3、运行结果 一、DS18B20温度传感器 DS18B20是比较常用到的温度传感器,采用单总线控制。是美国DALLAS半导体公司继DS1820之后最新推出的一种改进型智能温度传感器。关于该温度传感…

Leetcode刷题笔记题解(C++):LCR 153. 二叉树中和为目标值的路径

思路:利用回溯的思想,回溯的退出条件为当前节点为空,是符合路径的判断条件为路径和为目标值且叶子节点包含了,代码如下: /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *…

Elasticsearch 常用信息

简述 本文针对 Elasticsearch(简称ES)集群6.x版本出现故障时,可通过提供的命令进行排查。 1、集群健康状态 集群健康状态状态说明red不是所有的主要分片都可用。表示该集群中存在不可用的主分片。可以理解为某个或者某几个索引存在主分片丢失…

Vue2:全局事件总线

一、场景描述 之前我们学习了,通过props实现父子组件之间的通信。通过自定义组件,实现了子给父传递数据。 那么,兄弟关系的组件,如何通信了?任意组件间如何通信了? 这个时候,就要学习全局事件总…

测试工程师必看!测试用例设计全解析,让你彻底掌握

测试工程师在入行时,都会接触到一个名词——测试用例,都知道测试用例是干什么用的,提到设计测试用例的方法,大部分测试工程师都会侃侃而谈:等价类法、边界值法、判定表法、正交分解法……这些方法说起来都如数家珍&…

8-Python 工匠:使用装饰器的技巧

Python 工匠:使用装饰器的技巧 前言 这是 “Python 工匠”系列的第 8 篇文章。[查看系列所有文章] 装饰器 (Decorator) 是 Python 里的一种特殊工具,它为我们提供了一种在函数外部修改函数的灵活能力。它有点像一顶画着独一无二 符号的神奇帽子&#x…

仰暮计划|“说是操场,那就是个土坡,我们在那儿上边种种树啊,拔拔草,有的时候还会有同学来喂喂羊啥的,这都是我们的娱乐”

我是1948年农历二月份在河南省许昌市五女店镇的一个乡村里边出生的。从我记事的时候,中华人民共和国就已经成立了。当时是好多年,经历了三大改造呀、生产队呀、大队呀,乱七八糟的很多,估计你们现在这些孩子们啊,都没有…

浪花 - 更新队伍信息

一、接口设计 1. 请求路径:/team/update 2. 请求参数:TeamUpdateRequest 有些数据不允许修改,封装一个请求类,只存放允许修改的参数列表 package com.example.usercenter.model.request;import lombok.Data;import java.io.Se…

9款最新文生图模型汇总!含华为、谷歌、Stability AI等大厂创新模型(附论文和代码)

2023年真是文生图大放异彩的一年,给数字艺术界和创意圈注入了新鲜血液。从起初的基础图像创作跃进到现在的超逼真效果,这些先进的模型彻底变革了我们制作和享受数字作品的途径。 最近,一些大公司比如华为、谷歌、还有Stability AI等人工智能巨…

软件工程实验报告(完整)

博主介绍:✌全网粉丝喜爱、前后端领域优质创作者、本质互联网精神、坚持优质作品共享、掘金/腾讯云/阿里云等平台优质作者、擅长前后端项目开发和毕业项目实战✌有需要可以联系作者我哦! 🍅附上相关C语言版源码讲解🍅 &#x1f44…

c语言编译链接

目录 目录 前言 一.c语言的编译链接 1.翻译环境 编译阶段可以分为预处理,编译,汇编三个阶段 预处理阶段 编译阶段 词法分析 语法分析 语义分析 汇编阶段 链接阶段 2.运行环境 二.预处理详解 #define定义常量 #define定义宏 宏和函数的对比 #和##运算符…

ETL概念

ETL ETLELT 技术原理ETL 模式应用场景常见工具ETL未来发展方向 ETL 在BI项目中ETL会花掉整个项目至少1/3的时间, ETL设计的好坏直接关接到BI项目的成败。ETL(Extract-Transform-Load) : 用来描述将数据从来源端经过抽取(extract)、转换&…

VS2019配置Reshaper

参考VisualStudio神级插件。一JetBrains Resharpera2023.3.2学习版 拉到下面下载主程序,下载就点下一步就好了 然后不要打开VS2019,再按上面的地址下载学习补丁,下载好如图: 查看ReadMe 我们已经装好Reshaper了,然后点…

gmpy2与一些python库在vscode下没有自动补全的一种缓解方案

经过一定的研究,该问题的原因初步判断是gmpy2这个库天生没有把补全的函数doc说明附在pip包中。且因gmpy2是由C编译而来,以dll或so的形式作为动态链接库给python调用,这意味着无法从源码薅到可用的源码注释。 接下来先讲解决方案,再…

el-table样式错乱解决方案

bug: 图片的椭圆框住的地方,在页面放大缩小之后就对不齐了。 原因: 主要原因是当你对页面放大缩小的时候,页面进行了重构,页面的宽高及样式进行了变化,但是在这个更新的过程中,table的反应并没…

Python爬虫之协程

Python爬虫之协程 为什么要用协程 协程声明 await aiohttp aiofiles 案例修改 案例完整代码 为什么要用协程 轻量级:协程是轻量级的执行单元,可以在同一个线程中并发执行。相比于多线程或多进程,创建和切换协程的开销更小。高效利用资源&…

78.网游逆向分析与插件开发-背包的获取-背包类的C++还原与获取物品名称

内容参考于:易道云信息技术研究院VIP课 上一个内容:77.网游逆向分析与插件开发-背包的获取-物品类的C还原-CSDN博客 码云地址(ui显示角色数据 分支):https://gitee.com/dye_your_fingers/sro_-ex.git 码云版本号&…

影响ETL数据传输性能的9大因素及主流ETL应对策略

前言 现在很多企业在选择ETL工具时都特别关注ETL的数据传输性能,而有很多开源ETL工具都说自已是性能如何如何快,而事实上数据传输性能是不是这些工具说的那样快呢? 数据传输性能受制于哪些因素呢?企业在自身数据库性能受制的情况…

Redis(七)复制

文章目录 是什么功能配置配主库不配从库权限细节 案例配置文件修改 一主二仆固定配置文件主从问题命令操作手动指定 薪火相传反客为主复制原理和工作流程存在问题 是什么 https://redis.io/docs/management/replication/ 就是主从复制,master以写为主,S…