0.前言

float属性在css2中是一个热门的属性,被广泛应用于布局之中,同时由于不当使用float带来的问题也非常多,本文结合自己对float的理解以及实际项目中碰到float的相关问题,做一个详细总结,欢迎一起探讨,但未经同意禁止转载。以下是文章的目录

  1. float的特性

  2. float与absolute的区别

  3. float与inline-block

  4. 清除浮动的方法及优缺点

1. float的特性

文字环绕

float 最早的设计目的是用于图片,使文字能够环绕在图片周围,像下面这样:

文字环绕效果是很明显的,这里要注意一个地方:浮动的块虽然脱离的正常的文档流,但是还会占有正常文档流的文本空间,可以看到上面第二种图,p的区域其实是顶到了img的底下的,因为float让img脱离文档流,但是p上的文字却没有顶过去,也就是说p上的一部分文字空间仍然被img占据着,所以从这里也可以看出float的脱离文档流不是完全脱离。

包裹性

所谓的包裹性是指,使用float的元素会自动加上一个块级框,也就是可以像块级元素那样设置宽高
,例子如下:

破坏性

float的破坏性主要是指它会使父容器的高度塌陷,也就是父元素在高度计算的时候会忽略浮动的元素,

可以看到图中名为taxian的元素高度为0。这个特性也正是它能够实现文字环绕的原因,但是由于后来float被大量应用到页面布局之中,所以这个我们不得不想办法清除浮动,这个在下文会有提到。

2. float和position:absolute

脱离文档流

虽然在我们常常看到描述float和absolute的时候,都陈伟脱离文档流,但是实际上并不完全相同:
在脱离文档流方面,absolut正如它的名字一般,是绝对脱离,设置了该属性的元素,将完全独立在文档流之外,不会对其他的元素产生任何影响,就举上面文字环绕的例子来说,如果把img属性的float换成position:absolue属性的话,那么p元素以及上面的文字都会顶到图片的位置上,就像这样:

而对于float我们之前已经提出,float只是脱离了文档流的dom空间但是还占据着文字空间(这两个名词不知道是否已经有更标准的词语出现,在这里只是个人用法,见谅)

高度塌陷

float和absolute都能引起父元素的高度塌陷,同样地,由于absolute是完全脱离文档流,所以这种情况的高度塌陷是没办法清除的;float引起的高度塌陷则是可清除的,我们常说的清除浮动就是指清除float带来的高度塌陷问题,在下文会有提到。

在两列布局中的使用

float和absolute都被广泛用于两列布局之中,absolute由于完全脱离,可以做到精准的定位,但是不利于设计两列之间的联动变化;float属性可以保留一些相互影响,但是要非常小心传递来的问题,比如clear的不当使用会导致左右布局异常联动,在后面讲清除浮动时会专门讲解。而且在使用浮动布局的时候,要注意某些情况下要交换浮动左右浮动元素的声明次序

3. float和display:inline-block

横向排列

首先,使用floatinline-block都能使li横向排列。但是,使用float可以选择排列的方向,而inline只有一种方向;
第二是在单纯排列图片的时候,如果图片大小不是完全一致的,那么使用这两个属性都能完成比较合适的排列:

但是如果图片大小不等高,float的脱离文档流特性导致排列的某些图片会被挤到下一行,导致垂直方向无法对齐,如下:

而如果使用display:inline-block则可以保证垂直方向的对齐:

所以如果是要保证垂直对齐的情况下,使用display:inline-block会比较合适

float和displayinline-block这两个属性有一个很经常用到的地方就是横向导航。导航中一般是单行对齐,而且除了图片之外还有文字,这时候如果采用display:inline-block, 必须要考虑display:inline-block属性带来的空白间隙问题(这个问题可以自行查找,本文中不赘述),此时使用float:left更为合适一些。

4.关于清除浮动

清除浮动的方式

前文中提到float属性会引起父容器高度塌陷的问题,因此我们需要清除浮动。

在阅读这块内容之前,请先了解css中的BFC(这个问题可以自行查找,本文中不赘述),在此基础上,我认为清除浮动,根据原理来划分,分为两类:

  1. 利用clear属性清除浮动

  2. 利用bfc原理包容浮动

首先介绍第一类,利用clear原理清除浮动,如果大家有过经验都知道,通常利用clear属性清除浮动的方式有两种:

  • 利用添加空标签清除浮动

  • 通过after伪类清除元素

这两种方式只是写法上有所不同,通过伪类清除可以让代码比较简洁,并且符合语义化的原则(其实就是可以少写无意义的空标签)现在比较流行的bootstrap框架或者其他各大框架中,通常使用一下代码来清除:

.clearfix:before,
.clearfix:after
{
display: table;
content: " ";
}
.clearfix:after
{
clear: both;
}
.clearfix{zoom:1;} //ie 6 7

其实这里起清除浮动的作用的是只是

    .clearfix:after
{
content: " ";
clear: both;
}

至于before和after中的display:table;是为了防止子元素垂直方向上的边距折叠,也就是通常说的子元素margin-top会被转移到父元素的问题(为防止篇幅过长这个问题也不在此解释,如果有需要可以私信回答)。

所以以上的效果就相当于在父元素最后插入一个子元素,并且设置clear:both属性,这是现在最通用的办法,但是其实并无是完美无缺的

clear使用不当的例子

(这里为什么用了大号呢,因为这个问题很重要!很重要!很重要!)

举一个之前项目中碰到的一种情况,为了方便大家理解,在这里把模型简化,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>float</title>
<style>
*{
padding: 0;
margin:0;
}
.div1{
float: left;
width: 100px;
height: 100px;
background-color: lightpink;
}
.div2{
margin-left:100px;
background-color: lightgreen;
}
</style>
</head>
<body>
<div class="div1">
这是div1
</div>
<div class="div2">
<div style="float:left">这是一个浮动的标题</div>
<div style="clear:both"></div>
</div>
</body>
</html>

这段代码是一个非常简单的左右两列布局,在右边内部有个浮动的标题,于是在后面跟上一个清除浮动的子元素(这里采用空标签只是为了在研究问题的时候排除伪类元素的干扰),但是存在一个问题:右边的div2会自动适应div1的高度,或者说清除浮动的容器会有高度,我们可以在f12中直接改变左边div1的高度,可以看到右边的高度也随之改变。

这种情况有很多方法可以处理,比如让div2形成一个bfc容器,但是很少看到有文章讲到问题的根源,我查了很久,最后发现问题是源于clear这个属性上设计:

clear:
This property indicates which sides of an element's box(es) may not be adjacent to an earlier floating box. The 'clear' property does not consider floats inside the element itself or in other block formatting contexts.

clear:both
Requires that the top border edge of the box be below the bottom outer edge of any right-floating and left-floating boxes that resulted from elements earlier in the source document

以上是w3c文档上关于clear和clear:both的描述,大概有以下两个重点:

  • clear清除浮动对于其他形成bfc的块内部的浮动元素是无效的

  • clear清除浮动的原理是:让添加了clear属性的那个元素的top边缘在某侧或者两侧(看设置的值是left right还是both)浮动元素的底边距之下

其实这个很好理解,我们之所以能够使用clear解决float引起的父元素塌陷问题,其实就是因为加了clear的空标签或者是那么伪类元素,把top值设置在了浮动元素的bottom边缘下方,从而能够撑起父元素。

所以最后我们就知道上面的问题出在哪里了:clear是清除某侧或者两侧的所有浮动,结合上面那个例子来看,其实是有两处浮动的,第一是左侧的div1,第二是在div2内部有个浮动的标题,我们的目的是要清除内部的浮动,但是因为clear本身的定义,就把两个浮动都清除了,也就是把加了clear属性的标签top值设置了浮动元素的bottom边缘下方,所以,那个块将会和左侧等高(实质应是设置了clear空标签的高度为0并且top刚好在div的下方)。

总结

上面的一段说的有点拗口,不知道大家有没有理解,不过可以拿例子去跑一下,应该就很容易理解了。
既然问题找到了,那相应的解决方案也就出来了:

  1. 左侧使用absolute布局避开这个问题

  2. 给右侧div2添加overflow:auito形成bfc,从而隔离clear的作用范围

现在回到清除浮动的问题主线,关于使用bfc包含浮动的情况,了解了bfc特点后我们就知道bfc的内部是会计算浮动元素的高度的,所以直接给浮动元素父元素加上overflow:auto或者其他可以构成bfc的属性即可。

以上内容为查阅相关资料以后,结合经验的个人总结,可能有理解不到位之处,欢迎指出和讨论,同时再次声明未经允许不得转载!!

深入解析 float的更多相关文章

  1. JSON金额解析BUG的解决过程

    [原创申明:文章为原创,欢迎非盈利性转载,但转载必须注明来源] 这是在我们开发的一个支付系统中暴露的一个BUG,问题本身比较简单,有意思的是解决问题的过程.将过程分享出来,希望能够对大家有所帮助. 一 ...

  2. 尚学堂java答案解析 第二章

    本答案为本人个人编辑,仅供参考,如果读者发现,请私信本人或在下方评论,提醒本人修改 一.选择题: 1.CD 解析:A public是关键字. B 第一个不能是数字 2.C 解析:j=i++  < ...

  3. html及css常用的单词

    string? 字符串 boolean? 布尔数学体系,1,0 node? 节点,结 log? ? 日志,记录 console? 控制台 alert? ? 警报 document? 文档 write? ...

  4. 手 Q 人脸识别动画实现详解

    欢迎大家前往腾讯云社区,获取更多腾讯海量技术实践干货哦~ 前言 开门见山,先来看下效果吧. 看到这么酷炫的效果图,不得不赞叹一下我们的设计师.然而,站在程序员的角度上看,除了酷炫之外更多的是复杂.但是 ...

  5. UnityShader 表面着色器简单例程集合

    0.前言 这些简单的shader程序都是写于2015年的暑假.当时实验室空调坏了,30多个人在实验室中挥汗如雨,闷热中学习shader的日子还历历在目.这些文章闲置在我个人博客中,一年将过,师弟也到了 ...

  6. CSS中的一些内容总结

    一.选择器 1.选择器的分组:一个Style可以对多个选择器生效,只用在不同的选择器中间加入逗号即可.如: h1,h2,h3,h4,h5,h6 { color: green; } PS:CSS规定,所 ...

  7. 【Unity游戏开发】跟着马三一起魔改LitJson

    一.引子 在游戏开发中,我们少不了和数据打交道,数据的存储格式可谓是百花齐放,xml.json.csv.bin等等应有尽有.在这其中Json以其小巧轻便.可读性强.兼容性好等优点受到广大程序员的喜爱. ...

  8. js实现省市区联动

    先来看看效果图吧,嘻嘻~~~~~~~~~~~~~~~~~~~· 代码在下面: 示例一: html: <!DOCTYPE html> <html> <head> &l ...

  9. CSS学习之float解析

    转自:http://www.w3cplus.com/css/float.html 一.float是什么? float即为浮动,在CSS中的作用是使元素脱离正常的文档流并使其移动到其父元素的“最左边”或 ...

随机推荐

  1. WPS二级标题链接到一级标题

    WPS二级标题链接到一级标题,即2后出现2.1 2.2而不是1.3 1.4什么的 样式中的编号什么的都不用动,默认即可,关键在于这些多级标题是否选择了同一个编号方式 WPS中,只需要将它们的编号选择为 ...

  2. WIN10:全选一个文件夹中的所有文件

  3. c# 窗体相关操作(最大化/最小化/关闭/标题栏)

    /// <summary> /// 窗体跟随鼠标移动的标记 /// </summary> private bool normalmoving = false; /// < ...

  4. 任意文件夹打开CMD命令窗口

    1:打开任意文件夹 2:按住Shift键,鼠标右键单击 3:该文件夹下的命令窗口已打开,方便快捷

  5. 如何在 MWeb 中配置 Hexo 等静态网站

    原文链接 参考链接: https://zh.mweb.im/mweb-1.4-add-floder-octpress-support.html https://zhuanlan.zhihu.com/p ...

  6. UOJ191口胡

    UOJ191,你失败的原因只有一个:你没有强制在线. 首先这个序列末位加加减减很烦,于是换成操作树,这样就变成查询链的信息了. 注意到一个向量 \((x_1,y_1)\) 比 \((x_2,y_2)\ ...

  7. LGP4841题解

    无向联通图计数板子 首先,这个太难了,先让我们来求一个简单的: 无向图计数. 一共 \(\frac {n \times (n+1)} 2\) 条可能存在的边,枚举一条边是否存在,就有 \(2^{\fr ...

  8. 【面经】MyBatis常见面试问题

    1.什么是 MyBatis? 答:MyBatis 是一个可以自定义 SQL.存储过程和高级映射的持久层框架. 2.讲下 MyBatis 的缓存 答:MyBatis 的缓存分为一级缓存和二级缓存,一级缓 ...

  9. 在kali中安装两个版本的python

    在kali中安装两个版本的python 在kali中已经预装了两个版本的python,但是没有装pip(>︿<). 这时使用python或者python3表示python3:使用pytho ...

  10. Android 12(S) 图形显示系统 - BufferQueue的工作流程(十)

    题外话 疫情隔离在家,周末还在努力学习的我  ..... 一.前言 上一篇文章中,有基本讲清楚Producer一端的处理逻辑,最后也留下了一个疑问: Consumer是什么时候来消费数据的?他是自己主 ...