css之再谈浮动定位float(深入理解篇)

在现代开发中,float实际上已经很少使用,因为有更好用的flex布局。但float有他的历史地位,我学的第一个定位方式就是float。而且在面试中经常被提问,引出经典的BFC问题。实际上,float已经成为一个前端僵尸属性,用的不多,也不好用,但面试又被经常提及。

float的本质

float本质上就是做图文环绕的,这是他设计的目的,定位只是顺带的。也正是因为这一特性,在float身上有一些奇怪且不和逻辑的现象。这让用户用起来非常的困惑,对于初学者来说,这些困惑可以是致命的,不知道为什么,又搞不清楚,并且这对一个有着几年经验的前端来说,也是不容易搞清的。之所以这么说,是因为float有些现象是没有逻辑的,或者存在矛盾的地方。请看下面这个例子。

奇怪的空间占用问题(脱离文档流,但仍然会影响其他元素的布局。)

注意我标题的这句话:脱离文档流,但仍然会影响其他元素的布局。怎么影响其他元素布局?这个规则是没有明确提出的,但是,经过我的测试总结,可以用一个规律总结:左浮占空间,右浮不占空间。 你要问为什么?我只能说没有为什么,浏览器引擎内部就是这样设计的。

下面你可以带着这句话解释下面的现象,就都解释的通了。
情况1:

我们定义三个div。让div1和div2分别左右浮动。div3写在两者后面。

这时候你会看到一个奇怪的现象。div3的背景颜色消失了,这是最明显的。但更奇怪的是,div3的渲染位置是在div1的下面,注意,在y轴div2的高度是比div1要高的,div3渲染在div1的高度位置,而不是渲染在div2的高度位置。

这是不合逻辑的。我们知道,浮动元素是脱离文档流的。既然脱离文档流,那么就不会占用空间。按照正常的逻辑,div3应该覆盖在div1上面。 正如标题所说,这是因为浮动虽然脱离文档流,但仍然会影响其他元素的布局。

这是最蛋疼的,正是因为这样,才会出现那么多奇怪的现象。

好消息是,只要你记住浮动虽然脱离文档流,但仍然会影响其他元素的布局。左浮占空间,右浮不占空间。(规律) 你就能解释这一切。
对于情况1的解释:
左浮占用空间,所有换行。 注意这是浏览器引擎规律。如果你要以有没有空间容纳来解释的话,情况2就会出现矛盾的地方。你只能说这是浏览器引擎的内部处理规则就是这样。

至于为什么div3渲染的高度位置是在div1的底部的高度位置,而不是div2底部的高度位置。这实际上你只能说现象就是这样。这东西实际上是内部渲染机制决定的,不需要强行解释为什么,你只需要知道他就是这样就行了。因为毕竟div3的背景颜色都丢失了,你还和我说这些?但是,如果你用左浮占空间,右浮不占空间。这个规律来说,就可以解释的通,因为左浮占空间,右浮不占空间,所以div3出现在div1底部的高度,而不是div2底部的高度。

情况2:

我们做一下改动,把div1注释。效果如下,div3占据了div1原版的位置。这似乎非常的合理,因为div2脱离文档流,不占用空间。好像又正常了,符合脱离文档流不占用空间的直观感受。但别高兴的太早。
对于情况2的解释:

还是记住浮动虽然脱离文档流,但仍然会影响其他元素的布局。左浮占空间,右浮不占空间。(规律)

现在div3跑到左边占据了原来div1的位置。是符合左浮占空间,右浮不占空间这个规律的。因为右浮不占空间,所以第一行是完全空白的,div3自然就可以渲染了。前面说过,如果要按有没有空间来解释的话,这里就会出现矛盾,div2虽然浮动,但是可能是占用空间的(事实上是不占用空间的)。那么div3就应该换行。但实际上div2右浮是不占用空间的。

bash 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Title</title>
    <style>
      .box1 {
        width: 200px;
        height: 200px;
        background-color: lightblue;
        float: left;
      } 
      .box2 {
        width: 300px;
        height: 300px;
        background-color: lightgreen;
        float: right;
      }

      .box3 {
        width: 200px;
        height: 200px;
        background-color: lightsalmon;
        /* clear: right; */
      }
    </style>
  </head>
  <body>
    <!-- <div class="box1">1</div> -->
    <div class="box2">2</div>
    <div class="box3">3</div>
  </body>
</html>

情况3:

我们把代码再改一改,这次把div2注释。和最开始的情况是非常相似的,只是div2不显示了。

这种情况实际上和情况1是差不多的。用左浮占空间,右浮不占空间。非常好解释。div1左浮占空间,所以div3换行,div2右浮不占空间,所以有没有都不影响div3的布局(和情况1结合对比。)。

颜色消失问题:

颜色消失不是因为被遮挡。只能说是浏览器渲染异常。或者说,这是一个bug或者渲染error。其实出现这种情况页面已经不能正常显示了,只是程序没有奔溃。你完全可以把它当成是渲染错误的体现。相当于报渲染错误了。

这就是所谓的高度坍塌 问题。

总结:

解释这些奇怪的现象只需要记住下面这句话:
浮动虽然脱离文档流,但仍然会影响其他元素的布局。左浮占空间,右浮不占空间。(规律)

高度坍塌问题和clear属性

clear的属性的作用是设置一个元素是否允许旁边有浮动属性。这个属性是和float配套出现的。因为float主要是做图片环绕的,但如果你想让标题,分割线等不围绕图片,就可以使用clear属性。同时clear属性可以用于解决高度坍塌问题。

给div3设置clear:both属性后,div3的背景颜色就可以正常显示了。所谓的正常可以理解为现在div3就是一个正常的块元素,没有任何的东西影响他的布局。

bash 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Title</title>
    <style>
      .box1 {
        width: 200px;
        height: 200px;
        background-color: lightblue;
        float: left;
      }
      .box2 {
        width: 300px;
        height: 300px;
        background-color: lightgreen;
        float: right;
      }

      .box3 {
        width: 200px;
        height: 200px;
        background-color: lightsalmon;
        clear: both;
      }
    </style>
  </head>
  <body>
    <div class="box1">1</div>
    <div class="box2">2</div>
    <div class="box3">3</div>
  </body>
</html>

如果我们设置了clear: right;那么效果和clear: both;是一模一样的。对于div3来说,设置了clear: right;右浮就没有效果,那么div2就要占据空间大小,形成上图的效果是合理的。

bash 复制代码
      .box3 {
        width: 200px;
        height: 200px;
        background-color: lightsalmon;
        clear: right;
      }

如果我们设置了clear: left;那么效果如下图所示:

我们可以这样理解:现在左浮没有效果了,所以div1占据大小,而div2因为右浮,大小被忽略,所以div3的高度位置是在div1下面。

bash 复制代码
      .box3 {
        width: 200px;
        height: 200px;
        background-color: lightsalmon;
        clear: right;
      }

总结,如果你把这个例子的几种情况都理解了,那么float 90%的内容都理解了,而所谓的BFC也只是顺手的事。会单独开一篇讲BFC问题。

相关推荐
一个专注api接口开发的小白16 分钟前
Python/Node.js 调用taobao API:构建实时商品详情数据采集服务
前端·数据挖掘·api
掘金一周23 分钟前
我开源了一款 Canvas “瑞士军刀”,十几种“特效与工具”开箱即用 | 掘金一周 8.14
前端·人工智能·后端
嘘不要声张32 分钟前
地图点聚合(谷歌)
前端
缉毒英雄祁同伟39 分钟前
企业级WEB应用服务器TOMCAT
java·前端·tomcat
har01d39 分钟前
在 uniapp 里使用 unocss,vue3 + vite 项目
前端·uni-app·vue·uniapp·unocss
OLong1 小时前
React Update Queue 源码全链路解析:从 setState 到 DOM 更新
前端·react.js
知识浅谈1 小时前
OpenLayers与Vue.js结合实现前端地图应用
前端
答案answer1 小时前
three.js 实现几个好看的文本内容效果
前端·webgl·three.js
Running_C1 小时前
一文读懂跨域
前端·http·面试
前端Hardy1 小时前
HTML&CSS:有趣的小铃铛
javascript·css·html