重学前端 - 浏览器部分-工作流程-排版

概述

书接上文。浏览器进行到这一步,我们已经给 DOM 元素添加了用于展现的 CSS 属性,接下来,浏览器的工作就是确定每一个元素的位置,进入“排版”流程了。

在现代浏览器中,仍然借用了这个概念,但是排版的内容更加复杂,包括文字、图片、图形、表格等等,我们把浏览器确定它们位置的过程,叫作排版。

正常流文字排版

浏览器最基本的排版方案是正常流排版,它包含了顺次排布和折行等规则,这是一个跟我们提到的印刷排版类似的排版方案,也跟我们平时书写文字的方式一致,所以我们把它叫做正常流。在正常流的文字排版中,多数元素被当作长方形盒来排版,而只有 display 为 inline 的元素,是被拆成文本来排版的。

在正常流中,display 不为 inline 的元素或者伪元素,会以盒的形式跟文字一起排版。多数 display 属性都可以分成两部分:内部的排版和是否 inline,带有 inline- 前缀的盒,被称作行内级盒。

根据盒模型,一个盒具有 margin、border、padding、width/height 等属性,它在主轴方向占据的空间是由对应方向的这几个属性之和决定的,而 vertical-align 属性决定了盒在交叉轴方向的位置,同时也会影响实际行高。

所以,浏览器对行的排版,一般是先行内布局,再确定行的位置,根据行的位置计算出行内盒和文字的排版位置。

块级盒比较简单,它总是单独占据一整行,计算出交叉轴方向的高度即可。

绝对定位元素

position 属性为 absolute 的元素,我们需要根据它的包含块来确定位置,这是完全跟正常流无关的一种独立排版模式,逐层找到其父级的 position 非 static 元素即可。

浮动元素排版

float 元素非常特别,浏览器对 float 的处理是先排入正常流,再移动到排版宽度的最左 / 最右(这里实际上是主轴的最前和最后)。

移动之后,float 元素占据了一块排版的空间,因此,在数行之内,主轴方向的排版距离发生了变化,直到交叉轴方向的尺寸超过了浮动元素的交叉轴尺寸范围,主轴排版尺寸才会恢复。
float 元素排布完成后,float 元素所在的行需要重新确定位置。

其它的排版

CSS 的每一种排版都有一个很复杂的规定,实际实现形式也各不相同。比如如 flex 排版,支持了 flex 属性,flex 属性将每一行排版后的剩余空间平均分配给主轴方向的 width/height 属性。浏览器支持的每一种排版方式,都是按照对应的标准来实现的

延伸阅读

文字排版的思路是“改变文字和盒的相对位置,把它放进特定的版面中”,软件界面的思路则是“改变盒的大小,使得它们的结构保持固定”。在早年的 CSS 中,“使盒按照外部尺寸变化”的能力非常弱。就出现了CSS 三大经典问题:垂直居中问题,两列等高问题,自适应宽问题。这是在其它 UI 系统中最为基本的问题,而到了 CSS 中,却变成了困扰工程师的三座大山。

flex 排版方式应运而生,这是一种典型的“根据外部容器决定内部尺寸”的思路,也是我们最常用的 Windows 和 Apple 窗口系统的设计思路,有了它,解决当年的 CSS 三大经典问题,便易如反掌(具体代码请参照35 | CSS Flex排版:为什么垂直居中这么难?)