CSS清除浮动(Clear与BFC)

在CSS布局中float属性经常会被用到,但使用float属性后会使其在普通流中脱离父容器,让人很苦恼。

  1. 浮动带来布局的便利,却也带来了新问题;
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Clear float</title>
    <style type="text/css">
        .container{
            margin: 30px auto;
            width:600px;
            height: 300px;
        }
        .p{
            border:solid 3px #a33;
        }
        .c{
            width: 100px;
            height: 100px;
            background-color: #060;
            margin: 10px;
            float: left;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="p">
            <div class="c"></div>
            <div class="c"></div>
            <div class="c"></div>
        </div>
    </div>
</body>
</html>

我们希望看到的效果是这样的:


Paste_Image.png

但结果却是这样的:


Paste_Image.png

父容器并没有把浮动元素包围起来,俗称塌陷,为了消除这种现象,我们需要一些清除浮动的技巧。
  1. 如何清除浮动
    清除浮动一般有俩种思路:
  • 利用clear属性,清除浮动;
  • 是父容器形成BFC;
    分别看一下:

2.1 利用clear属性清除浮动;
clear属性是一个什么东东呢?clear属性规定元素的那一侧不允许其他浮动元素,修改一下刚才的代码:

<div class="p">
    <div class="c"></div>
    <div class="c" style="clear:left;"></div>
    <div class="c"></div>
Paste_Image.png

第二个div添加了clear:left属性后,其左侧的div(第一个div)不再浮动,我们可以利用这点在父容器的最后添加一个空的div,设置属性clear:left,这样就可以达到我们的目的了。

2.1.1 添加空的div清理浮动
对我们刚才代码稍作修改

<div class="p">
    <div class="c"></div>
    <div class="c"></div>
    <div class="c"></div>
    <div style="clear:left;"></div>
</div>

也就是在父容器的最后添加<div style="clear:both"></div>看看效果

Paste_Image.png

果真好使了,有些同学看了后可能感觉奇怪,为什么想上一个例子修改第二个div<div style="clear:left" class="c"></div>没有变成这样的效果
Paste_Image.png

说一下自己的拙见,clear:left属性只是消除其左侧div浮动对自己造成的影响,而不会改变左侧div甚至于父容器的表现,在父容器看来,三个div都还是浮动的,所以高度依旧是塌陷。但是我们在最后添加了一个非浮动的div,由于它有clear:left属性,所以它会按照左侧div不浮动来定位自己,也就是定位到下一行,而父容器看到有一个非浮动,普通流的子元素,会将其包围,这样造成了顺便也把三个浮动元素也包裹起来的效果,高度不再塌陷。

2.1.2 使用CSS插入效果
上面的做法浏览器兼容性不错,但是有个很大的问题就是向页面添加了内容来改变效果的目的,也就是数据和表现混淆,既然是变现,看看怎么使用CSS来解决这一问题。根本的做法还是向父容器的最后追加元素,但我们可以利用CSS的:after伪元素来做此事。
添加一个floatfix

.floatfix::after{
  content: ".";
  display:block;
  height:0;
  visibility:hidden;
  clear:left;
}

对父容器添加此类

<div class="p floatfix">
  <div class="c">1</div>
  <div class="c">2</div>
  <div class="c">3</div>
</div>

这样我们就可以看到正确效果了


Paste_Image.png

2.1.3 大师手笔
nicolas Gallagher在A new micro clearfix hack中提供了一种看起来更清爽的做法;

.floatfix::after{
  content: "";
  display:table;
  clear:both;
}

2.2 使父容器形成BFC
BFC有三个特性:

  • BFC会阻止外边距(margin-top、margin-bottom)折叠;
    • 按照BFC的定义,只有同属于一个BFC时,俩个元素才有可能发生垂直Margin的重叠,这个包括相邻元素、嵌套元素,只要它们之间没有阻挡(例如边框、非空内容、padding;)就会发生margin重叠。
    • 因此要解决margin重叠问题,只要让它们不在同一个BFC就行了,但是对于俩个相邻的元素来说,意义不大,没有必要给它们加个外壳,但是对于嵌套元素来说就很有必要了,只要把父元素设置为BFC就可以了。这样子元素的margin就不会和父元素的margin发生重叠了。
  • BFC不会重叠浮动元素;
  • BFC可以包含浮动;

我们可以利用BFC的第三条特性来”清除浮动“,这里其实说清除浮动已经不再合适,应该说包含浮动。也就是说只要父容器形成BFC就可以,简单看看如何形成BFC

  • float为left | right;
  • overflow为 hidden | auto | scroll;
  • display为 table-cell | table-caption | inline-block;
  • position为 absolute | fixed;
    我们可以对父容器添加这些属性来形成BFC达到”清除浮动“的效果

2.2.1 利用float来使父容器形成BFC

<div class="p" style="float:left;">
    <div class="c">1</div>
    <div class="c">2</div>
    <div class="c">3</div>
Paste_Image.png

我们可以看到父容器高度没有塌陷,但是长度变短了,因为div应用float后会根据内容来改变长度,这个在很多时候有用。

2.2.2 使用BFC的其他局限
上面提到使用BFC使用float的时候会使父容器的长度缩短,而且还有一个重要缺陷——父容器float解决了其塌陷问题,那么父容器的父容器怎么办?难道要全部使用float吗(确实有这种布局方式)。BFC的几种布局方式都有自己的问题,overflow会影响滚动条和绝对定位的元素;position会改变元素的定位方式,这是我们不希望的,display这几种凡是依然没有解决低版本IE问题……

2.2.3 haslayout
我们知道在IE6、7内有个hasLayout的概念,很多bug正式由hasLayout导致的,当元素的hasLayout属性值为false的时候,元素的尺寸和位置由最近拥有布局的祖先元素控制。当元素的hasLayout属性值为true的时候会达到和BFC类似的效果,元素负责本身及其子元素的尺寸设置和定位。我们可以利用这点儿在IE6、7下完成清浮动,先看看怎么使元素hasLayout为true
position: absolute
float: left|right
display: inline-block
width: 除 “auto” 外的任意值
height: 除 “auto” 外的任意值
zoom: 除 “normal” 外的任意值
writing-mode: tb-rl

在IE7中使用overflow: hidden|scroll|auto 也可以使hasLayout为true

3 一个相对靠谱的解决方案

  • 在IE+、现代浏览器上使用伪元素;
  • 在IE6、7使用haslayout;
.floatfix{
    *zoom:1;
}
.floatfix:after{
    content:"";
    display:table;
    clear:both;
}

参考文献——CSS清浮动处理(Clear与BFC)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容

  • 清除浮动一般有两种思路:一、利用clear属性,清除浮动二、使父容器形成BFC 一、利用clear属性,清除浮动c...
    饥人谷_紫尘阅读 4,726评论 2 11
  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,728评论 1 92
  • 一,浮动元素有什么特征?对父容器、其他浮动元素、普通元素、文字分别有什么影响? 浮动模型是一种可视化格式模型,浮动...
    DeeJay_Y阅读 856评论 0 4
  • relative:生成相对定位的元素,通过top,bottom,left,right的位置相对于其正常位置进行定位...
    zx9426阅读 929评论 0 2
  • 文章版权归饥人谷_Lyndon以及饥人谷所有。 1. 浮动元素有什么特征?对父容器、其他浮动元素、普通元素、文字分...
    HungerLyndon阅读 2,370评论 4 10