1

浮动最初的定义:实现文本环绕图片的效果。除此之外,没有其他方法可实现。

image-20200730213436644

查看DEMO

什么是浮动?

css中的浮动是用float属性来定义:float: left | right | none | inline-start | inline-end

float值不为none,会对display属性的值产生影响:

  • inline-block、inline、block -> block
  • table-* -> block
  • inline-table、table -> table
  • flex、inline-flex -> 值不变,但是float对这样的元素不起作用
  • 其他值不变

当一个元素浮动之后,它会被移出正常的文档流,然后向左或者向右平移,一直平移直到碰到了所处的容器的边框,或者碰到另外一个浮动的元素。浮动元素不属于文档中的普通流,属于浮动布局。 (CSS三种基本的定位机制:普通流、浮动和绝对定位)

浮动的元素不会影响到普通流的块级元素的布局(如同浮动元素不存在一样),只会影响内联元素(如:文本环绕)的排列,如下图2所示。当浮动元素高度超出父元素的时候,就会出现父元素不会自动伸高来闭合浮动元素(高度塌陷现象)。顾名思义,浮动就是漂浮于普通流之上,像浮云一样,但是只能左右浮动。

image-20200730224651452

<section class="flex_box2">
    <div class="flex_item2">
        <div class="img"><img src="./img/pins_3333913039.webp"></div>
        <div class="color"></div>
    </div>
    <div class="flex_item2">
        <img src="./img/pins_3333913039.webp">
        <div class="text">读书,去别人的灵魂里偷窥。旅行,去陌生的环境里去感悟。电影,去荧屏里感受别人的生活历程。冥想,去自己内心的秘境里探寻。<br/>读书,去别人的灵魂里偷窥。旅行,去陌生的环境里去感悟。电影,去荧屏里感受别人的生活历程。冥想,去自己内心的秘境里探寻。</div>
    </div>
</section>
<style>
    .flex_box2 {
        font-size: 0;
    }
    .flex_item2 {
        padding: 20px;
        border: 1px solid #0aa;
        box-sizing: border-box;
        vertical-align: top;
    }
    .flex_item2 .img,
    .flex_item2 img {
        float: left;
        width: 100px;
        margin-left: 20px;
        margin-right: 20px;
    }
    .flex_item2 .img > img {
        width: 100%;
    }
    .flex_item2 .color {
        height: 50px;
        margin-top: 5px;
        background: #0aa;
    }
    .flex_item2 .text {
        font-size: initial;
    }
</style>

查看DEMO

浮动造成影响

  • 会对相邻的元素(紧邻浮动元素后面的元素)产生影响。

    如果相邻元素是块级元素会无视这个浮动的块框(如上图中的背景色模块),也就是我们平时看到的效果——使到自身尽可能与这个浮动元素处于同一行,导致被浮动元素覆盖。

    如果相邻元素是内联元素,则会尽可能围绕浮动元素(如上图中的文案模块)。

  • 父元素在获取高度计算时,会忽略浮动元素,即不计算浮动元素高度。这就是浮动塌陷,也称高度塌陷现象。

什么是块级格式化上下文?

块格式化上下文(Block Formatting Context,BFC)Web页面的可视CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。

BFC,主要用于对块级元素排版。创建了 BFC 的元素就是一个独立的盒子(HTML中的一个盒子, 看不见而已),里面的子元素不会在布局上影响外面的元素,同样,外面的元素,也不会影响其子元素。

从这一点来说,块级格式化上下文的特性与层叠上下文(css探索系列之CSS层叠)类似。

下列方式会创建块格式化上下文:

  • 根元素:<html>
  • 浮动元素:float 不为 none
  • 绝对定位元素:position不为static | relative
  • overflow 值不为 visible 的块元素
  • 行内块元素:display: inline-block
  • 表格单元格:display: table-cellHTML表格单元格默认为该值
  • 表格标题:display: table-captionHTML表格标题默认为该值
  • 匿名表格单元格元素:display: table | inline-table | table-row | table-row-group | table-header-group | table-footer-group
  • display: flow-root一个新的 display 属性的值,它可以创建无副作用的 BFC。注:Safari不支持。
  • 弹性元素:display: flex | inline-flex 元素的直接子元素
  • 网格元素:display: grid | inline-grid 元素的直接子元素
  • contain: layout | content | paint
  • 多列容器:column-countcolumn-width 不为 autocolumn-count: 1
  • column-span: all。即使该元素没有包裹在一个多列容器中(标准变更,Chrome bug)。
注意:display: table 本身并不会创建BFC,但是它会产生匿名盒子(anonymous boxes),而匿名盒子中的display: table-cell可以创建新的BFC,换句话说,触发块级格式化上下文的是匿名框,而不是display: table。所以通过display:tabledisplay: table-cell创建的BFC效果是不一样的。

块级格式化上下文的特性

块格式化上下文对浮动定位(float)、清除浮动(clear)、外边距折叠(Margin collapsing)都很重要。浮动定位和清除浮动时只会应用于同一个BFC内的元素。外边距折叠(Margin collapsing)也只会发生在属于同一BFC的块级元素之间。

块级格式化上下文的三个特性:

  • BFC会阻止外边距折叠(CSS探索系列之Margin

    当两个相邻的块框在同一个块级格式化上下文中时,它们之间垂直方向的外边距会发生叠加。换句话说,如果这两个相邻的块框不属于同一个块级格式化上下文,那么它们的外边距就不会叠加。

    根据规定,一个块级格式化上下文的边框不能和它里面的元素的外边距重叠。由于这个原因,当给一个挨着浮动的块级格式化上下文添加负的外边距时将会不起作用

  • BFC不会重叠浮动元素

    BFC内的浮动不会影响其它BFC中元素的布局,而清除浮动只能清除同一BFC中在它前面的元素的浮动。

  • BFC通常可以包含浮动,即计算BFC的高度时,浮动元素也参与计算

    独立的块级上下文可以包裹浮动流,全部浮动子元素也不会引起容器高度塌陷,也就是说父元素会把浮动元素的高度也计算在内,所以不用清除浮动来撑起高度。同时BFC任然属于文档中的普通流。

    因此,父元素创建了新的BFC,可以闭合浮动

什么是hasLayout?

hasLayoutie私有的概念,ie7及更低版本的ie浏览器不支持BFC,但我们可以针对ie7、6浏览器加入对应的hasLayout规则来实现BFC的效果!

IE使用Layout概念来控制元素的尺寸和位置。可以用Javascript函数hasLayout查看一个元素是否拥有Layout,返回true | false。如果一个元素有Layout,它就有自身的尺寸和位置;如果没有,它的尺寸和位置由最近的拥有布局的祖先元素控制。

hasLayout是一个只读属性,所以无法使用Javascript进行设置。它的值为true的时候会达到和BFC类似的效果

以下方法可以使元素hasLayouttrue

  • position: absolute
  • float: left | right
  • display: inline-block
  • width: 除 auto 外的任意值
  • height: 除 auto 外的任意值
  • zoom: 除 normal 外的任意值
  • writing-mode: tb-rl
  • IE7中 overflow: hidden|scroll|auto

怎样清除浮动呢?

清除浮动,也可以称为闭合浮动。两者实质上,都是为了消除浮动塌陷。它们的区别在于:

清除浮动:对应的单词是 clear,对应CSS中的属性是 clear:left | right | both | none,只能清除同一BFC中在它前面的元素的浮动。

闭合浮动:更确切的含义是使浮动元素闭合,即创建BFC,从而消除浮动塌陷。

确切的说,我们想要达到的效果是闭合浮动,而不是单纯的清除浮动。单纯的清除浮动,并不能解决容器高度塌陷的问题。

比如:我们将上一个示例的背景色模块,加上样式clear: both清除浮动,该模块的浮动还是会影响其后面的兄弟元素。如下图3:

image-20200730224651452

<section class="flex_box2">
    <div class="flex_item2" style="clear: both;">
        <div class="img"><img src="./img/pins_3333913039.webp"></div>
        <div class="color"></div>
    </div>
    ...
    </div>
</section>

查看DEMO

再如:我们将上一个示例的背景色模块,加上样式display: flow-root闭合浮动,创健了新 BFC ,那么,它就不会影响其他 BFC 的元素了。如下图4:

image-20200731003636340

<section class="flex_box2">
    <div class="flex_item2" style="display: flow-root">
        <div class="img"><img src="./img/pins_3333913039.webp"></div>
        <div class="color"></div>
    </div>
    ...
    </div>
</section>

查看DEMO

三种清除浮动的方法

方法一(摧荐): 父元素加伪元素,并给伪元素加clear:both ,据说是最高大上的方法

优点:浏览器支持好,不容易出现怪问题

缺点:注意浏览器兼容问题

<!--定义一个通用清除浮动的样式,在需要的元素中加上-->
<style>
    .clear_float {
        zoom: 1; /*对IE6/7的兼容处理,触发 hasLayout*/
    }
    .clear_float:after,
    .clear_float::after {
        display: block;
        width: 0;
        height: 0;
        content:' ';
        visibility: hidden;
        clear: both;
    }
</style>
<section class="flex_box2">
    <div class="flex_item2 clear_float"> ... </div>
    <div class="flex_item2"> ... </div>
</section>

方法二:浮动元素后,新增空标签div,并设置样式clear:both

优点:通俗易懂,容易掌握

缺点:将添加很多无意义的空标签

 <section class="flex_box2">
    <div class="flex_item2"> ... </div>
    <div style="clear: both;"></div>
    <div class="flex_item2"> ... </div>
</section>

方法三:浮动元素后,新增空标签br标签,并设置属性clear="both"。与方法二类似

    <section class="flex_box2">
        <div class="flex_item2"> ... </div>
        <br clear="both" />
        <div class="flex_item2"> ... </div>
    </section>

闭合浮动的方法

为浮动元素的父元素创建 BFC(为兼容ie6,还需触发hasLayout,如加: zoom: 1)。比如:

  • (推荐)display: inline-block。注意设置width: 100%
  • overflow: auto | hidden | visible。据说autoseo比较友好, hiddenseo不是太友好,但切记不能使用visible值。缺点:内部元素宽高超过父元素时,会出现滚动条(scroll)或者隐藏溢出部分(hidden)。
  • float: left | right。缺点:使得与父元素相邻的元素的布局会受到影响,不可能一直浮动到body
  • display: table。缺点:盒模型属性已经改变,由此造成的一系列问题,得不偿失。
  • display: flow-root一个新的 display 属性的值,它可以创建无副作用的 BFC。缺点:Safari不支持。

参考链接

MDN float

MDN 块格式化上下文


lizh
31 声望0 粉丝