接着講最後一部分啦,咳咳咳,開始上課!css
3. visible的block box
html
這種狀況就複雜多了。chrome
overflow爲visible的block box(看第23條)是不具有創建block formatting context的能力,這就意味着它位於float box後面時自己的位置是不會變化的,但它的子孫box因爲少了block formatting context這層圍牆,位置會受到float box的影響。canvas
咱們將子孫box分爲:inline box( 看第18條), 非inline box的inline-level box( 看第20條), 非visible的block-level box( 看第21條)以及visible的block-level box四種。(ps: float box 及 absolutely positioned box不在考慮範圍內,緣由請移步 這裏。)不一樣的子孫box會進行怎樣的圍繞呢?上栗子!瀏覽器
3.1 子孫box爲inline boxbash
例一測試
<html>
<head>
<style type="text/css">
.parent{
width:500px;
height:auto;
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;
height: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'>
I'm first visible block box after float box.--- <span>I'm grandson whose type is text. I'm grandson whose type is text. I'm grandson whose type is text. </span>
</div>
<div class='normal-child'>I'm second visible block box after float box</div> <div class='normal-child'>I'm third visible block box after float box</div>
</div>
</body>
</html>
複製代碼
效果以下:ui
能夠看出,float box被其後的div中的文字包圍,貌似成了第一個div.normal-child的子box,感受好奇怪的樣子。。。不行,我要驗證一下!spa
爲類normal-child加上margin:code
margin-left:10px;
margin-top:10px複製代碼
效果以下:
那以前到底是怎麼回事呢(⊙_⊙)?
先普及一點渲染知識。一份html文檔在瀏覽器上呈現出來有四個步驟:1. 生成DOM樹;2. 生成渲染樹;3. 渲染樹展示到canvas上;4.canvas呈現到瀏覽器的窗口裏。其中,在第3步驟中,普通流中的block-level box是先於float box渲染到canvas上的,這意味着block-level box有可能被float box遮擋住的(事實上,除非咱們故意設置,不然block-level box是不會被float box遮擋的)。
對於本例,在第2步驟中,因爲float box脫離了普通流(normal flow),div.normal-child在生成box時會假設float box不存在,並肯定本身的位置爲containing block的左上角。
接下來的第3步驟,div.normal-child會先展示到canvas上,接着float box也會展示到canvas上,問題來了!div.normal-child把它的位置佔了!怎麼辦?float box會直接回到本身本來的位置,而div.normal-child裏被float box遮擋的部分會自覺的流動到float box的旁邊。咱們上圖中float box右邊的文字部分就是從新流動的那部分。
好了,真相大白了!
接下來看其餘狀況吧。
3.2 子孫box爲非inline box的inline-level box
例二
<html>
<head>
<style type="text/css">
.parent{
width:500px;
height:auto;
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;
height:auto;
border:solid 1px rgba(247, 79, 79, 0.56);
margin-bottom:5px;
padding-left:5px;
}
.normal-child span{
width:300px;
display:inline-block;
}
</style>
</head>
<body>
<div class='parent'>
<div class='float-child'></div>
<div class='normal-child'>
<span>I'm grandson. I'm grandson. I'm grandson. I'm grandson. </span>
</div>
<div class='normal-child'>I'm second visible block box after float box</div> <div class='normal-child'>I'm third visible block box after float box</div>
</div>
</body>
</html>
複製代碼
效果以下:
其實道理和例一相似,只不過此次換inline-block了。display 爲inline-block的box並非一個inline box,由於它是以一個總體的形式參與到div.normal-child所創建的inline formatting context中的,這就使得它不能切割成幾個部分去與float box並排同處,於是就是上圖看到的效果。
3.3 子孫box爲非visible的block-level box
例三
<html>
<head>
<style type="text/css">
.parent{
width:500px;
height:auto;
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;
height:auto;
border:solid 1px rgba(247, 79, 79, 0.56);
margin-bottom:5px;
padding-left:5px;
}
.normal-child div{
width:300px;
overflow:auto;
}
</style>
</head>
<body>
<div class='parent'>
<div class='float-child'></div>
<div class='normal-child'>
<div>I'm grandson. I'm grandson. I'm grandson. I'm grandson.
</div>
</div>
<div class='normal-child'>I'm second visible block box after float box</div> <div class='normal-child'>I'm third visible block box after float box</div>
</div>
</body>
</html>
複製代碼
本例只是將例二中的span換成了非visible的block-level box,你們先想一想,結果會如何呢?
想好了沒?
實際效果以下:
如出一轍耶!
道理和例二同樣哦。非visible的block-level box會創建一個堅固的block formatting context,於是當float box過來後,右邊剩餘空間不足,使得它不得不下移。
3.4 子孫box爲visible的block-level box
你們看到這,有沒有發現這幾種狀況的分類很熟悉~~~
從上篇開始,就圍繞着float box的崇拜者有哪幾類來展開,接着,又對崇拜者的子孫有哪幾類進行展開。。。。。
有沒有以爲這是遞歸!(不懂的同窗請百度)
因爲子孫box爲visible的block-level box,那麼子孫box並不會爲本身的子孫創建一個block formatting context,因而咱們又回到了子子孫box爲inline box,子子孫box爲非inline box的inline-level box等四種狀況上了。。。
寫成總結代碼就是醬紫:
var box = float box以後的box;
while(null !== box){
switch(box){
case 'inline box':
文字圍繞float box;
box =null;
break;
case '非inline box的inline-level box':
整個inline-level box圍繞float box;
box =null;
break;
case '非visible的block-level box':
整個block-level box圍繞float box;
box =null;
break;
case 'visible的block-level box':
box =box的子box;
break;
default:
box =null;
break;
}
}
複製代碼
上述代碼是對以前全部狀況的一個總結,其實還有一種狀況咱們尚未考慮!
什麼是混搭?
就是不一樣類型的box混在一塊,一塊兒去圍繞float box。
仍是用栗子解釋吧!
例四 混搭
<html>
<head>
<style type="text/css">
.parent{
width:500px;
height:auto;
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:350px;
float:left;
margin-right:10px;
box-sizing:border-box;
background:rgba(247, 79, 79, 0.56);
}
.normal-child{
width:auto;
height:auto;
border:solid 1px rgba(247, 79, 79, 0.56);
margin-bottom:5px;
padding-left:5px;
}
.non-visible{
overflow: auto;
}
.inline-block{
display: inline-block;
}
.non-visible,.inline-block{
width:350px;
}
.long-width{
width:450px;
}
</style>
</head>
<body>
<div class='parent'>
<div class='float-child'></div>
<span>I'm inline box after float box. </span> <div class='inline-block'>I'm not a inline box,but a inline-level box after float box.</div>
<div class='normal-child'>
I'm visible block box after float box.--- <span>I'm inline box in visible block box. </span>
<span class='inline-block'>I'm not a inline box, but a inline-level box which is in visible block box. </span> <div class='non-visible'>I'm a non-visible block box in a visible block box.</div>
</div>
<div class='normal-child non-visible'>
I'm non-visible block box after float box.--- <span>I'm inline box in non-visible block box. </span>
</div>
<div class='inline-block long-width'>I'm not a inline box,but a long-width inline-level box after float box.</div> </div> </body> </html> 複製代碼
float box以後一共有五個box,分別是inline box、非inline box的inline-level box、visible的block-level box、non-visible的block-level box以及寬度很長的非inline box的inline-level box。
其中visible的block-level box的寬度設爲auto是爲了讓子box充分展現他們的特性;non-visible的block-level box及非inline box的inline-level box寬度設爲350px,能夠足夠與float box並排;最後一個加長的非inline box的inline-level box是爲了展現總體參與性;float box足夠高,可使得除最後一個box以外,其餘box均與其並排。
咱們來看看效果。
出現混搭時,你能夠將其看做單一類型圍繞float box的組合。inline box中的文字會一排一排的去圍繞,非inline box的inline-level box及non-visible的block-level box會在寬度容許的狀況下與float box並排,visible的block-level box須要視子孫box而定,一旦出現哪一個box由於寬度不容許而下移到float box之下,接下來的box均將位於float box之下。
稍微更新一下上面的總結代碼,可獲得
終極總結
var boxs = float box以後的box;
surroundFloatBox(boxs);
function surroundFloatBox(boxs){
if(0 === boxs.length){
return;
}
for(var i=0;i<boxs.length;i++){
var box = boxs[i];
while(null !== box){
switch(box){
case 'inline box':
文字圍繞float box;
box =null;
break;
case '非inline box的inline-level box':
整個inline-level box圍繞float box;
box =null;
break;
case '非visible的block-level box':
整個block-level box圍繞float box;
box =null;
break;
case 'visible的block-level box':
surroundFloatBox(box的第一層子box);
break;
default:
box =null;
break;
}
}
}
}
複製代碼
文字圍繞現象總算講完了,我也能夠虛一口氣了~
ps: 本文中的例子均是在chrome 上測試。