CSS定位机制之一:普通流
原创。原文:http://www.swordair.com/blog/2010/08/415,转载请保留。
由于没有找到自己认为完整的关于普通流、浮动和绝对定位的中文文章,于是鼓起勇气决定自己来写篇。为此大致啃掉了CSS2.1里的 8 Box model 以及 9 Visual formatting model 。实话说,还真是看得有点头大,呵呵~
文档流,其实标准里根本就没有这个词。如果把文档流直译为英文就是 document flow ,但标准里只有另一个词,叫做普通流( normal flow ),或者称为常规流。但似乎大家更习惯文档流的称呼,因为很多中文翻译的书就是这么来的。比如《CSS Mastery》,英文原书中至始至终都只有普通流 normal flow 这一词,从来没出现过文档流 document flow 。但是中文译本“普通流”和“文档流”却是交替出现的。
什么是普通流?简单说就是元素按照其在 HTML 中的位置顺序决定排布的过程。并且这种过程遵循标准的描述。
为了从不同角度说明,我采集了一些可能冗长、具体或者晦涩的其他人给出的定义:
将窗体自上而下分成一行行,并在每行中按从左至右的顺序排放元素,即为文档流。 Jennifer.Kyrnin@About.com: 普通流是元素在多数情况下呈现在 web 页面上的方式。所有 HTML 都在块框( block boxes,块级元素 )或者行内框( inline boxes,行内元素 )中。 Rainbo Design: 当浏览器开始渲染 HTML 文档,它从窗口的顶端开始,经过整个文档内容的过程中,分配元素需要的空间。除非文档的尺寸被 CSS 特别的限定,否则浏览器垂直扩展文档来容纳全部的内容。每个新的块级元素渲染为新行。行内元素则按照顺序被水平渲染直到当前行遇到了边界,然后换到下一行垂直渲染。这个过程被成为普通文档流。可见,把流( flow )理解为流程,完全说的通。普通流即是通常情况下的元素排布和定位流程。
但其实在CSS2.1RC里,普通流的本质是三种定位机制( Positioning schemes )之一,被定义为:
引用:
??????????? <div id="B" style="margin-top:10px;">
??????????????? 我有10px m-t
??????????? </div>
??????? </div>
??? </body>
</html>
如果在现代的浏览器里运行,那么 B 的10px上边距将会和父元素 A 的20px上边距重叠起来,从而看起来就好像 B 没有上边距一样。就像前面说的那样,同一个 block formatting context 中的垂直边界将被重叠。那么不同 block formatting context 呢?
这种情况,如果不想加边框( border:1px solid transparent; )解决的话,那么就需要 A 建立一个新的 block formatting context 将 B 包裹起来,那么 A 的上边距和 B 的上边距就毫不相干了。可以用浮动,也可以加 overflow ,这要看具体情况。
代码:
??????????? <div id="B" style="margin-top:10px;">
??????????????? 我有10px m-t
??????????? </div>
??????? </div>
??? </body>
</html>
再一个例子,回头看下上面过程里这样的一句:除非创建一个新的 block formatting context ,否则块级元素的布局不受浮动元素的影响。
这是造成元素重叠的原因。比如下面的代码:
代码:
??????????? <div id="B" style="background:green;margin:10px 10px 0 0;float:right;">
??????????????? 浮动元素m_10_10_0_0
??????????? </div>
??????????? <div id="C" style="background:red;">
??????????????? 普通流块
??????????? </div>
??????? </div>
??? </body>
</html>
普通流块 C 在容器 A 里排布的时候,并不受浮动元素的影响,甚至当浮动元素 B 不存在。但是如果 C 创建了新的 block formatting context ,那么,普通流块c就会像 line box 一样受到浮动元素存在的影响而缩小。
代码:
??????????? <div id="B" style="background:green;margin:10px 10px 0 0;float:right;">
??????????????? 浮动元素m_10_10_0_0
??????????? </div>
??????????? <div id="C" style="background:red;overflow:auto;">
??????????????? 普通流块
??????????? </div>
??????? </div>
??? </body>
</html>
关于浮动和 block formatting context ,brunildo.org 上有一份不错的参考。
说了这么多了,其实概念仍然可以很简单。普通流仅仅只是一种定位的机制。而flow本身在标准里也可以作为一个动词,就如同按顺序一个个的拿出HTML元素然后放到页面上一般。只是要注意一下 formatting context 的概念,特别是 block formatting context ,因为其影响更大(包括边距重叠、浮动清除、元素重叠等)。
写到这里也就差不多了,由于水平所限,如文中有不当之处,请指点下,非常感谢。谢谢阅读