浮動 二 文字圍繞現象(下)

接着講最後一部分啦,咳咳咳,開始上課!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複製代碼

效果以下:

能夠看出,float box仍是原來的那個float box ! 沒變!放心了~~

那以前到底是怎麼回事呢(⊙_⊙)?

先普及一點渲染知識。一份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>
複製代碼

效果以下:

哎,文字並無與float box同行耶。。

其實道理和例一相似,只不過此次換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 上測試。

相關文章
相關標籤/搜索