CSS清除浮动

前言

昨天考了美团的笔试,有道简答题是关于css浮动影响以及如何清除,答的不是太好,今天抽空整理总结下。

正文

什么是浮动

在布局过程中,我们可以通过设置元素为浮动元素很方便地布局,但是一旦成为浮动元素就会脱离普通流,说到这里就要提一下CSS中的定位机制。CSS中有三种定位机制:

  1. 普通流:将窗体自上而下分成一行行, 并在每行中按从左至右的顺序排放元素,即为普通流。
  2. 浮动:浮动的框可以左右移动,直至它的外边缘遇到包含框或者另一个浮动框的边缘。浮动框不属于文档中的普通流,当一个元素浮动之后,不会影响到块级框的布局而只会影响内联框(通常是文本)的排列,文档中的普通流就会表现得和浮动框不存在一样,当浮动框高度超出包含框的时候,也就会出现包含框不会自动伸高来闭合浮动元素(“高度塌陷”现象)。简言之,浮动可以理解为让某个div元素脱离标准流,漂浮在标准流之上,和标准流不是一个层次。
  3. 绝对定位:使用 positon: absolute; 或者 position: fixed 也会让元素脱离普通流。绝对定位的元素的位置相对于最近的已定位祖先元素,如果元素没有已定位的祖先元素,那么它的位置相对于最初的包含块。已定位的祖先元素是指position值不为static的父元素。

浮动带来的负面影响

  1. 背景不能显示。由于浮动的影响,如果对父元素设置背景图片或者背景色,而父元素不能被撑开也就是“高度坍塌”现象导致了背景无法显示。
  2. 边框不能撑开。由于子级里使用了float属性,产生浮动,父级不能被撑开,导致边框不能随内容而被撑开。
  3. margin padding设置值无法正确表达

清除浮动的方法

假设如下布局

<div id="main">
  <p id="left">float left</p>
  <p id="right">float right</p>
</div>
#main {
  border: 1px solid red;
}

#left {
  border: 1px solid black;
  float: left;
  width: 200px;
  height: 200px;
}

#right {
  border: 1px solid black;
  float: right;
  width: 400px;
  height: 200px;
}

清除浮动之前如下图:
"未清除浮动"
清除后如下:
"清除浮动"

方法一:使用带clear属性的空元素

在浮动元素后使用一个空元素,如下

<div id="main">
  <p id="left">float left</p>
  <p id="right">float right</p>
  <div class="clear"></div>
</div>

并且在CSS中添加

.clear {
  clear: both;
}

亦或者使用

<br class="clear" />
  • 优点:简单,代码少,浏览器兼容性好
  • 缺点:需要添加大量无语义的html元素,代码不够优雅

方法二:使用CSS的overflow属性

给浮动元素的容器添加 overflow: hidden 或者 overflow: auto 可以清除浮动,在IE6下还需要触发hasLayout就要添加*zoom: 1

#main {
  border: 1px solid red;
  overflow: hidden;
  /* overflow: auto; */
  *zoom: 1;
}
  • 优点:不存在结构和语义化问题,代码少
  • 缺点:内容增多时候容易造成不会自动换行导致内容被隐藏掉,无法显示需要溢出的元素

方法三:使用CSS的:after伪元素

给浮动元素的容器添加一个clearfix的class,然后给这个class添加一个:after伪元素实现元素末尾添加一个看不见的块元素(Block element)清理浮动。

<div id="main" class="clearfix">
  <p id="left">float left</p>
  <p id="right">float right</p>
</div>
#main {
  border: 1px solid red;
  /* 触发hasLayout */
  zoom: 1;
}

.clearfix:after {
  content: ".";
  display: block;
  height: 0;
  clear: both;
  visibility: hidden;  
}

方法四:给浮动元素的容器设置高度

给父元素设置高度是最不推荐的,使用设置高度样式,清除浮动产生,前提是对象内容高度要能确定并能计算好。

方法五:给浮动元素的容器也设置浮动属性

  • 优点:不存在结构和语义化问题,代码量极少
  • 缺点:使得与父元素相邻的元素的布局会受到影响,不可能一直浮动到body,不推荐使用

总结

清除浮动主要分为两大类:

  • 利用clear属性,也就是为clear属性添加clear:both来清除浮动,包括使用:after伪元素也是为了添加一个具有该属性的块元素来清除浮动带来的影响
  • 触发浮动元素父元素的 BFC(Block Formatting Contexts) 使得该父元素可以包含浮动元素,包括更早版本IE6的 hasLayout 也是如此。