重学前端
程劭非(winter)
前手机淘宝前端负责人
立即订阅
32956 人已学习
课程目录
已完结 58 讲
0/4登录后,你可以任选4讲全文学习。
开篇词+学习路线+架构图 (3讲)
开篇词 | 从今天起,重新理解前端
免费
明确你的前端学习路线与方法
列一份前端知识架构图
模块一:JavaScript (15讲)
JavaScript类型:关于类型,有哪些你不知道的细节?
JavaScript对象:面向对象还是基于对象?
JavaScript对象:我们真的需要模拟类吗?
JavaScript对象:你知道全部的对象分类吗?
JavaScript执行(一):Promise里的代码为什么比setTimeout先执行?
JavaScript执行(二):闭包和执行上下文到底是怎么回事?
JavaScript执行(三):你知道现在有多少种函数吗?
JavaScript执行(四):try里面放return,finally还会执行吗?
JavaScript词法:为什么12.toString会报错?
(小实验)理解编译原理:一个四则运算的解释器
JavaScript语法(预备篇):到底要不要写分号呢?
JavaScript语法(一):在script标签写export为什么会抛错?
JavaScript语法(二):你知道哪些JavaScript语句?
JavaScript语法(三):什么是表达式语句?
JavaScript语法(四):新加入的**运算符,哪里有些不一样呢?
模块二:HTML和CSS (16讲)
HTML语义:div和span不是够用了吗?
HTML语义:如何运用语义类标签来呈现Wiki网页?
CSS语法:除了属性和选择器,你还需要知道这些带@的规则
HTML元信息类标签:你知道head里一共能写哪几种标签吗?
CSS 选择器:如何选中svg里的a元素?
CSS选择器:伪元素是怎么回事儿?
HTML链接:除了a标签,还有哪些标签叫链接?
CSS排版:从毕升开始,我们就开始用正常流了
HTML替换型元素:为什么link一个CSS要用href,而引入js要用src呢?
HTML小实验:用代码分析HTML标准
CSS Flex排版:为什么垂直居中这么难?
CSS动画与交互:为什么动画要用贝塞尔曲线这么奇怪的东西?
HTML语言:DTD到底是什么?
CSS渲染:CSS是如何绘制颜色的?
CSS小实验:动手做,用代码挖掘CSS属性
HTML·ARIA:可访问性是只给盲人用的特性么?
模块三:浏览器实现原理与API (9讲)
浏览器:一个浏览器是如何工作的?(阶段一)
浏览器:一个浏览器是如何工作的?(阶段二)
浏览器:一个浏览器是如何工作的(阶段三)
浏览器:一个浏览器是如何工作的?(阶段四)
浏览器:一个浏览器是如何工作的?(阶段五)
浏览器DOM:你知道HTML的节点有哪几种吗?
浏览器CSSOM:如何获取一个元素的准确位置
浏览器事件:为什么会有捕获过程和冒泡过程?
浏览器API(小实验):动手整理全部API
模块四:前端综合应用 (5讲)
性能:前端的性能到底对业务数据有多大的影响?
工具链:什么样的工具链才能提升团队效率?
持续集成:几十个前端一起工作,如何保证工作质量?
搭建系统:大量的低价值需求应该如何应对?
前端架构:前端架构有哪些核心问题?
特别加餐 (9讲)
新年彩蛋 | 2019,有哪些前端技术值得关注?
用户故事 | 那些你与“重学前端”的不解之缘
期中答疑 | name(){}与name: function() {},两种写法有什么区别吗?
答疑加餐 | 学了这么多前端的“小众”知识,到底对我有什么帮助?
加餐 | 前端与图形学
加餐 | 前端交互基础设施的建设
期末答疑(一):前端代码单元测试怎么做?
期末答疑(二):前端架构中,每个逻辑页面如何可以做到独立发布呢?
加餐 | 一个前端工程师到底需要掌握哪些技能?
尾声 (1讲)
尾声 | 长风破浪会有时,直挂云帆济沧海
重学前端
登录|注册

浏览器:一个浏览器是如何工作的(阶段三)

winter 2019-02-14
你好,我是 winter。
在上一节课中,我已经讲了浏览器的 DOM 构建过程,但是这个构建的 DOM,实际上信息是不全的,它只有节点和属性,不包含任何的样式信息。
我们这一节课就来讲讲:浏览器是如何把 CSS 规则应用到节点上,并给这棵朴素的 DOM 树添加上 CSS 属性的。

整体过程

首先我们还是要感性地理解一下这个过程。
首先 CSS 选择器这个名称,可能会给你带来一定的误解,觉得好像 CSS 规则是 DOM 树构建好了以后,再进行选择并给它添加样式的。实际上,这个过程并不是这样的。
我们回忆一下我们在浏览器第一节课讲的内容,浏览器会尽量流式处理整个过程。我们上一节课构建 DOM 的过程是:从父到子,从先到后,一个一个节点构造,并且挂载到 DOM 树上的,那么这个过程中,我们是否能同步把 CSS 属性计算出来呢?
答案是肯定的。
在这个过程中,我们依次拿到上一步构造好的元素,去检查它匹配到了哪些规则,再根据规则的优先级,做覆盖和调整。所以,从这个角度看,所谓的选择器,应该被理解成“匹配器”才更合适。
我在 CSS 语法部分,已经总结了选择器的各种符号,这里再把它列出来,我们回顾一下。
空格: 后代,选中它的子节点和所有子节点的后代节点。
>: 子代,选中它的子节点。
+:直接后继选择器,选中它的下一个相邻节点。
~:后继,选中它之后所有的相邻节点。
||:列,选中表格中的一列。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《重学前端》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(34)

  • coma
    之前选择器是从右往左匹配,好像跟这里的说法不一致,是理解错了吗?
    2019-02-14
    65
  • 以勒
    css的渲染过程:
    1. 流式渲染,每生成一个dom节点,便立刻去匹配相应的css规则

    2. dom节点的生成顺序是 从父-> 子。 css的渲染顺序也是 从 父节点-》子节点

    3.混合选择器 在激活的时候父元素已经确定好了 。 后代选择器,所有元素都是父元素,并 选中自己的子元素。 子元素 选择器,只有父元素为当前节点的 dom 元素会被选中。 在父元素 结束标签时,关闭 选择器。

    2019-02-14
    17
  • 啊柴
    老师好,文中后代选择器是说先检查父级,匹配后再检查子级,以前学习看到比较多的一种说法是从关键选择器开始匹配,然后左移查找选择器的祖先元素,实践中也一直把最后一个选择器权重加高。请问这是从开始就学错了,还是我对两种说法理解有偏差呢?

    作者回复: 浏览器编写本身有不同的思路,但是按关键选择器这个思路,据我所知还没有实现。

    2019-02-14
    15
  • 南半边翅膀
    dom树构建与cssom构建有先后关系吗?css计算与dom树流式构建同步进行是不是意味着dom树流式构建之前cssom已经构建完成呢?
    2019-02-14
    14
  • 一步
    老师,对于这个问题,我也有疑问:
    dom树构建与cssom构建有先后关系吗?css计算与dom树流式构建同步进行是不是意味着dom树流式构建之前cssom已经构建完成呢?

    作者回复: 我这里说的确实有点歧义,cssom是有rule部分和view部分的,rule部分是在dom开始之前就构件完成的,而view部分是跟着dom同步构建的。

    2019-03-01
    7
  • flow
    请问DOM去匹配css rule的时候是不是必须先等页面的css都下载完成后才会去匹配的?否则如果DOM匹配的时候对应的css还没下载完,后面怎么得到正确的css?

    作者回复: head中的css是要下载完的,body中放CSS的话,会重新计算。

    2019-02-16
    2
    6
  • 嗯喊我杰哥
    <也就是说,未来也不可能会出现“父元素选择器”这种东西,
    因为父元素选择器要求根据当前节点的子节点,来判断当前节点是否被选中,而父节点会先于子节点构建。>

    这句话后半句好难理解,有大神能通俗地解释一下吗

    作者回复: 意思是DOM树构造到父节点的时候,还不知道它有没有子节点,所以算不出来CSS。

    2019-02-14
    6
  • 乃乎
    CSS 没有父选择器那里讲得太好了,这个原因不能更合理

    作者回复: 其实Selector Level 4里面已经打破这个规则了,现在还是draft,也不知道最后能不能过。

    要是真过了 webkit这块差不多得重写……

    2019-02-26
    5
  • CC
    第一反应猜测 CSS 语法应该解析成对象(Object),然后根据 DOM 的树形结构,CSS 也会生成自己的树形结构。

    查找验证后发现,这被称为 CSSOM(CSS Object Model)。

    举个 CSSOM 的例子:

    body {font-size: 16px;}
    h1 {font-size: 2rem;}
    .orange {color: orange;}
    div {margin: 1rem 0;}
    div p {padding-bottom: 1rem;}

    从根结点 body 开始,树形结构如下:

    * body {font-size: 16px;}
        * h1 {font-size: 2rem;}
        * .orange {color: orange;}
        * div {margin: 1rem 0;}
            * div p {padding-bottom: 1rem;}

    不知道这样理解是否准确?

    作者回复: 哈哈 CSSOM不是这样子的,CSSOM主要是DOM结构上的盒的描述,它基本上是依附于DOM树的。

    你说的这个东西,比较接近的是CSS的语法树。

    2019-02-14
    4
  • 🐻🔫🐸
    我发现关于CSS选择从右到左开始匹配的理论网上还是有很多相关资料的,https://www.sitepoint.com/optimizing-css-id-selectors-and-other-myths/
    看起来应该还是有点道理?不过这个东西浏览器引擎应该也会不断优化,不同版本不同引擎都可能有差异
    2019-03-07
    3
  • Dylan-Tseng
    请问老师,有一点不是很明白,如果是在构建dom树的同时,就开始构建css,带空格选择子元素的时候,css怎么知道dom树有没有构建完成,是否有没有子元素,是怎么做匹配的?

    作者回复: 并不管有没有子元素,只是让这条规则前进一格。

    2019-02-20
    2
  • flow
    看到老师一个分享会的视频,说到DOM匹配css rule的时候是从右往左匹配的,为什么跟文章提到的后代选择器的匹配顺序相反呢?

    作者回复: 哈哈,是这样的没错,但是你看,新加了这么多运算符,所以思路也会有不一样。

    其实浏览器实现是比较懒的,直接每条规则都检查了,没做合并优化。

    2019-02-16
    2
  • Jaykey
    空格,和后代选择器有什么不一样吗?
    2019-06-19
    1
    1
  • Young!
    老师,请问一下您说的「后退,前进」的含义,不太理解

    a#b .cls 这个选择器中,分成 a#b 和 .cls ,当 DOM 树构造到 <a id=b> 这个节点时,css 匹配 a#b,并且「前进」看是否自带是否有 class="cls" 的元素,这里可能会有指针这个抽象,指向 .cls,当 DOM 树构建到 </a> 这里时,css 选择器指针「后退」到 a#b 这里,然后继续构造 DOM 树,而且这个选择器已经被构造所谓的 css 树之类的,只是指针会有回退和前进的时候

    可以这样理解吗

    2019-03-13
    1
  • 啊咩
    || 列选择器 是最新的标准出的吗? 我在w3school和 菜鸟教程 都找不到这个选择器

    作者回复: Selector Level 3里的,不过不太重要,不用太在意。

    2019-02-22
    1
  • 胡永
    css选择器这里面最重要的一条规则就是没有父选择器,根据流式处理的dom规则,这样就节省了很多的重新计算
    2019-09-04
  • 令狐洋葱
    老师,DOM 和 CSSOM 都是流式构建的,按照您的讲解,我理解是 CSSOM 必须先解析好,才能和 DOM 做样式上的融合,然后流式绘制已经解析好的 DOM,单纯HTML的解析我认为时间是可以忽略不计的,遇到 script 标签才会导致 DOM 解析有停顿,这时候页面才会做渲染,所以我理解上的流式渲染是分批的,遇到 js 就立即渲染之前融合好的布局,不知道这样理解流式渲染是否正确?
    还望老师指正,谢谢。

    作者回复: 不是分批的,也跟JS无关。

    2019-05-30
  • 小王
    处理后退的情况那里没太理解,当找到匹配了a#b的元素才开始检查它的所有子代是否匹配.cls。那第三个span节点不是a#b元素的子节点,它本身就不会被选中的。为什么文中提到“必须使得规则a#b .cls回退一步,这样第三个span才不会被选中”
    2019-05-08
  • 关山楂
    我还是比较认同,从左往右匹配的规则,这样就像老师讲的可以在构建dom树的同时来进行匹配css规则,相当于同时构建渲染树了,而不必等到dom构建完毕在进行css的规则匹配,进行构建渲染树,虽然从右向左匹配对于复杂的选择器更优,但是这里面浪费了等待dom构建完毕才能使用的css匹配规则。而且相对于同为id等单一选择器而言,明显从左向右更具有优势!这是我的一点想法,望老师指正!
    2019-05-08
  • KB24_钱昊
    程老师你好。我在很多地方看到的说法是:CSS会阻塞dom渲染,但不会阻塞dom的解析,且CSS文件的请求是异步请求。
    那么如果按照上面文章中所说,DOM的构建和CSS属性的计算是同步的话,head中CSS文件的下载以及CSSOM的rule部分的构建应该会阻塞HTML的解析和DOM的构建。
    好像这两种说法之间就有了冲突。。麻烦程老师有空的时候可以帮忙解释一下,万分感谢~
    2019-05-07
收起评论
34
返回
顶部