理解CSS中的BFC

理解CSS中的BFC

1. 前提知识点概述

(1)基本概念类了解

块级元素:是那种源文档被格式化为可视块了的元素。

然后使这个元素变成块级元素的display属性取值如下: ‘block’, ‘list-item’, 和 ‘table’。

块级元素会自动生成一个块级盒block-level box。

块级盒block-level box:是这种参与了块级排版上下文的一种盒子,每个块级元素都生成了一个包含后代盒子和生成的内容的主要块级盒,并且这个盒子参与了任何定位的计算。

margin、border、padding、content分别定义了元素四种边,然后每种类型的边的四条边定义了一个盒子,分别是content box、padding box、border box、margin box,而决定块盒在包含块中与相邻块盒的垂直间距的便是margin-box,这个margin-box是始终存在的,即使它的margin为0 。
这里写图片描述

所有的块级盒子无论怎样都会有一个margin-box,在BFC中,margin-box会与其相邻的margin-box的对边相折叠。

margin-box是参与块级盒在上下文中的布局的,但是参与BFC布局的盒子却是块级盒block-level box,并且参与布局的是盒子而不是元素本身。

理解的块级盒block-level box的构成:
这里写图片描述

(2)Box: CSS布局的基本单位

Box 是 CSS 布局的对象和基本单位, 直观点来说,就是一个页面是由很多个 Box 组成的。

元素的类型和 display 属性,决定了这个 Box 的类型。

不同类型的 Box, 会参与不同的 Formatting Context(一个决定如何渲染文档的容器),因此Box内的元素会以不同的方式渲染。

盒子类型:

  • block-level box :display 属性为 block, list-item, table 的元素,会生成 block-level box。并且参与 block fomatting context;

  • inline-level box :display 属性为 inline, inline-block, inline-table 的元素,会生成 inline-level box。并且参与 inline formatting context;

  • run-in box: css3 中才有。

(3)Formatting Context

Formatting context 是 W3C CSS2.1 规范中的一个概念。

它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。

最常见的 Formatting context 有:

  • Block fomatting context (简称BFC)

  • Inline formatting context (简称IFC)。

CSS2.1 中只有 BFC 和 IFC, CSS3 中还增加了 GFC 和 FFC。

2. BFC 定义

BFC(Block formatting context)直译为”块级格式化上下文”。
它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。

3. BFC布局规则:

  • 内部的Box会在垂直方向,一个接一个地放置。

  • Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠。

  • 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。

  • BFC的区域不会与float box重叠。

  • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之也如此。

  • 计算BFC的高度时,浮动元素也参与计算。

4. 会生成BFC的元素:

根元素

float属性不为none

position为:absolute或fixed

display为:inline-block, table-cell, table-caption, flex, inline-flex

overflow不为visible,是其他的值(hidden,auto,scroll )

filedset元素

5. BFC的应用

BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。

(1)自适应两栏布局

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>自适应两栏布局</title>
        <style type="text/css">
        body{ 
            width: 400px; 
            position: relative; 
            background: lightblue;
        }
        .side{ 
            width:100px; 
            height: 100px; 
            float: left; 
            background: #f66; 
        }
        .main{ 
            height:200px; 
            background:green;
            overflow: hidden; /* 自适应两栏布局关键语句 */
        }
        </style>
    </head>
    <body>
        <div class="side">side: 100 * 100 </div>
        <div class="main">main : 400 * 200</div>
    </body>
    </html>

理解:

每个元素的margin box的左边,与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。

因此,虽然存在浮动的元素aslide,但main的左边依然会与包含块的左边相接触。

BFC的区域不会与float box重叠。

所以可以通过触发main生成BFC,来实现自适应两栏布局,当触发main生成BFC后,这个新的BFC不会与浮动的aside重叠。因此会根据包含块的宽度,和aside的宽度,自动变窄。
对比结果:
这里写图片描述
自适应布局后:
这里写图片描述

(2)清除元素内部浮动

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>清除内部浮动</title>
    <style type="text/css">
    .parent{
        width: 300px;
        border: 1px solid black;
        overflow: hidden; /* 清除内部浮动:没有这一行代码时,结果是下面的第一幅图,加上的结果是第二幅图 */
    }
    .child{
        width:100px;
        height: 100px;
        border: 1px solid red;
        float: left;
    }
    </style>
</head>
<body>
    <div class="parent">
        parent
        <div class="child"> child </div>
        <div class="child"> child </div>
    </div>
</body>
</html>

理解:

计算BFC的高度时,浮动元素也参与计算

为达到清除内部浮动,我们可以触发parent生成BFC,那么parent在计算高度时,parent内部的浮动元素child也会参与计算。

对比结果:
这里写图片描述
清除浮动后:
这里写图片描述

(3)防止垂直的margin重叠

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>垂直的margin重叠</title>
</head>
<style type="text/css">
    p{
        width: 200px;
        line-height: 100px;  /* 设置行高 */
        text-align: center;  /*设置文字居中*/
        color: red;          /*设置段落字体的颜色*/
        margin: 100px;       /*设置外边距*/
        background: pink;    /* 设置背景颜色*/
        border: 1px solid black; /* 设置边框*/
    }
</style>
<body>
    <p>p1: hello  200*100</p>
    <p>p2: world  200*100</p>
</body>
</html>

结果: 两个p之间的距离为100px,发送了margin重叠
这里写图片描述
理解:

Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠。

可以在p外面包裹一层容器,并触发该容器生成一个BFC。那么两个P便不属于同一个BFC,就不会发生margin重叠了。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>防止垂直的margin重叠</title>
</head>
<style type="text/css">
    p{
        width: 200px;
        line-height: 100px;
        text-align: center;
        color: red; 
        margin: 100px;
        background: pink;  
        border: 1px solid black;
    }
    .wrap{  
        overflow: hidden; /*防止垂直的margin重叠 */
    }
</style>
<body>
    <p>p1: hello  200*100</p>
    <div class="wrap">
        <p>p2: world  200*100</p>
    </div>

</body>
</html>

结果:

这里写图片描述

本文参考:
http://www.cnblogs.com/lhb25/p/inside-block-formatting-ontext.html
http://web.jobbole.com/84808/

更多文章可参考:
http://www.zhangxinxu.com/wordpress/2015/02/css-deep-understand-flow-bfc-column-two-auto-layout/

PS:可能本文还有不完善之处,欢迎您留言或与本人联系;-)

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

英子的搬砖日志

您的鼓励是我创作的动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值