浮動 二 文字圍繞現象(中)
接著講block-level box了。。。該來的始終逃不過~喵~~
block-level box
不知道block-level box是如何產生的童鞋,請移駕這裡,找第21條。會不會有童鞋疑惑 —— 塊狀的box竟然也能畫圈圈 。。。哈哈哈,本小姐變給你看!
要讓塊狀的box畫圈圈,得配合一定的形勢!試想,如果這個block-level box在float box之前,它能夠畫嗎?
例一 block-level box在前,float box在後
<html> <head> <style type="text/css"> .parent{ width:500px; height:120px; margin:20px auto 0; padding:10px; line-height:30px; font-family:"Times New Roman",Georgia,Serif; border:solid 2px rgba(247, 79, 79, 0.56); } .normal-child{ width:100%; border:solid 1px rgba(247, 79, 79, 0.56); text-align:center; margin-bottom:10px; } .float-child{ width:100px; height:50px; float:left; margin-right:10px; box-sizing:border-box; background:rgba(247, 79, 79, 0.56); } </style> </head><body> <div class=parent> <div class=normal-child>Im block-level box. Im block-level box.</div> <div class=float-child></div> </div></body></html>
效果如下:
哎,沒有與float box同行耶!
我知道了!是因為block-level box的寬度太長,他倆一行放不下!——童鞋甲興奮的說道
好!就按你說的來,改短點。
修改例一的CSS代碼:
.normal-child{ width:300px; border:solid 1px rgba(247, 79, 79, 0.56); text-align:center; margin-bottom:10px; }
效果如下:
不科學呀,怎麼沒同行,不同行怎麼圍。。。怎麼圍。。。怎麼。。。怎。。。。。。童鞋,對於block-level box而言,能不能圍起float box不光是看寬度的!
當block-level box在float box之前,由於本身的特性,它自己會獨佔一行,不給其他box一點機會(別跟我說positioned box啊,人為計算距離故意設置的不算!),那麼float box也只能移居下方了。因此,要想圍起float box,就得把block-level box放置float box之後!
考慮三種block-level box:1. 非visible的block box(第23條);2. visible的block box;3.非block box的block-level box。至於為什麼要醬紫分,接著看。
1. 非visible的block box
看過這篇文章的童鞋應該知道,非visible的block box會為它的內容(也就是它的子孫)建立一個新的block formatting context。
這個功能有什麼作用呢?
在CSS渲染時,該box將以一個整體參與到當前的block formatting context中(這個context不一定是父box建立的,也可能是祖父box哈),而它的子孫只會參與到它所建立的block formatting context。
不懂?上栗子!
例二 整體參與,且寬度夠小可與float box同行
<html> <head> <style type="text/css"> .parent{ width:500px; height:130px; margin:20px auto 0; padding:10px; line-height:30px; font-family:"Times New Roman",Georgia,Serif; border:solid 2px rgba(247, 79, 79, 0.56); } .float-child{ width:100px; height:50px; float:left; margin-right:10px; box-sizing:border-box; background:rgba(247, 79, 79, 0.56); } .normal-child{ width:350px; overflow:auto; border:solid 1px rgba(247, 79, 79, 0.56); margin-bottom:5px; padding-left:5px; } </style> </head><body> <div class=parent> <div class=float-child></div> <div class=normal-child>Im first non-visible block box after float box</div> <div class=normal-child>Im second non-visible block box after float box</div> <div class=normal-child>Im third non-visible block box after float box</div> </div></body></html>
效果如下:
上圖中,每個div.normal-child 佔據一行,div裡面的文字很乖的排在裡面,並沒有移動到上一行的空餘位置上,這說明div是以一個整體形式參與到當前的block formatting context中(如果不是整體參與,第三個div里的文字應該跑到第二個div的後面,對不對啦)。至於為什麼float box會與block-level box同行?這一方面取決於float box本身的浮動特性,它可以與block-level box及inline-level box同行;另一方面取決於當前的形勢。就如同一位廚師,要想做出一桌滿漢全席,他首先得具備做滿漢全席的能力,其次他需要原材料,這樣才能真正的做出來。
浮動特性沒什麼好說的,完全由css控制。我來說說形勢。
因為float box是脫離了普通流(normal flow), 那麼不管block-level box是排在float box之前還是之後,它都會假設float box不存在,並確定好自己的位置。待float box渲染時,float box會回到自己原本的位置,如果自己的位置被佔了怎麼辦,其他box會自覺的向反方向流動,若該行沒有足夠空間放置其他box,那麼它們會委屈下移。
看本例,float box寬度加上一個div.normal-child的寬度依然小於containing block(看第11條)的寬度,那麼它們可並排同行。
例三 整體參與,且寬度夠大不可同行
<html> <head> <style type="text/css"> .parent{ width:500px; height:130px; margin:20px auto 0; padding:10px; line-height:30px; font-family:"Times New Roman",Georgia,Serif; border:solid 2px rgba(247, 79, 79, 0.56); } .float-child{ width:100px; height:50px; float:left; margin:0 10px 10px 0; box-sizing:border-box; background:rgba(247, 79, 79, 0.56); } .normal-child{ width:450px; overflow:auto; border:solid 1px rgba(247, 79, 79, 0.56); padding-left:5px; } </style> </head><body> <div class=parent> <div class=float-child></div> <div class=normal-child>Im non-visible block box after float box, and have a longer width</div </div></body></html>
效果如下:
可以看到,如果float box的寬度加上block box的寬度超過了containing block的寬度,排在後面的block box就會自動下移,而這也說明了非visible的block box是整體參與到當前的block formatting context,文字並沒有被包裹成匿名的block box上移到float box的右邊(按常理,文字只有被包裹成匿名的block box才可以參與到block formatting context中)。例四 整體參與,且寬度為auto
<html> <head> <style type="text/css"> .parent{ width:500px; height:auto; margin-top:50px; margin-left:auto; margin-right:auto; } .float-child{ width:200px; height:200px; background-color:rgba(247, 79, 79, 0.56); margin-right:10px; float:left; } .normal-child{ overflow:auto; height:200px; } .special-child{ width:350px; height:100px; border:solid 2px rgba(247, 79, 79, 0.56); padding:10px; } </style> </head><body><div class=parent> <div class=float-child></div> <div class="normal-child"> <div class="special-child">Im a child in non-visible block box</div> </div></div></body></html>
效果如下:
上例中,我並沒有指定跟在float box後面的div的寬度,那麼對於這種情況,即便div的子box的寬度超過了除float box之外的剩餘寬度,div產生的block box依然會與float box同行,因為它的寬度任意啊!!!width為auto的情況下,將overflow設為非visible就是無敵啊!另外,該div同樣是以一個整體的形式參與到當前的block formatting context中,裡面的文字參與的是該div所建立的inline formatting context。小結:對於block-level box為非visible的block box,因為它具備建立一個block formatting context 的特殊功能,故它始終是以一個整體(包含它本身及子box)的形式參與到當前的block formatting context中。如果要達到包圍的效果,只需將多個該類型的box放置float box之後,且寬度小於w( w = containing block的寬度 - float box的寬度 )即可。
2. 非block box的block-level box
由於非block box的block-level box與非visible的block box很相似,這邊先分析。
非block box的block-level box是么尼呢?不知道的童鞋翻翻這裡的第21,22,23條,display為table的非replaced元素及display為block / list-item / table的 replaced元素均會產生非block box的block-level box。我們來看看他們的行為。
例五 table圍繞float box
<html> <head> <style type="text/css"> .parent{ width:500px; height:130px; margin:20px auto 0; padding:10px; line-height:30px; font-family:"Times New Roman",Georgia,Serif; border:solid 2px rgba(247, 79, 79, 0.56); } .float-child{ width:100px; height:50px; float:left; margin-right:10px; box-sizing:border-box; background:rgba(247, 79, 79, 0.56); } .normal-child{ width:350px; display:table; border:solid 1px rgba(247, 79, 79, 0.56); margin-bottom:5px; padding-left:5px; } </style> </head><body> <div class=parent> <div class=float-child></div> <div class=normal-child>Im block-level box, but not block box.</div> <div class=normal-child>Im block-level box, but not block box.</div> <div class=normal-child>Im block-level box, but not block box.</div> </div></body></html>
與例二相比,去掉了class 類normal-child的overflow設置,並將display設為table,效果如下:
竟與例二的效果驚人的一致 。。。
其實,overflow值不為visible的block box 與 非block box的block-level box都是以一個整體形式參與當前的block formatting context,所以他們在float box的前後時行為會表現一致。不信!?那就把例三和例四中的normal-child.div 都替換為table試試看吧。
小結:看上個小結(竊笑中。。。)
還有一個visible的block box沒分析,想留著下篇寫。。。不要罵我懶,這篇已經夠大家消化了,下篇再見哈!
ps: 本文中的例子均是在chrome 49.0上測試。
(轉載請先徵得本人同意)
推薦閱讀:
※【修真院「純潔」系列之一】四臉蒙逼
※You Don't Know CSS(二)
※[譯] 使用 CSS 的 font-size-adjust 屬性改善網頁排版
※Bootstrap 的body行高數值: 1.428571429;怎麼來的?
※新手向 · CSS選擇器