在之前的文章《CSS格式化上下文之BFC》我们阐述了可视化格式模型(盒子模型)和排版上下文,这两个规范和标准的相关概念,并细说了下块级格式化上下文(BFC)的一些概念和实际应用场景。在上篇文章中我们知道在页面普通流中,不同类型的盒子,会参与不同的FC,块级盒子会参与BFC,行级盒子会参与IFC,在这次我们就来说说IFC(Inline Formatting Context 行级格式化上下文)
1,inline-level box (行级盒子)
与块级盒子相对应的就是行级盒子,行级盒子和块级盒子结构一致,只是在基础盒子模型基础上有自身的一些特性。比如行级盒子的width是由子行级盒子(content-box)的外宽度(margin+border+padding+content width)决定的,直接定义width是没有效果的。
一个元素会对应0~N个box(display为None,则对应0个box),根据display属性的值,元素会对应不同的controlling box(inline-level box 和block-level box均是controlling box的子类)。CSS2中display为inline|inline-block|inline-table|table-cell|table-column-group的元素对应的盒子就是inline-level。
行级盒子在包含块里是从左到右水平排列的,这个和块级盒子不一样,但是这里实际上还涉及到一个隐含的概念line-box,line-box也在排版中也是垂直排列的。
总结:
inline-level box的结构和block-level box基本一致。
content box的高度仅能通过font-size来进行设置,content box的宽度则自适应其内容而无法通过设置width来进行控制。
当inline-level box的宽度大雨包含块的宽度且达到换行条件时,会将inline-level box拆分成多个inline-level box并分布到多行中,然后当属性direction为ltr时,margin/border/padding-left将作用于第一个inline-level box,margin/border/padding-right将作用于最后一个inline-level box,如果direction为rtl,效果则相反。
2,line box(行盒子)
line box 是一个看不到摸不着的边框,但是每一行所占的高度实际上是line box的高度,而不是Inline-level box的高度。
2.1,line box的特点
同一行的line-level box属于同一个 line box
line box的高度的计算方式是结合line-height和vertical-align属性来计算的。
eg:
1. 根据规则,span.parent所在行的line box的高度受span.parent、span.child、span.inline-block元素对应的inline-level box”高度”的影响。其中span.parent的”高度”为其line-height实际值,span.child的”高度”为其line-height实际值,而span.inline-block的”高度”为其margin box的高度。由于设置line-height:1,因此span.parent和span.child的content box高度等于line-height实际值;
2. 根据vertical-align属性垂直对齐,造成各“高度”间并不以上边界或下边界对齐;
3. span.inline-block红色的上边框(border top)到span.child蓝色的下边框(border bottom)的距离再减去1px即为line box的高度。(line box的下界其实是span.child的content box的下限的)
总结:
inline-level box的排版单元不是其身而是line box,重点在于line-height的计算。
位于改行上所有的normal-flow的inline-level box均参与到line-heigh高度的计算。
replaced elements、Inline-block elements、inline-table elements将以其对应的不透明的margin box参与到line box的计算,而其他的inline-level box的高度则以line-height的实际值参与到line-height的计算。
各inline-level box根据vertical-align属性值相对应各自的父容器垂直方向进行对其。
最上方的box的上边界到最下方的box的下边界的差值就是line box的高度。
3,IFC的形成
在可视化模型中,元素形成的盒子,会参与到格式化上下文中(初始化大小、布局、排版),不同类型的盒子参与不同的FC,且只能参与到一种FC,行级盒子会参与IFC。
4,IFC的特性
1,inline-level box会从包含块的顶部开始,一个接一个地水平摆放。
2,摆放这些inline-level box的时候,它们在水平方向上的外边距、边框、内边距所占用的空间都会被考虑在内。在垂直方向上,这些框可能会以不同形式来对齐:它们可能会把底部或顶部对齐,也可能把其内部的文本基线对齐。能把在一行上的inline level box都完全包含进去的一个矩形区域,被称为该行的行盒(line-box), 如果一个line box 不够 则会有形成多个line box(换行)。水平的margin、padding、border有效,垂直无效,不能指定宽高。
3,Inline-level box的宽度是由包含块和存在的浮动来决定,Inline-level box一定会高到足以容纳它所包含的全部inline-level box。但是,它也可能比它所包含的最高的框还要高。
4,Inline-level box的左边紧贴其包含块的左边,而行框的右边紧贴其包含块的右边。然而,浮动框可以插在包含块边缘与行框边缘之间。因此,尽管在同一个IFC中的inline-level box通常有同样的宽度(也就是其包含块的宽度),但它们的宽度也可能受浮动让水平可用空间减少的影响而有所改变。在同一个IFC中,inline-level box的高度通常是变化的(例如:某一行包含了一个比较高的图片,而其它行只包含文本)。
5,当一行上的inline-level box的总宽度小于包含它们的inline-level box的宽度,则它们在inline-level box内的水平分布由’text-align’属性来决定。
6,当一个inline-level box的宽度超过了line box的宽度,line box会被分割成几个,而这些inline-level box会分布在几个line box。如果此line-level box不可分割(例如:单个字符、或语言指定的文字打断规则不允许在此inline-level box中出现打断、或该inline-level box受 white-space 属性为 nowrap或 pre 的影响),那么该inline-level box溢出该line box。
7,line box被分割的时候,外边距、边框和内边距在出现分割的地方都没有视觉效果。
**行高计算 ― ‘line-height’ 与 ‘vertical-align’ 属性**
计算line box里的各inline-level box的高度。对于置换元素、行内块元素、行内表格元素来说,这是边界框的高度,对于行内框来说,这是其 ‘line-height’。
行内级元素根据其 ‘vertical-align’ 属性垂直对齐。
line box的高是最顶端inline-level box的顶边到最底端line-level box的底边的距离。
8,同个ifc下的多个line box高度会不同
备注:inline-level box 不能包含 bloc-level box,如果将块级元素放到行级元素中,如span中插入div,则会形成独特的IFC与div区隔开来,对外表现为BFC,与div垂直排列。
参考借鉴网文,错误遗落未言明之处,敬请谅解。