本文不讲float的所有内容,只浅谈float对不同高度块之间浮动结果的规则以及父元素高度塌陷的解决方法。

首先看一个小问题,就是float会导致父容器的高度塌陷,如下代码:

<head>
    <style>
        .container {
            border: solid red 1px;
        }

        .fl {
            float: left;
            width: 30%;
            height: 100px;
            border: green solid 1px;
            margin: 2px;
        }

        .f2, .f5, .f9 {
            height: 150px;
        }
    </style>
</head>

<body>
    <div class="container">
        <div class="fl">左浮动元素-1(width: 30%; height: 100px;)</div>
        <div class="fl f2">左浮动元素-2(width: 30%; height: 150px;)</div>
        <div class="fl">左浮动元素-3(width: 30%; height: 100px;)</div>
        <div class="fl">左浮动元素-4(width: 30%; height: 100px;)</div>
        <div class="fl f5">左浮动元素-5(width: 30%; height: 150px;)</div>
        <div class="fl">左浮动元素-6(width: 30%; height: 100px;)</div>
        <div class="fl">左浮动元素-7(width: 30%; height: 100px;)</div>
        <div class="fl">左浮动元素-8(width: 30%; height: 100px;)</div>
        <div class="fl f9">左浮动元素-9(width: 30%; height: 150px;)</div>
        <div class="fl">左浮动元素-10(width: 30%; height: 100px;)</div>
        <div class="fl">左浮动元素-11(width: 30%; height: 100px;)</div>
        <div class="fl">左浮动元素-12(width: 30%; height: 100px;)</div>
    </div>
</body>

 

浏览器中结果:

当一个父元素里面的所有元素都是浮动元素时,此时父元素无法识别这些浮动子元素,会进一步导致父元素发生高度塌陷问题。有什么办法可以解决呢?

方法1一种通用的解决方案就是在父元素内部的尾部append一个非浮动的、尺寸为0的块级元素(简称fix元素),然后使用clear:both,让这个fix元素换行显示,进而让父元素能够识别前一行的高度。这种朴素的方案其实就是clearfix的基本原理,clearfix只是更加优雅地用 :after 来实现fix元素。

方法2给父容器添加overflow属性为auto,即:

.container {
    border: solid red 1px;
    overflow: auto;
}

方法3:可以通过将父元素声明为BFC(块级格式化上下文)元素来实现。例如将container的position属性设置为absolute:

.container {
    border: solid red 1px;
    position: absolute;
}

以上方法在浏览器中的结果如下:

从下图中我们可以发现,左浮动元素4的位置有点怪异,为什么它的位置不是在左浮动元素1的下面、左浮动元素2的左边?(即图中问号处的位置),同理左浮动元素6,7,8,9的位置跟我们想象的或许也不一样。

这跟浮动元素的规则有关(其实不用看这么多,只需要记住一句话:浮动元素的位置,只参考前一个元素的位置即可,可看这篇文章:浮动元素的位置,只参考前一个元素的位置即可):

  1. 浮动的项目不能超出它的父容器的边缘。
  2. 左浮动框的左外边界(margin edge)不可以出现在它包含块左边界之左,对于右浮动的元素也有类似规则。
  3. 如果当前框是左浮动框,并且在源文档中存在更早生成的左浮动框,那么对于任意这些先前的框,要么当前框的左外边出现在先前框右外边之右,要么它的顶部必须在先前框的底部之下。对于向右浮动的框也有类似的规则。
  4. 左浮动框的右外边不可以出现在它右侧的任何右浮动框的左外边之右。对于向右浮动的元素也有类似的规则。
  5. 浮动框的顶边不可以高于源文档中先前元素产生的块框或浮动框的顶。浮动框的顶边不可以高于源文档中先前元素产生的包含一个框的任何行框的顶。
  6. 一个浮动块位置必须尽可能高。
  7. 左浮动框必须尽量靠左放置,右浮动框必须尽量靠右放置。
  8. 在更高的位置和更靠左或靠右的位置间,选择前者。
  9. 左浮动框左边如果有另外一个左浮动框,它的右外边不可以出现在它包含块的右边之右。(或者比较宽松的要求是:一个左浮动不可以超出右边,除非它已经尽可能地靠左排列。)对于向右浮动的元素也有类似的规则。

可见,浮动的规则确实很让人迷惑,但从这几条规则中也不难发现,浮动的宗旨是,在不溢出包含块的情况下,尽量地靠上靠左/右放置,但是不能高于它前面生成的块框、浮动框和行框的顶。

这里补充一下浮动原理

  • 浮动起始位置:浮动元素(包括左右)的浮动起始位置为最后一行最左侧的空白位置,而不管空白位置是否能够容纳当前浮动元素
  • 浮动方向:左浮动元素的浮动方向为从起始位置向左浮动;右浮动元素的浮动方向为从起始位置向右浮动。
  • 浮动结束位置:左浮动元素遇到第一个左浮动元素或包含块的最左侧padding时,结束浮动;右浮动元素遇到第一个右浮动元素或包含块的最右侧padding时,结束浮动。

参考文献:

[1] http://www.jb51.net/web/73916.html

[2] https://mp.weixin.qq.com/s/8eAfz_I5xIhh7oFRifxaFw

 

 

 

 

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐