根据对前三步的认识,在构建 render 树的过程,浏览器都是以单个节点为单位产出元素的。在排版的过程很难达到这么独立,很多排版都会有千丝万缕的联系,尤其是 Flex 和 Grid 排版,子元素之间互相关联互相影响。
排版方式
-
正常流排版: 浏览器基本的排版方案,这种排版方式是由上往下的顺次排布和折行等规则。
在正常流的基础上,浏览器还支持元素的两种定位:- 绝对定位:绝对定位元素由 position 属性控制。绝对定位元素把自身从正常流抽出,直接由 top 和 left 等属性确定自身的位置,不参加排版计算,也不影响其它元素。
- 浮动:浮动元素由 float 属性控制,浮动元素则是使得自己在正常流的位置向左或者向右移动到边界,并且占据一块排版空间。
-
盒模型: 每个元素都被定义为一个类似盒子一样的占具一定位置的区域,由边框、边距、留白组成,浏览器还支持元素和文字的混排。
-
其他排版:这些排版方式由外部元素的 display 属性来控制,比如当前流行的 Flex。
-
文字排版:行模型有点类似于小时候写作业的英文薄,它规定了行顶、行底、文字区域、基线等对齐方式。浏览器还支持不同语言,通常不同语言的书写顺序也不一致,所以浏览器支持多种语言排版。
-
正常流文字排版:这是唯一一个文字和盒混排的排版方式,我们先从文字来讲起:
浏览器从人们日常书写习惯得到启发,浏览器的排版也很类似,浏览器还支持改变排版方向,所以主轴、主方向、辅轴、延伸方向的概念随之而来。
横向版本:
横向纵向版本:
纵向其中是字体中最重要的属性,它代表每一个排布后的文字在主轴上的前进距离,跟普通的宽、高不相等。
字体的排版还会收到 的影响:letter-spacing、line-height、word-spacing 等等。
在正常流的文字排版里,绝大部分元素都被当作盒子来排版,只有少数 display 为 inline 的元素被当作文本来排版,它们会被直接排入文字流中,这类元素的主轴方向的 margin 和 border 属性会被计算进上面提到的 advance 里。
有一种特殊情况是当没有指定文字书写方向的时候,往左到右的文字里插入右到左的文字会形成双向文字盒,简单来说就是不指定文字书写方向,往文字里插入与之相反方向的文字会形成双向文字盒。这种盒子的排版方式会先排盒内再排盒外。
- 正常流盒排版:display 不为 inline 的元素或者伪元素,会以盒子的身份跟文字一同排版,带 inline- 前缀的也不例外。
盒子模型主轴方向占据的空间由 width/height 、padding、border、margin 等属性决定,盒子在交叉轴的位置由 vertical-align 属性决定,也会影响盒子的行高。
所以,浏览器在排版行的时候,一般会先进行内布局,再确定行的位置,根据行的位置计算出行内盒和文字的排版位置。
块元素排版比较简单,单个元素占一行,对它进行排版只要计算出交叉轴方向的高度。
- 正常流浮动元素排版:
浏览器会将带有 float 属性的元素排入正常流,再根据 float 移动到排版方向的最左/最右。float 也会占据排版空间,所以会影响数行内其他已经排好版的元素,所以被影响行的其他元素需要重新确定位置。
其他排版:
-
绝对定位元素排版:
浏览器在对绝对定位元素排版的时候,会使它们脱离正常流,需要向外逐层找到 position 不为 static 的元素来确定它们的位置。 -
Flex 排版:
CSS 的每一种排版都有一个很复杂的规定,实际实现形式也各不相同。比如如 Flex 排版,支持了 flex 属性,flex 属性将每一行排版后的剩余空间平均分配给主轴方向的 width/height 属性。浏览器支持的每一种排版方式,都是按照对应的标准来实现的。
END......我是个有底线的家伙......END
网友评论