常规流之行内级格式化上下文(Inline Formatting Contexts)
本节我们来讨论一下Inline formatting contexts(行内格式化上下文,以下简称IFC)和line box(行框)。
一、行框
在一个行内格式化上下文中,框会一个接一个的水平放置,从包含块的顶部开始。这些框水平方向的margin、border以及padding属性是会起作用的。这些框在垂直方向上的对齐方式可以不一样:可以顶部或底部对齐,或根据其中文字的基线对齐。包含这些框的矩形区域,会形成一行叫做行框(line box)的东西。
一个行框的宽度由它的包含块和和其中的浮动元素来决定。高度的计算相对来说要比较复杂,大家可以去这个地方看看http://www.w3.org/TR/CSS2/visudet.html#line-height,或者之后有机会在可视化格式模型的细节中和大家再一起探讨。
二、行框的边界
1.行框的宽度
通常,行框的左边接触到其包含块的左边,右边接触到其包含块的右边。但是包含块中的浮动元素可能会处于包含块边缘和行框的边缘之间。来看一个例子:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> *{margin:0; padding: 0;} </style> </head> <body> <p style="background-color:silver; width:500px;overflow:hidden; text-align:center;"> <span style="border:1px solid blue; font-size:50px; float:left;">FLOAT</span><em style="border:1px solid yellow; font-size:30px;">great1</em><span style="border:1px solid yellow;">good</span> </p> </body> </html>dom
运行结果如下:
由于float的存在,行框的宽度被压缩了。
2.行内框的超出行框的宽度时
当一个行内框超出了行框的宽度时,它会被分割成几个框,而且这几个框会分散在几个行框中。如果一个行内框不能被分割时(如行内框只包含一个字符或者有特殊的word-break设置或者white-space属性值为nowrap或pre时),行内框会溢出行框。
如果一个行内框被分割,margin、padding 和 border 在所有分割处没有视觉效果。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>split inline box</title> <style> *{margin: 0; padding: 0} p{ margin: 20px 50px;} </style> </head> <body> <p style="background-color:silver; width:100px; "> <span style="border:1px solid blue; font-size:50px;">text in span</span> <em style="border:1px solid yellow; font-size:30px; vertical-align:top;">great1</em> </p> <p style="background-color:silver; width:100px; "> <span style="border:1px solid blue; font-size:50px; white-space:nowrap">text in span</span> <em style="border:1px solid yellow; font-size:30px; vertical-align:top;">great1</em> </p> </body> </html>
运行结果如下:
第一个p中由于包含块的宽度p只有100px,第一个span形成的行内框被分割成了3段,分别在不同的行框中;
第二个p中同样包含块只有100px的宽度,但是span多了一个white-space:nowrap的样式,span形成的行内框没有被分割,溢出了行框。
不包含文本,保留空白符,margin/padding/border 非0的行内元素,以及其他常规流中的内容(比如,图片,inline blocks 和 inline tables), 并且不是以换行结束的行框,必须被当作零高度行框对待。
三、行内框的对齐
1.垂直方向上的对齐
行框的高度总是足够容纳所包含的所有框。不过,它可能高于它包含的最高的框(例如,框对齐会引起基线对齐)。 当一个框 B 的高度小于包含它的行框的高度时,B 在行框中垂直方向上的对齐决定于 'vertical-align'属性。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vertical-align</title> <style> *{margin: 0; padding: 0;} p{ margin: 20px 40px;} </style> </head> <body> <p style="background-color:silver; width:500px; "> <span style="border:1px solid blue; font-size:50px;">text in span</span> <em style="border:1px solid yellow; font-size:30px; vertical-align:top;">top</em> </p> <p style="background-color:silver; width:500px; "> <span style="border:1px solid blue; font-size:50px;">text in span</span> <em style="border:1px solid yellow; font-size:30px; vertical-align:baseline;">baseline</em> </p> <p style="background-color:silver; width:500px; "> <span style="border:1px solid blue; font-size:50px;">text in span</span> <em style="border:1px solid yellow; font-size:30px; vertical-align:bottom;">bottom</em> </p> <p style="background-color:silver; width:500px; "> <span style="border:1px solid blue; font-size:50px;">text in span</span> <em style="border:1px solid yellow; font-size:30px; vertical-align:text-bottom;">text-bottom</em> </p> </body> </html>
没有列举所有的属性,大家可以自己去跑跑看,也可以感受下蛋疼的兼容性问题。
vertical-align实在是一个很复杂的属性,这里不是我们这次的重点,大家有兴趣的话可以去张鑫旭的博客看看:我对css-vertical-align的一些理解与认识(一)。
2.水平方向上的对齐
当一行中行内框宽度的总和小于包含它们的行框的宽,它们在水平方向上的对齐,取决于 'text-align' 特性。 如果其值是 'justify',用户端也可以拉伸行内框(除了 'inline-table' 和 'inline-block' 框)中的空间和文字 。
四、总结
行框这个东西在做页面的时候我们经常会和它打交道。本文只是一个大概的概述,其实很多细节比如line-height高度的计算啊、vertical-align的属性啊都可以展开深入的去讲,还涉及到很多兼容性的问题以及很多实际的应用,如果都摊开写就太多了,以后有机会会和大家做更深入烦人探讨。本人能力有限,文章各处难免会有错漏,还请大家多多指正。
参考资料: