float、absolute、inline-block三者区别

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框架或者其他各大框架中,通常使用一下代码来清除:

[css] view plain copy

  1. .clearfix:before,
  2. .clearfix:after
  3. {
  4. display: table;
  5. content: " ";
  6. }
  7. .clearfix:after
  8. {
  9. clear: both;
  10. }
  11. .clearfix{zoom:1;} //ie 6 7

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

[css] view plain copy

  1. .clearfix:after
  2. {
  3. content: " ";
  4. clear: both;
  5. }

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

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

clear使用不当的例子

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

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

[html] view plain copy

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>float</title>
  6. <style>
  7. *{
  8. padding: 0;
  9. margin:0;
  10. }
  11. .div1{
  12. float: left;
  13. width: 100px;
  14. height: 100px;
  15. background-color: lightpink;
  16. }
  17. .div2{
  18. margin-left:100px;
  19. background-color: lightgreen;
  20. }
  21. </style>
  22. </head>
  23. <body>
  24. <div class="div1">
  25. 这是div1
  26. </div>
  27. <div class="div2">
  28. <div style="float:left">这是一个浮动的标题</div>
  29. <div style="clear:both"></div>
  30. </div>
  31. </body>
  32. </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的属性即可。

ps:以上内容转载至http://blog.csdn.net/qq_22855325/article/details/78015502,纯属学习总结,如有不妥,及时联系删除,谢谢

时间: 2024-10-10 13:34:02

float、absolute、inline-block三者区别的相关文章

display:inline 和display:inline-block和display:block的区别

之前讲过块级元素使用display:block 行内元素使用display:inline 那么今天我们就来区分一下display:inline,display:inline-block和display:block的区别 首先先说一个名词 :inline element:行内元素也叫作内联元素,内嵌元素,直进式元素 block element:块级元素 1.display:inline 转化成内联元素,不换行: 内联元素的前面和后面都不会有换行符,你不可以给内联元素定宽和高,也就是说你如果同时给一

CSS display:inline|block|inline-block差异

display:inline|block|inline-block三属性的区别和联系,block就是将元素显示为块级元素,inline就是将元素 显示为行内元素,CSS display:inline-block将对象呈递为内联对象,但是对象的内容作为块对象呈递.旁边的内联对象会被呈递在同一行内,允许空格. 详解CSS display:inline|block|inline-block的区别 ◆CSS display:block CSS display:block就是将元素显示为块级元素. blo

Position属性四个值:static、fixed、absolute和relative的区别和用法

Position属性四个值:static.fixed.absolute和relative的区别和用法 在用CSS+DIV进行布局的时候,一直对position的四个属性值relative,absolute,static,fixed分的不是很清楚,以致经常会出现让人很郁闷的结果.今天研究了一下,总算有所了解.在此总结一下: 先看下各个属性值的定义: 1.static(静态定位):默认值.没有定位,元素出现在正常的流中(忽略 top, bottom, left, right 或者 z-index 声

使用float和display:block将内联元素转换成块元素的不同点

使用float和display:block将内联元素转换成块元素的不同点:建议:尽可能的手写代码,可以有效的提高学习效率和深度.内联元素可以转换成块级元素,常用的方法比如可以为内联元素使用float属性让内联元素浮动起来,或者为内联元素添加display:block.虽然两者都可以让内联元素转换成块级元素,但是有区别的.代码实例如下: <!DOCTYPE html> <html> <head> <meta charset=" utf-8">

css absolute与relative的区别

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-

QWidget QMainWindow QDialog 三者区别

Qt类是一个提供所需的像全局变量一样的大量不同的标识符的命名空间.通常情况下,你可以忽略这个类.QObject和一些其它类继承了它,所以在这个Qt命名空间中定义的所有标识符通常情况下都可以无限制的使用. QWidget类是所有用户界面对象的基类. 窗口部件是用户界面的一个原子:它从窗口系统接收鼠标.键盘和其它事件,并且在屏幕上绘制自己的表现.每一个窗口部件都是矩形,并且它们按Z轴顺序排列的.一个窗口部件可以被它的父窗口部件或者它前面的窗口部件盖住一部分. QMainWindow 类提供一个有菜单

C# 总结const、 readonly、 static三者区别:

总结const. readonly. static三者区别: (有人问我,看似简单,我也没能立刻回答出来,总结一下,分享一下.) const:静态常量,也称编译时常量(compile-time constants),属于类型级,通过类名直接访问,被所有对象共享! a.叫编译时常量的原因是它编译时会将其替换为所对应的值: b.静态常量在速度上会稍稍快一些,但是灵活性却比动态常量差一些: c.静态常量,隐式是静态的,即被static隐式修饰过,不能再用static重复修饰, d.在声明时初始化: e

@[email&#160;protected] @PathVariable @RequestParam三者区别

一.问题描述 由于项目是前后端分离,因此后台使用的是spring boot,做成微服务,只暴露接口.接口设计风格为restful的风格,在get请求下,后台接收参数的注解为RequestBody时会报错:在post请求下,后台接收参数的注解为RequestParam时也会报错. 二.问题原因 由于spring的RequestParam注解接收的参数是来自于requestHeader中,即请求头,也就是在url中,格式为xxx?username=123&password=456,而RequestB

display:block | inline | inline-block的区别

display:block; 1.默认宽度为父元素宽度. 2.可设置宽高. 3.换行显示. display:inline: 1.默认宽度为内容宽度. 2.不可设置宽高. 3.同行显示. display:inline-block: 1.默认宽度为内容宽度. 2.可设置宽高. 3.同行显示. 4.整块换行. 例:input,buttom,select等表单元素.