Visual formatting model
參考
這個(gè)直譯為可視化格式模型,規(guī)定了文檔樹(shù)中的每個(gè)元素的布局
先解釋什么是Containing Box,Controlling Box generation,什么是xx-level element,什么是xx-level box
下文中的"我"是指一個(gè)元素
xx-level element and xx-level box
這個(gè)很好理解,就是我是什么級(jí)別的嗎
- block-level element
display為'block','list-item','table'的element被稱為block-level element - inline-level element
display為'inline','inline-table','inline-block被稱為inline-level element - block-level-box
每一個(gè)block-level element一般會(huì)生成一個(gè)block-level box,稱為主box,有些會(huì)生成不止一個(gè),比如display為list-item的元素,會(huì)生成額外的box,這些額外的box根據(jù)主box定位,block-level box會(huì)參與BFC - inline-level box
每一個(gè)inline-level element都會(huì)生成inline-level box,參與IFC
Controlling Box generation
這個(gè)我理解為生成何種類型的container box,
- block container box
block-level box會(huì)生成block container box,其實(shí)規(guī)范是說(shuō)
a block-level box is also a block container box
我還是覺(jué)得把他理解為生成更好,block container box也可以通過(guò)其他box生成,比如display為'inline-block'等等,block container box只能包含block-level boxes或者只生成IFC來(lái)包含inline-level boxes,如果盒子中即有inline-level boxes,又有block-level boxes,其實(shí)是為inline-level boxes生成了一個(gè)匿名的block box只用來(lái)生成IFC來(lái)包含inline-level boxes,block box是指即為block-level box,又生成了block container box
- inline container box
一個(gè)不可替換元素(比如p,div等等,img這種由src定的,input這種由value定的稱作可替換元素)display為'inline'會(huì)生成inline container box
注意規(guī)范中是沒(méi)有inline containing box這個(gè)詞的,只有'inline box'規(guī)范中說(shuō)
An inline box is one that is both inline-level and whose contents participate in its containing inline formatting context
為了更好理解我把這里的contents解釋為inline containing box's contents
inline container box可以包含inline-level box,如果inline container box中放入了block box,那么這個(gè)inline container box將會(huì)被打破,其中的內(nèi)容會(huì)分為三部分,兩個(gè)被隔開(kāi)的匿名inline box,和插入的block box,這時(shí)的第一個(gè)匿名inline box的inline container box就會(huì)成為原來(lái)的inline container box
比如這樣
<p style="border:1px solid #ccc; width:200px; padding:20px;">
我是P中的文字
<span style="border:1px solid #ccc; position:relative;color:#ccc">
我是匿名inline box
<em style="color:#000;position:absolute;bottom:0; left:0;">absulute</em>
<em style="display:block;height:40px ;color:green; top:0; left:0;">我是Block</em>
<em style="color:red; ">我是匿名inline box</em>
</span>
</p>
Containing Block
直譯為包含塊,是一個(gè)矩形區(qū)域,,決定了我在這個(gè)區(qū)域中的布局和大小等等
- 如果我的position為relative或者static,那么我所處的包含塊由距離我最近的祖先元素創(chuàng)建,包含塊的大小是祖先元素content box的大小
- 如果我的positon為absolute,我的包含塊由最近的position不為static的祖先元素創(chuàng)建,包含塊的大小為祖先元素的padding box的大小
- 如果最近的祖先元素的為inline box,那么,還是看圖吧
測(cè)試圖片
<p style="border:1px solid #ccc; width:200px; padding:20px;">
我是P中的字
<span style="border:1px solid #ccc; position:relative;color:#ccc">
我是字呀我是字,我是字呀我是字,我是字呀,我是字,我是字,我是字呀我是字,我是字呀我是字
<em style="position:absolute; color:green; top:0; left:0;">XX</em>
<em style="position:absolute; color:red; bottom:0; right:0;">XX</em>
</span>
</p>
還有這樣,那containing block只剩下了一條線
現(xiàn)在"我"是誰(shuí)(level),我能包含誰(shuí)(container box)差不多就明白了,接下來(lái)就要寫我是怎么被排布的了,有三種方式
- normal flow
常規(guī)流,常規(guī)流中的block-level box參與bfc,inline level box參與ifc
bfc(在css3中稱為flow root)
block formatting context,說(shuō)誰(shuí)觸發(fā)了bfc就是給自己生成的的container box加了一個(gè)標(biāo)簽bfc,能控制自己生成的container box中block-level box的布局方式,并且不受外界環(huán)境干擾,元素中的box按照從上到下的順序排布,元素的margin edge 挨著所在container box,上下margin會(huì)發(fā)生疊加,除非這個(gè)元素新建了一個(gè)bfc,那么元素將不不遵守上面的規(guī)則
生成bfc的方式如下float不為none
overflow不為visible
display為‘table-cell’,‘table-caption’,‘inline-block’or‘inline-table’
positon不為relative和static
The value of ‘block-progression’ is ‘lr’ or ‘rl’ and the value of ‘block-progression’ of its parent box is ‘tb’
The value of ‘block-progression’ is ‘tb’ and the value of ‘block-progression’ of its parent box is ‘lr’ or ‘rl’.這個(gè)我暫時(shí)不太明白ifc
inline formatting context,控制inline-level box的排布,每一個(gè)inline container box都是一個(gè)ifc,其實(shí)也就是多個(gè)line boxes的組合,就像bfc中一樣,不過(guò)從垂直排列變成了水平排列,多了對(duì)齊方式,關(guān)于line box在詳細(xì)了解line-height和vertical寫過(guò),這里主要寫line box的可用寬度是其所在的container box的寬度減去float元素的寬度,或者說(shuō)若有float元素和line box重疊,則內(nèi)容就不挨著container box,之間隔了一個(gè)float寬度ffc
flex formatting context,ffc中的container box不存在block-level或者inline-level,每一個(gè)都是一個(gè)flex item,建議看阮一峰Flex布局介紹gfc
gird formatting context,另一種布局方式,暫時(shí)還不是很了解
- float
float先根據(jù)常規(guī)流定位,然后從常規(guī)流中取出,向左或向右移動(dòng),直到碰見(jiàn)另一個(gè)float或者container box的邊緣 - absolute/fixed
從常規(guī)流完全取出,然后根據(jù)所處的containing block定位,就像上面containing block中寫的定位方式