浮动 二 文字围绕现象(下)

接着讲最后一部分啦,咳咳咳,开始上课!

3. visible的block box

这种情况就复杂多了。

overflow为visible的block box(看第23条)是不具备建立block formatting context的能力,这就意味着它位于float box后面时本身的位置是不会变化的,但它的子孙box由于少了block formatting context这层围墙,位置会受到float box的影响。

我们将子孙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 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;
    }
  </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>
复制代码

效果如下:

可以看出,float box被其后的div中的文字包围,貌似成了第一个div.normal-child的子box,感觉好奇怪的样子。。。不行,我要验证一下!

为类normal-child加上margin:

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 上测试。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值