什么是BFC?这个在刚接触前端时候一直困扰自己的东西,知道如何用却不知道原理。
正所谓知其然,知其所以然,今天来对它做一个总结!
BFC 一直是面试躲不过的一个命题,之前也看过很多篇文章,但是讲的都相似却讲不清楚,只聊使用却不聊原理,所以一直也记不住。今天通过看其他文章并融入自己的理解作一次总结,希望有所帮助。
在此之前,我们先了解一下FC是什么:
看下W3c文档对标准流和formatting context的解释:
Boxes in the normal flow belong to a formatting context, which may be block or inline, but not both simultaneously. Block-level boxes participate in a block formatting context. Inline-level boxes participate in an inline formatting context.
从中我们能得到如下信息:
简而言之 - 块级元素
所在的布局和上下文就是BFC(Block Formatting Context) - 行内级元素
所在的布局和上下文就是IFC(Inline Formatting Context)
MDN上作了如下解释(形成BFC的条件):
除了文档的根元素 () 之外,还将在以下情况下创建一个新的 BFC:
- 使用float 使其浮动的元素
- 绝对定位的元素 (包含 position: fixed 或position: sticky
- 使用以下属性的元素 display: inline-block
- 表格单元格或使用 display: table-cell, 包括使用 display: table-* 属性的所有表格单元格
- 表格标题或使用 display: table-caption 的元素
- 块级元素的 overflow 属性不为 visible
- 元素属性为 display: flow-root 或 display: flow-root list-item
- 元素属性为 contain: layout, content, 或 strict
- flex items
- 网格布局元素
- multicol containers
- 元素属性 column-span 设置为 all
理解:html是一个BFC, 但是body不是一个BFC,overflow属性除了visible外都是一个BFC
下面我们作如下示例来加深理解:
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>BFCtitle>
head>
<body>
<div class="box1">div>
<div class="box2">div>
body>
html>
这段代码中的box1和box2就都是在html根元素的BFC中布局的。
margin重叠问题原因:
In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block. The vertical distance between two sibling boxes is determined by the ‘margin’ properties. Vertical margins between adjacent block-level boxes in a block formatting context collapse.
In a block formatting context, each box’s left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch). This is true even in the presence of floats (although a box’s line boxes may shrink due to the floats), unless the box establishes a new block formatting context (in which case the box itself href=“https://www.w3.org/TR/CSS2/visuren.html#bfc-next-to-float”>may become narrower due to the floats).
从中我们可以了解到:
因此块级元素会独占一行
html就是一个BFC,因此每一个元素都是默认靠左对齐。
margin重叠问题解决:
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>BFCtitle>
<style>
.box1 {
height: 200px;
width: 400px;
background-color: red;
margin-bottom: 30px;
}
.box2 {
height: 150px;
width: 400px;
background-color: burlywood;
margin-top: 50px;
}
style>
head>
<body>
<div class="box1">div>
<div class="box2">div>
body>
html>
此时box1和box2同事处于html的BFC中,所以会出现margin重叠的情况,取50px;
所以我们如果让它们不在同一个BFC中,就可以解决这个问题:
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>BFCtitle>
<style>
.box1 {
height: 200px;
width: 400px;
background-color: red;
margin-bottom: 30px;
}
.box2 {
height: 150px;
width: 400px;
background-color: burlywood;
margin-top: 50px;
}
.top{
overflow: hidden;
}
style>
head>
<body>
<div class="top">
<div class="box1">div>
div>
<div class="box2">div>
body>
html>
这样我们给box1加一层父元素,并加属性overflow:hidden
让box1处于新的BFC下,就可以让box1和box2处于不同的BFC,也就解决了margin重叠的问题。
当dom设置float浮动后,浮动元素会脱离文档流,导致父元素高度塌陷。见下面例子:
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>BFCtitle>
<style>
.container {
background-color: orange;
padding:10px;
}
.item {
width: 400px;
height: 200px;
box-sizing: border-box;
border: 1px solid #000;
float: left;
background-color: #f00;
}
style>
head>
<body>
<div class="container">
<div class="item">div>
<div class="item">div>
<div class="item">div>
<div class="item">div>
div>
body>
html>
为了可以看清父元素(橙色),我加了10px的padding值,我们可以看到设置了float的item并没有撑起父元素container的高度(此时container高度为0
)。
此时想解决高度塌陷问题需要满足两个条件:
因此我们给.container加上“overflow:hidden”即可。(不绝对,只要让父元素触发BFC即可
)
当BFC高度是auto时,高度是这样计算的:
以上就是今日的分享!希望对大家理解BFC有所帮助。