小松的技术博客

六和敬

若今生迷局深陷,射影含沙。便许你来世袖手天下,一幕繁华。 你可愿转身落座,掌间朱砂,共我温酒煮茶。

CSS浮动与BFC

网页重构时经常会遇到浮动与清除浮动的时候,最开始掌握clear清除浮动的方式就以为清除浮动很简单,但现在觉得清除浮动真的不是件简单的事,学习到了BFC等东西,依然发现看似简单的东西蕴深层次的理论,懂得了其底层的原理,提前就能预料的产生的效果或者做好规划,才能高效的干活,省时省力。

先来一段代码:

<!doctype html>
<html lang="en">
    <head>
         <meta charset="UTF-8">
         <title>Clear float</title>
         <style type="text/css">
             .f_box{float:left;}
         </style>
    </head>
    <body>
        <div class="container">
            <div class="f_box"></div>
            <div class="f_box"></div>
            <div class="f_box"></div>
        </div>
    </body>
</html>

利用clear属性来清除浮动

在子元素的某个元素添加clear:both属性后会清除前面的盒子的浮动,因此最开始我就熟悉用这种方法在父元素的最后面加上一个空盒子,然后定义类并且用于公用,看起来如下

<div class="container">
    <div class="f_box"></div>
    <div class="f_box"></div>
    <div class="f_box"></div>
    <div class="clear"></div>
</div>

CSS代码:.

.clear{clear:both;}

这样有需要就加上这个空盒子,但是这样就加了一大堆混淆内容的空盒子不利于内容与样式的分离,然后学习了css中:after这一属性后就采取全部用css来清除浮动了,html代码变为:

<div class="container clear">
    <div class="f_box"></div>
    <div class="f_box"></div>
    <div class="f_box"></div>
</div>

CSS代码:

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

这样后续只需在父元素中引入clear类就可以了,更加方便。

BFC

最近做项目时遇到布局问题,虽然自己实现了相关的界面,但导师指出这显然不是最优方案,并且介绍了BFC(Block Format Content),之前从未听过这个词,看后顿时觉得自己之前的探索是多么的肤浅。

w3c规范中的BFC定义:

浮动元素和绝对定位元素,非块级盒子的块级容器(例如 inline-blocks, table-cells, 和 table-captions),以及overflow值不为“visiable”的块级盒子,都会为他们的内容创建新的BFC(块级格式上下文)。

在BFC中,盒子从顶端开始垂直地一个接一个地排列,两个盒子之间的垂直的间隙是由他们的margin 值所决定的。在一个BFC中,两个相邻的块级盒子的垂直外边距会产生折叠。 在BFC中,每一个盒子的左外边缘(margin-left)会触碰到容器的左边缘(border-left)(对于从右到左的格式来说,则触碰到右边缘)。

这也就是BFC提供了一个封闭的空间,并且BFC不会与浮动元素发生重叠。形成BFC的条件就有以下几点:

  1. float为 left|right
  2. overflow为 hidden|auto|scroll
  3. display为 table-cell|table-caption|inline-block
  4. position为 absolute|fixed

因此就可以利用它提供的封闭盒子来清除浮动,如给container类加css:

.container{overflow:hidden;}

这样不用加其它任何处理就可以清除浮动了,实在方便。其次也可以利用BFC来形成两栏布局,像一边宽度固定另一边宽度自适应就是个典型例子。

<div class="container">
    <div class="left"></div>
    <div class="right"></div>
</div>

当然可以用左边各自的浮动和右边盒子的margin-left来实现

.container{overflow:hidden;}//清除浮动
.left{width:100px;height:100px;float:left;background:#ff0000;}
.right{margin-left:100px;height:250px;background:#00ff00;}

这种虽然实现了效果,但是两个盒子有着数字依赖,即改变左边盒子的宽度,右边盒子的margin-left属性就必须改变,而根据BFC的不会与浮动元素重叠,上述代码就可以改变为:

.container{overflow:hidden;}//清除浮动
.left{width:100px;height:100px;float:left;background:#ff0000;}
.right{overflow:hidden;height:250px;background:#00ff00;}

如此就再也不用管margin-left了,当有改动时,改动就相对要小一些了,虽然看上去很小,不过却是很重要,每项小的重复加在一起就是很大的工作量了,最近苦学vim更是感觉到了小细节的重要性了。当然上述的清除浮动的方法没有加上zoom触发IE6的hasLayout属性来清除浮动。

←支付宝← →微信 →
comments powered by Disqus