Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BFC 原理 #25

Open
wl05 opened this issue May 23, 2019 · 0 comments
Open

BFC 原理 #25

wl05 opened this issue May 23, 2019 · 0 comments

Comments

@wl05
Copy link
Owner

wl05 commented May 23, 2019

说到css的布局原理就不得不谈到BFC的概念,了解这个概念能够加深我们对布局的理解。

什么是BFC

BFC(Block Formatting Context),中文直译为块级格式上下文。它决定了元素如何对其内容进行定位,以及与其他元素的关系和相互作用。简单来说,它就是一个独立的盒子,这个盒子中的元素的布局与盒子之外的布局之间不会相互影响。

如何触发BFC

常见的能触发BFC的属性值有:

  1. 根元素;

  2. float属性值不为none;

  3. position属性值为absolte或者fixed;

  4. display属性值为inline-block、table-cell、table-caption、flex、inline-flex;

  5. overflow属性值不为visible。

BFC 的布局规则

  1. 内部的Box会在垂直方向,一个接一个地放置。
  2. Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin 会发生重叠
  3. 每个元素的margin-box的左边,与包含块border-box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
  4. BFC的区域不会与float box重叠。

说明

当容器有足够的剩余空间容纳 BFC 的宽度时,所有浏览器都会将 BFC 放置在浮动元素所在行的剩余空间内。
当 BFC 的宽度大于容器剩余宽度时,最新版本的浏览中只有firefox会在同一行显示,其它浏览器均换行。

  1. BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
  2. 计算BFC的高度时,浮动元素也参与计算。

BFC 原理的应用

现在我们了解了BFC的原理,那么我们平时在哪些地方实际上是用到了BFC的原理呢。这里举几个栗子。

1. 清除浮动

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <style>
        .parent {
            border: 2px solid #eeeeee;
        }

        .child {
            width: 100px;
            height: 100px;
            background: #000;
        }
    </style>
</head>
<body>
<div class="parent">
    <div class="child"></div>
</div>
</body>
</html>


我们看到因为child设置了浮动,脱离了文档流,造成了parent高度的塌陷。根据规则6,我们知道BFC在计算元素的时候也会把浮动元素算进去。那么我们触发parent生成BFC试试,加入:

.parent {
    border: 2px solid red;
    overflow: hidden;
}


现在我们看到parent元素的高度被重新撑了起来。这样我们达到了清除浮动的目的。

2. 防止margin重叠

根据第二条规则我们知道"属于同一个BFC的两个相邻Box的margin 会发生重叠", 这不是css的bug,我们可以理解成一种规范。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <style>
        .parent {
            border: 2px solid red;
        }

        .child {
            width: 100px;
            height: 100px;
            background: #000;
            margin: 20px 0;
        }
    </style>
</head>
<body>
<div class="parent">
    <div class="child"></div>
    <div class="child"></div>
</div>
</body>
</html>


我们看到两个child的上下边距发生了重叠,边距只有20px而不是40px,那么如果我们不想margin发生重叠怎么办呢,我们可以把child放到不同的BFC中。我们这样:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <style>
        .parent {
            border: 2px solid red;
        }

        .child {
            width: 100px;
            height: 100px;
            background: #000;
            margin: 20px 0;
        }

        .wrap {
            overflow: hidden;
        }
    </style>
</head>
<body>
<div class="parent">
    <div class="child"></div>
    <div class="wrap">
        <div class="child"></div>
    </div>
</div>
</body>
</html>


这样边距就是40px了。

3. BFC 可以阻止元素被浮动元素覆盖(两栏布局右侧自适应)

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <style>
        .parent {
            border: 2px solid red;
        }

        .child1 {
            width: 100px;
            height: 200px;
            background: blue;
            float: left;
        }

        .child2 {
            background: #2db200;
            height: 300px;
        }
    </style>
</head>
<body>
<div class="parent">
    <div class="child1"></div>
    <div class="child2"></div>
</div>
</body>
</html>

根据规则3我们来分析一下:

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

所以我们看到child1,child2的左边与parent的左边相接触。我们看到child1,child2发生了重叠 ,现在我们想child1,child2不发生重叠我们应该怎么做呢,我们看规则4:

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

.child2 {
   background: #2db200;
   height: 300px;
   overflow: hidden;
}

这样child1,child2就分开了。

小结

BFC原理还是非常有意思的,对理解我们常见的布局方式很有帮助,以前布局只是知其然不知其所以然,学习了BFC后,我们再也不用死记硬背了,非常的nice。

参考资料

  1. BFC原理详解
  2. 前端精选文摘:BFC 神奇背后的原理
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant