首先明白文档流分为普通流、定位流和浮动流三种。
概念
块级格式化上下文(Block Formatting Context,BFC),用于布局块级盒子的一块渲染区域。
触发条件
- 根元素即HTML元素
- float的值不为none
- overflow的值不为visible
- display的值为inline-block、table-cell、table-caption
- position的值为absolute或fixed
作用
BFC是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面元素,反之亦然。它与普通的块框类似,不同之处在与
- 可以阻止元素被浮动元素覆盖
- 可以包含浮动元素
- 属于同一个BFC的两个相邻块级元素的上下margin会发生重叠,而当两个相邻块级子元素分属于不同BFC时可以阻止margin重叠
在我们进行CSS布局时可能会遇到高度塌陷和margin重叠的情况,这个时候就可以利用BFC的特性来处理这两种问题了。
高度塌陷
HTML
<div class="out">
<div class="in"></div>
</div>
CSS
html, body{
margin: 0;
padding: 0;
background-color: aquamarine;
}
.out{
width: 300px;
height: 300px;
background-color: rgb(212, 191, 191);
}
.in{
width: 100px;
height: 100px;
background-color: red;
margin: 20px; // 给内部div设置margin
}
可以发现内部子div的margin-top和外部父div上边框发生了重叠,并且父div的高度还向下塌陷了20px。这明显和我们想要布局的格式是不一致的。而这一高度塌陷的问题就可以使用BFC来解决。
在上述CSS代码中加入触发BFC的相关条件
触发BFC的条件
.out{
width: 300px;
height: 300px;
background-color: rgb(212, 191, 191);
/* display: inline-block; table-cells、flex */
/* overflow: hidden; auto、scroll */
/* float: left; right*/
position: absolute; /*fixed*/
}
结果如下,成功解决高度塌陷问题。
margin重叠
margin重叠用书面语言来讲,就是垂直相邻的外边距的合并,这种合并行为只应用于外边距。如果元素有内边距和边框,它们绝对不会合并的。下面描述还是使用margin重叠来讲解。
margin重叠主要有三条规则:
- 相邻margin值同为正数,取其最大值
- 相邻margin值同为负数,取其绝对值最大的,然后该元素,从 0 位置,负向位移;
- 相邻margin值一正一负,取其相加和
HTML
<div class="demo1"></div>
<div class="demo2"></div>
CSS
- margin都是正数
.demo1{
width: 300px;
height: 100px;
background-color: blue;
margin-bottom: 30px;
}
.demo2{
width: 300px;
height: 100px;
background-color: blueviolet;
margin-top: 20px;
}
结果如下:
2. margin都是负数
.demo1{
width: 300px;
height: 100px;
background-color: blue;
margin-bottom: -30px;
}
.demo2{
width: 300px;
height: 100px;
background-color: blueviolet;
margin-top: -20px;
}
结果如下:
3. margin一正一负
.demo1{
width: 300px;
height: 100px;
background-color: blue;
margin-bottom: 30px;
}
.demo2{
width: 300px;
height: 100px;
background-color: blueviolet;
margin-top: -20px;
}
结果如下:
以上三种情况就是margin重叠的问题了,但是在我们布局时是需要处理这样的问题的。而使用BFC就可以很好的处理掉margin重叠的问题。
解决思路:
给demo2包一个外部div,在外部div触发BFC条件使其成为一个独立的块级盒子,这样就可以不影响外部元素,反之,外部也不能影响myDIv这个内部元素了。这样就成功解决了margin重叠的问题。
HTML
<body>
<div class="demo1"></div>
<div class="myDiv">
<div class="demo2"></div>
</div>
</body>
CSS
.demo1{
width: 300px;
height: 100px;
background-color: blue;
margin-bottom: 30px;
}
.myDiv{
overflow: hidden;
}
.demo2{
width: 300px;
height: 100px;
background-color: blueviolet;
margin-top: 20px;
}
结果如下:
总结
块级格式化上下文 BFC对于解决一些特殊的问题是很有帮助的,不过我在第一次看它的时候并没有十分在意,只是大致了解了一下它的原理和实用范围。在我自己CSS布局也不常出现需要使用BFC解决的问题,但是这是个很简单的知识点,对于了解CSS布局是很有帮助的。在面试的时候,有时面试官要想考验一下你的CSS基础时有很大可能会考到BFC,比如可能会问你margin重叠的原因以及解决办法,这时你就可以答BFC,会有奇效哦!
拓展
除了BFC外,还有诸如IFC、GFC、FFC等格式化上下文。