清除浮动技巧总结

一、为何要清除浮动?

要解答这个问题。我们得先说说CSS中的定位机制:普通流,浮动。绝对定位 (当中"position:fixed" 是 "position:absolute" 的一个子类)。

1)普通流:非常多人或者文章称之为文档流或者普通文档流。事实上标准里根本就没有这个词。

假设把文档流直译为英文就是 document flow ,但标准里仅仅有还有一个词,叫做普通流(normal
flow),或者称之为常规流。但似乎大家更习惯文档流的称呼,由于非常多中文翻译的书就是这么来的。比方《CSS Mastery》,英文原书中至始至终都仅仅有普通流 normal flow(普通流) 这一词,从来没出现过document flow (文档流)

2)浮动:浮动的框能够左右移动,直至它的外边缘遇到包括框或者还有一个浮动框的边缘。浮动框不属于文档中的普通流,当一个元素浮动之后。不会影响到块级框的布局而仅仅会影响内联框(一般是文本)的排列,文档中的普通流就会表现得和浮动框不存在一样,当浮动框高度超出包括框的时候。也就会出现包括框不会自己主动伸高来闭合浮动元素(“高度塌陷”现象)。

顾名思义,就是漂浮于普通流之上,像浮云一样,可是仅仅能左右浮动。

正是由于浮动的这样的特性。导致本属于普通流中的元素浮动之后,包括框内部由于不存在其它普通流元素了,也就表现出高度为0(高度塌陷)。

在实际布局中,往往这并非我们所希望的,所以须要闭合浮动元素。使其包括框表现出正常的高度。

二、清除浮动的原理——了解 hasLayout 和 Block formatting
contexts

先看一下清理浮动的各种方法:

1)加入额外标签

这是在学校老师就告诉我们的 一种方法。通过在浮动元素末尾加入一个空的标签比如 <div style=”clear:both”></div>,其它标签br等亦可。

  1. <div class="warp" id="float1">
  2. <h2>1)加入额外标签</h2>
  3. <div class="main left">.main{float:left;}</div>
  4. <div class="side left">.side{float:right;}</div>
  5. <div style="clear:both;"></div>
  6. </div>
  7. <div class="footer">.footer</div>

长处:通俗易懂,easy掌握

缺点:能够想象通过此方法,会加入多少无意义的空标签,有违结构与表现的分离,在后期维护中将是噩梦,这是坚决不能忍受的,所以你看了这篇文章之后还是建议不要用了吧。

2)使用
br标签和其自身的 html属性

这种方法有些小众,br 有 clear=“all | left | right | none” 属性

  1. <div class="warp" id="float2">
  2. <h2>2)使用 br标签和其自身的 html属性</h2>
  3. <div class="main left">.main{float:left;}</div>
  4. <div class="side left">.side{float:right;}</div>
  5. <br clear="all" />
  6. </div>
  7. <div class="footer">.footer</div>

长处:比空标签方式语义稍强,代码量较少

缺点:相同有违结构与表现的分离,不推荐使用

3)父元素设置
overflow:hidden

通过设置父元素overflow值设置为hidden;在IE6中还须要触发 hasLayout ,比如 zoom:1。

  1. <div class="warp" id="float3" style="overflow:hidden; *zoom:1;">
  2. <h2>3)父元素设置 overflow </h2>
  3. <div class="main left">.main{float:left;}</div>
  4. <div class="side left">.side{float:right;}</div>
  5. </div>
  6. <div class="footer">.footer</div>

长处:不存在结构和语义化问题。代码量极少

缺点:内容增多时候easy造成不会自己主动换行导致内容被隐藏掉。无法显示须要溢出的元素;04年POPO就发现overflow:hidden会导致中键失效,这是我作为一个多标签浏览控所不能接受的。

所以还是不要使用了

4)父元素设置
overflow:auto 属性

相同IE6须要触发hasLayout,演示和3差点儿相同

长处:不存在结构和语义化问题,代码量极少

缺点:多个嵌套后,firefox某些情况会造成内容全选;IE中 mouseover 造成宽度改变时会出现最外层模块有滚动栏等,firefox早期版本号会无故产生focus等, 请看 嗷嗷的 Demo ,不要使用

5)父元素也设置浮动

长处:不存在结构和语义化问题,代码量极少

缺点:使得与父元素相邻的元素的布局会受到影响。不可能一直浮动到body,不推荐使用

6)父元素设置display:table

长处:结构语义化全然正确,代码量极少

缺点:盒模型属性已经改变,由此造成的一系列问题,得不偿失,不推荐使用

7)使用:after 伪元素

须要注意的是 :after是伪元素(Pseudo-Element),不是伪类(某些CSS手冊里面称之为“伪对象”),非常多清除浮动大全之类的文章都称之为伪类。只是csser要严谨一点,这是一种态度。

因为IE6-7不支持:after,使用 zoom:1触发 hasLayout。

原文所有代码例如以下:

  1. <style type="text/css"> .clearfix:after { content: ".";display: block;height: 0;clear: both;visibility: hidden; }  .clearfix {display: inline-block;}  /* for IE/Mac */  </style><!--[if IE]> <style type="text/css">.clearfix
    {zoom: 1;/* triggers hasLayout */ display: block;/* resets display for IE/Win */}</style> <![endif]-->

鉴于 IE/Mac的市场占有率极低,我们直接忽略掉,最后精简的代码例如以下:

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

长处:结构和语义化全然正确,代码量居中

缺点:复用方式不当会造成代码量添加

小结

通过对照,我们不难发现,事实上以上列举的方法。无非有两类:

其一。通过在浮动元素的末尾加入一个空元素,设置 clear:both属性,after伪元素事实上也是通过 content 在元素的后面生成了内容为一个点的块级元素;

其二,通过设置父元素 overflow 或者display:table 属性来闭合浮动。我们来探讨一下这里面的原理。

在CSS2.1里面有一个非常重要的概念,可是国内的技术博客介绍到的比較少,那就是Block
formatting contexts
(块级格式化上下文),下面简称 BFC。

CSS3里面对这个规范做了修改。称之为:flow
root
,而且对触发条件进行了进一步说明。

那么怎样触发BFC呢?

  • float 除了none以外的值
  • overflow 除了visible 以外的值(hidden。auto,scroll )
  • display (table-cell。table-caption,inline-block)
  • position(absolute,fixed)
  • fieldset元素

须要注意的是。display:table 本身并不会创建BFC,可是它会产生匿名框(anonymous
boxes),而匿名框中的display:table-cell能够创建新的BFC,换句话说,触发块级格式化上下文的是匿名框。而不是display:table。

所以通过display:table和display:table-cell创建的BFC效果是不一样的。

fieldset 元素在www.w3.org里眼下没有不论什么有关这个触发行为的信息,直到HTML5标准里才出现。有些浏览器bugs(Webkit,Mozilla)提到过这个触发行为,可是没有不论什么官方声明。

实际上,即使fieldset在大多数的浏览器上都能创建新的块级格式化上下文。开发人员也不应该把这当做是理所当然的。CSS
2.1未定义哪种属性适用于表单控件,也未定义怎样使用CSS来给它们加入样式。用户代理可能会给这些属性应用CSS属性,建议开发人员们把这样的支持当做实验性质的,更高版本号的CSS可能会进一步规范这个。

BFC的特性:

1)块级格式化上下文会阻止外边距叠加当两个相邻的块框在同一个块级格式化上下文中时,它们之间垂直方向的外边距会发生叠加

换句话说,假设这两个相邻的块框不属于同一个块级格式化上下文,那么它们的外边距就不会叠加。

2)块级格式化上下文不会重叠浮动元素依据规定。一个块级格式化上下文的边框不能和它里面的元素的外边距重叠。这就意味着浏览器将会给块级格式化上下文创建隐式的外边距来阻止它和浮动元素的外边距叠加。因为这个原因,当给一个挨着浮动的块级格式化上下文加入负的外边距时将会不起作用(Webkit和IE6在这点上有一个问题——能够看这个測试用例)。

3)块级格式化上下文通常能够包括浮动详见:
W3C CSS2.1 - 10.6.7 ‘Auto‘
heights for block formatting context roots

通俗地来说:创建了 BFC的元素就是一个独立的盒子,里面的子元素不会在布局上影响外面的元素。反之亦然,同一时候BFC任然属于文档中的普通流。

至此,您也许明确了为什么 overflow:hidden或者auto能够闭合浮动了,真是由于父元素创建了新的BFC。

对于张鑫旭在对

p=621" target="_blank" style="word-wrap:break-word; margin:0px; padding:0px; font-family:verdana,‘Microsoft YaHei‘,Tahoma,sans-serif; color:rgb(0,85,170); text-decoration:none; font-size:14px; line-height:25.200000762939453px">《overflow与zoom”清除浮动”的一些认识
一文中对于用包裹来解释闭合浮动的原理。我认为是不够严谨的,并且没有根据。

并且说道“Firefox等浏览器并没有haslayout的概念”。那么现代浏览器是有BFC的。从表现上来说。hasLayout
能够等同于 BFC。

IE6-7的显示引擎使用的是一个称为布局(layout)的内部概念。因为这个显示引擎自身存在非常多的缺陷,直接导致了IE6-7的非常多显示bug。当我们说一个元素“得到 layout”。或者说一个元素“拥有 layout” 的时候。我们的意思是指它的微软专有属性 hasLayouthttp://msdn.microsoft.com/worksh
... rties/haslayout.asp
 为此被设为了 true 。

IE6-7使用布局的概念来控制元素的尺寸和定位,那些拥有布局(have layout)的元素负责本身及其子元素的尺寸设置和定位。假设一个元素的 hasLayout 为false,那么它的尺寸和位置由近期拥有布局的祖先元素控制。

触发hasLayout的条件:

在 IE7 中,overflow 也变成了一个 layout 触发器:

  • overflow: hidden|scroll|auto ( 这个属性在IE之前版本号中没有触发 layout 的功能。 )
  • overflow-x|-y: hidden|scroll|auto (CSS3 盒模型中的属性。尚未得到浏览器的广泛支持。

    他们在之前IE版本号中相同没有触发 layout 的功能)

hasLayout更具体的解释请參见 old9翻译的 大名鼎鼎的 《On
having layout》一文(英文原文:http://www.satzansatz.de/cssd/onhavinglayout.htm),因为old9博客被墙。中文版地址:

IE8使用了全新的显示引擎,据称不使用 hasLayout属性了,因此攻克了非常多深恶痛绝的bug。但 IE8~IE11 通过「document.documentElement.currentStyle.hasLayout」依旧能够获得 hasLayout 的标志,我写了一个測试
Demo
(IE8 中 zoom:1 返回 false)。更具体的请看《IE8
haslayout = true》

综上所述:在支持BFC的浏览器(IE8+,firefox。chrome,safari)通过创建新的BFC闭合浮动;在不支持 BFC的浏览器 (IE6-7),通过触发 hasLayout
闭合浮动。

三、闭合浮动方法——精益求精

上面已经列举了7种闭合浮动的方法,通过第三节分析的原理。我们发现事实上很多其它的:display:table-cell,display:inline-block等仅仅要触发了BFC的属性值都能够闭合浮动。从各个方面比較,after伪元素闭合浮动无疑是相对照较好的解决方式了,以下具体说说该方法。

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

1) display:block 使生成的元素以块级元素显示,占满剩余空间;

2) height:0 避免生成内容破坏原有布局的高度。

3) visibility:hidden 使生成的内容不可见,并同意可能被生成内容盖住的内容能够进行点击和交互;

4)通过 content:"."生成内容作为最后一个元素,至于content里面是点还是其它都是能够的,比如oocss里面就有经典的 content:"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",有些版本号可能content 里面内容为空,一丝冰凉是不推荐这样做的,firefox直到7.0
content:”" 仍然会产生额外的空隙;

5)zoom:1 触发IE hasLayout。

通过分析发现。除了clear:both用来清除浮动的。其它代码无非都是为了隐藏掉content生成的内容,这也就是其它版本号的闭合浮动为什么会有font-size:0,line-height:0。

精益求精方案一:

相对于空标签闭合浮动的方法代码似乎还是有些冗余,通过查询发现Unicode字符里有一个“零宽度空格”,也就是U+200B,这个字符本身是不可见的,所以我们全然能够省略掉
visibility:hidden了

  1. .clearfix:after {content:"\200B"; display:block; height:0; clear:both; }
  2. .clearfix { *zoom:1; }

精益求精方案二:

由Nicolas Gallagher 大湿提出来的,原文:A
new micro clearfix hack
,该方法也不存在firefox中空隙的问题。

  1. /* For modern browsers */
  2. .cf:before,.cf:after {
  3. content:"";
  4. display:table;
  5. }
  6. .cf:after { clear:both; }/* For IE 6/7 (trigger hasLayout) */
  7. .cf { zoom:1; }

须要注意的是:

上面的方法用到了  :before伪元素,非常多人对这个有些迷惑,究竟我什么时候须要用before呢?为什么方案一没有呢?事实上它是用来处理margin边距重叠的。因为内部元素 float 创建了BFC,导致内部元素的margin-top和 上一个盒子的margin-bottom
发生叠加。假设这不是你所希望的。那么就能够加上before。假设仅仅是单纯的闭合浮动,after就够了!并非如同大漠《Clear
Float》
一文所说的:但仅仅使用clearfix:after时在跨浏览器兼容问题会存在一个垂直边距叠加的bug,这不是bug,是BFC应该有的特性。

在实际开发中,改进方案一因为存在Unicode字符不适合内嵌CSS的GB2312编码的页面,使用方案7全然能够解决我们的需求了。改进方案二等待大家的进一步实践。方案3、4通过overflow闭合浮动,实际上已经创建了新的 块级格式化上下文。这将导致其布局和相对于浮动的行为等发生一系列的变化。清除浮动仅仅只是是一系列变化中的一个作用而已。

所以为了闭合浮动去改变全局特性。这是不明智的,带来的风险就是一系列的bug,比方firefox
早期版本号产生 focus,截断绝对定位的层等等。始终要明确,假设单单仅仅是须要闭合浮动,overflow就不要使用,而不是某些文章所说的“慎用”。

时间: 2024-12-18 16:35:20

清除浮动技巧总结的相关文章

CSS布局模型 之 浮动模型(浮动的工作原理和清除浮动技巧?)

浮动的工作原理 浮动是让某元素脱离文档流,在浮动框之前和之后的非定位元素会当它不存在一样,可能沿着它的另一侧垂直流动,但都为其腾出空间,块级元素也不例外(被浮动元素占据了部分行空间的块级元素,仍然被看作是占据了一整行,只不过是被浮动元素占据的那部分空间无法利用罢了). 浮动的框可以向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止:如果当前线上的水平空间不足,它将逐行向下移动,直到有空间为止(所以浮动元素不会影响页面上方布局).任何元素都可以浮动,浮动元素会生成一个块级框(拥有块级

CSS清除浮动技巧

一般浮动是什么情况呢?一般是一个盒子里使用了CSS float浮动属性,导致父级对象盒子不能被撑开,这样CSS float浮动就产生了. 本来两个黑色对象盒子是在红色盒子内,因为对两个黑色盒子使用了float浮动,所以两个黑色盒子产生了浮动,导致红色盒子不能撑开,这样浮动就产生了. 简单地说,浮动是因为使用了float:left或float:right或两者都是有了而产生的浮动. 二.浮动产生负作用 1.背景不能显示由于浮动产生,如果对父级设置了(CSS background背景)CSS背景颜色

解释下浮动和它的工作原理?清除浮动的技巧

浮动元素脱离文档流,不占据空间.浮动元素碰到包含它的边框或者浮动元素的边框停留. 浮动元素引起的问题和解决办法? 浮动元素引起的问题: 父元素的高度无法被撑开,影响与父元素同级的元素 与浮动元素同级的非浮动元素(内联元素)会跟随其后 若非第一个元素浮动,则该元素之前的元素也需要浮动,否则会影响页面显示的结构 解决方法: 使用CSS中的clear:both;属性来清除元素的浮动可解决2.3问题,对于问题1,添加如下样式,给父元素添加clearfix样式: .clearfix:after{conte

CSS技巧(一):清除浮动

什么是CSS清除浮动? 在非IE浏览器(如Firefox)下,当容器的高度为auto,且容器的内容中有浮动(float为left或right)的元素, 在这种情况下,容器的高度不能自动伸长以适应内容的高度,使得内容溢出到容器外面而影响(甚至破坏)布局的现象.这个现象叫浮动溢出,为了防止这个现象的 出现而进行的CSS处理,就叫CSS清除浮动. 引用W3C的例子,news容器没有包围浮动的元素. .news { background-color: gray; border: solid 1px bl

CSS技巧(一):清除浮动总洁

什么是CSS清除浮动? 在非IE浏览器(如Firefox)下,当容器的高度为auto,且容器的内容中有浮动(float为left或right)的元素,在这种情况下,容器的高度不能自动伸长以适应内容的高度,使得内容溢出到容器外面而影响(甚至破坏)布局的现象.这个现象叫浮动溢出,为了防止这个现象的出现而进行的CSS处理,就叫CSS清除浮动. 引用W3C的例子,news容器没有包围浮动的元素. .news { background-color: gray; border: solid 1px blac

css技巧:清除浮动

1.常用方法——overflow 给浮动元素的容器添加overflow:hidden;或overflow:auto;可以清除浮动,另外在 IE6 中还需要触发 hasLayout ,例如为父元素设置容器宽高或设置 zoom:1. 不过不能和position配合使用,因为超出的尺寸的会被隐藏. overflow:auto会在内部宽度超过父元素时出现滚动条. 在添加overflow属性后,浮动元素又回到了容器层,把容器高度撑起,达到了清理浮动的效果. 2.终极方法——伪元素 如果遇到水平排列列表需要

两种好用的清除浮动的小技巧(clearfix hack)

方法一:使用内容生成的方式清除浮动 这种方法不能解决margin在垂直边界上的叠加问题,如果不涉及margin的边界叠加问题使用这种方法清除浮动就行了 . 1 /* 2 :after 选择器向选定的元素之后插入内容 3 content:" "; (注意这里有一个空格)生成内容为空 4 display: block; 5 clear:both; 清除前面元素浮动带来的影响 6 */ 7 .clearfix:after { 8 content:""; 9 display

关于清除浮动的一些认识

 清除浮动方法 方法1:给父级盒子加高 给他的父级盒子一个高度,只有有高度的盒子才能关住浮动,也就是说只要这个浮动的盒子在一个有高度的父级盒子中,那么他的浮动就不会影响后面的浮动元素. 方法2:clear:both: 在网页制作中,我们经常用内容来撑起父级盒子的高度,这个时候我们可以给这个浮动的盒子后面的盒子css属性添加clear:both:属性,clear:清除的意思,both: 左右浮动都清除,意思就是清除别人对我的影响.但是存在一个致命的问题就是margin失效. 方法3: 1)隔墙法

利用伪对象选择器E:after实现清除浮动效果

利用伪对象选择器E:after实现清除浮动效果:关于清除浮动已经是老生畅谈的问题,文章实在是太多了,几乎已经被谈烂了.这当然是因为浮动是不居中必须要用到的技巧,那么清除浮动自然也是必须的,但是本章节还是要啰嗦一下,再次介绍一下清除浮动的方法的一种,因为它会用到之前比较少见的伪对象选择器,希望能够引起大家的注意.先看一段代码实例: <!DOCTYPE html> <html> <head> <meta charset=" utf-8"> &