前言
谈到CSS,就会想到兼容性,想到兼容性就会涉及到浏览器,因为浏览器是CSS的运行环境。
浏览器
浏览器指显示万维网上的媒体信息(文字、图像、音频、视频等)和处理用户交互操作的软件。
世界五大浏览器鼎立的格局:
plain
世界五大浏览器:Chrome、Safari、Firefox、Opera、IExplorer/Edge
渲染引擎
渲染引擎 又名浏览器内核,指负责对网页语法解析并渲染成一张可视化页面的解析器。
它是浏览器最核心最重要的部位,不同内核对网页语法的解析也有不同,因此同一网页语法在不同内核的浏览器中的渲染效果也可能不同,这就是常说的浏览器差异性。
上述提到的世界五大浏览器,在自身的发展过程中都使用了一种或多种浏览器内核作为自身的渲染引擎。
- Chrome:Webkit(前期)、Blink(后期)
- Safari:Webkit
- Firefox:Gecko
- Opera:Presto(前期)、Blink(后期)
- Edge(/ edʒ /):Trident(前期)、Blink(后期)
- IExplorer:Trident
plain
IExplorer和Edge同是微软公司开发的浏览器产品,鉴于IExplorer存在很多为人诟病的问题,在后续的系统升级中逐渐使用Edge取代IExplorer在Windows上的位置
因此浏览器历史里,被大规模使用的浏览器内核也就这五个。
-
Blink内核 :由谷歌公司和欧朋公司合作自研的内核,同时谷歌公司也将其作为开源内核架构
Chromium
的一部分发布,在Chrome 28+
和Opear 15+
中被使用。 -
Webkit内核 :由苹果公司自研的内核,同时也是
Blink内核
的原型,在Chrome 1 ~ 28
和Safari 1+
中被使用。 -
Gecko(/ ˈɡekəʊ /)内核 :由网景公司自研的内核,先期在
Navigator
中使用,后期推广到Firefox
上,在Firefox 1+
中被使用。 -
Presto内核 :由欧朋公司自研的内核,其渲染性能达到极致但是牺牲了兼容性,目前已经废弃,在
Opear 7 ~ 14
中被使用。 -
Trident内核 :由微软公司自研的内核,由于其被包含在全世界使用率最高的
Windows操作系统
中,导致十多年时间里一直称霸浏览器内核界,在IExplorer 4+
中被使用。
推荐一个统计互联网市场份额的网站StatCounter,以后产品经理让你兼容IExplorer
,你可把浏览器市场份额统计数据
全盘搬出,大声并自信地告诉TA,现在几乎没人使用IExplorer了🤔。
渲染过程
要了解浏览器页面的渲染过程,首先得知道关键渲染路径
。关键渲染路径指浏览器从最初接收请求得到HTML、CSS、JS等资源,然后解析、构建、渲染、布局、绘制、合成,到最后呈现在用户眼前界面的整个过程。
渲染过程分为以下几部分。
-
解析文件
-
- 将
html文件
转换为DOM树 - 将
css文件
转换为CSSOM树
- 将
-
- 将DOM树和CSSOM树合并生成渲染树
-
绘制图层
-
- 根据渲染树布局(
回流
) - 根据布局绘制(
重绘
)
- 根据渲染树布局(
-
合成图层:合成图层显示在屏幕上
解析文件
HTML文档描述一个页面的结构,浏览器通过HTML解析器
将HTML解析成DOM树
结构。HTML文档中所有内容皆为节点,各节点间拥有层级关系,彼此相连,构成DOM树。
CSS文档描述一个页面的表现,浏览器通过CSS解析器
将CSS解析成CSSOM树
结构,与DOM树结构比较像。CSS文档中所有内容皆为节点,与HTML文档中的节点一一对应,各节点间拥有层级关系,彼此相连,构成CSSOM树。
在构建DOM树的过程中,当HTML解析器
遇到<script>
时会立即阻塞DOM树的构建,将控制权移交给浏览器的JS引擎
,等到JS引擎
运行完毕,浏览器才会从中断的地方恢复DOM树的构建。
<script>
的脚本加载完成后,JS引擎
通过DOM API
和CSSOM API
操作DOM树和CSSOM树。为何会产生渲染阻塞呢?其根本原因在于:JS操作DOM后,浏览器无法预测未来DOM的具体内容,为了防止无效操作和节省资源,只能阻塞DOM树的构建。
浏览器的渲染引擎
将DOM树和CSSOM树合并生成渲染树,只渲染需显示的节点及其样式。DOM树 、CSSOM树 和渲染树 三者的构建并无先后条件
和先后顺序
,并非完全独立而是会有交叉并行构建的情况。因此会形成一边加载,一边解析,一边渲染的工作现象。
绘制图层
进入绘制阶段,遍历渲染树,调用渲染器的paint()
在屏幕上绘制内容。根据渲染树布局计算样式,即每个节点在页面中的布局、尺寸等几何属性。HTML默认是流式布局,CSS和JS会打破这种布局,改变DOM的几何属性和外观属性。在绘制过程中,根据渲染树布局,再根据布局绘制,这就是常听常说的回流重绘。
在此涉及到两个核心概念:回流 、重绘。
- 回流:几何属性需改变的渲染
- 重绘:更改外观属性而不影响几何属性的渲染
当生成渲染树后,至少会渲染一次。在后续交互过程中,还会不断地重新渲染。这时有回流、重绘
或只有重绘
。因此引出一个定向法则:回流必定引发重绘,重绘不一定引发回流。
合成图层
将回流重绘生成的图层逐张合并并显示在屏幕上。上述几个步骤并不是一次性顺序完成的,若DOM或CSSOM被修改,上述过程会被重复执行。实际上,CSS和JS往往会多次修改DOM或CSSOM,简单来说就是用户的交互操作引发了网页的重渲染。
磨平浏览器默认样式
每个浏览器的CSS默认样式不尽相同,所以最简单最有效的方法就是对其默认样式初始化
。以下贴一个各位同学都会的初始化代码。简单暴力但是不明确,*
通配符可是有执行性能问题的。
plain
* {
margin: 0;
padding: 0;
}
推荐一种磨平浏览器默认样式的方法
- normalize.css:懒人必备的浏览器默认样式库,接近
40k
的Star,说明大部分人都是懒人
插入浏览器私有属性
通常编写CSS都会在一些CSS3属性前加入-webkit-
、-moz-
、-ms-
或-o-
,这些奇形怪状写到手软的东西就是浏览器私有属性。样式少还好,样式多那就欲哭无泪了😂。
出现这些私有属性,是因为制定CSS标准的W3C其动作就像蜗牛一样慢,量产一个CSS属性是需走一个很严格很复杂的流程。一个成熟且被大众肯定的属性,浏览器厂商会加大其支持力度而铺路,但是为了避免日后W3C公布标准时有所变更,就加入一个本厂商的私有属性提前支持该属性,待W3C公布该属性标准后,再让新版浏览器支持标准属性。
对于编写私有属性的顺序需特别注意:兼容性写法放到前面,标准写法放到最后。在浏览器解析CSS过程中,若标准属性无法使用则使用当前浏览器对应的私有属性。
plain
/* Chrome、Safari、New Opera、New Edge */
-webkit-transform: translate(10px, 10px);
/* Firefox */
-moz-transform: translate(10px, 10px);
/* IExplorer、Old Edge */
-ms-transform: translate(10px, 10px);
/* Old Opera */
-o-transform: translate(10px, 10px);
/* 标准 */
transform: translate(10px, 10px);
当然不是所有的CSS3属性都需补齐-webkit-
、-moz-
、-ms-
或-o-
,上述Demo只是一个示例,真正的transform
私有属性只有-webkit-
和-ms-
。这些需查看Caniuse
确保正确的编写,若想偷懒也可全部写上。
查看浏览器版本
window.navigator.userAgent