前言
大家好,我是HoMeTown,今天想聊一聊CSS中的BFC,很多朋友應該都聽過這個名詞,搞懂BFC可以讓我們理解CSS中一些很詭異的地方,話不多説,直奔主題!
什麼是BFC
BFC是什麼?引用MDN的一段介紹:
塊格式化上下文(Block Formatting Context,BFC) 是 Web 頁面的可視 CSS 渲染的一部分,是塊級盒子的佈局過程發生的區域,也是浮動元素與其他元素交互的區域。
大白話講,我理解BFC其實就是CSS中的塊級作用域,包含上下文元素中的所有子元素,但不包括內創建了新的BFC的子元素的內部元素,也就是 A -> B -> C 但是 A !-> C,換句話講,一個元素不可能存在於兩個BFC中,因為如果一個元素存在於兩個不同的BFC,那麼這個元素就能和這兩個BFC中的子元素髮生作用,那就違法了BFC的初衷:隔離。
BFC的渲染規則
BFC中有特定的渲染規則,如下:
- 同一個BFC中兩個相鄰的元素的
margin重疊問題 - BFC在計算高度是,即使浮動的元素也會參與高度計算
- BFC的區域不會與float的元素區域重疊
- 每個元素的左外邊距與包含塊的左邊界相接觸,即使浮動也如此
- 內部的盒子會一在垂直方向上一個個放置
BFC的觸發條件
- 根元素(HTML標籤)
- float
- overflow != visible
- display =
inline-block、table-cell、table-caption、table、inline-table、flex、inline-flex、grid、inline-grid - postion =
fixed/absolute
BFC的作用
防止相鄰元素的margin重疊
上面提到過,同一個BFC的兩個相鄰元素的上下margin會發生重疊,舉個🌰:
<style>
p {
width: 300px;
height: 200px;
margin: 100px;
line-height: 200px;
text-align: center;
background-color: #f3eaff;
color: #8857cd;
font-weight: bold;
}
</style>
</head>
<body>
<p>HoMeTown</p>
<p>你好朋友</p>
</body>
頁面顯示如下:
同一個BFC中的兩個相鄰元素的margin上下重疊,此時我們需要手動創建新的BFC,解決這個問題,改動如下:
<style>
p {
width: 300px;
height: 200px;
margin: 100px;
line-height: 200px;
text-align: center;
background-color: #f3eaff;
color: #8857cd;
font-weight: bold;
}
.wrapper {
overflow: hidden;
}
</style>
</head>
<body>
<p>HoMeTown</p>
<div class="wrapper">
<p>你好朋友</p>
</div>
</body>
頁面展示如下:
margin恢復正常
BFC在計算高度是,即使浮動的元素也會參與高度計算
眾所周知,元素float脱離文檔流之後,會產生高度塌陷的問題,除了清除浮動,我們還可以通過BFC的特性去處理,舉個🌰:
<style>
p {
width: 300px;
height: 200px;
line-height: 200px;
text-align: center;
background-color: #f3eaff;
color: #8857cd;
font-weight: bold;
float: left;
}
.wrapper {
width: 600px;
border: 4px solid #cfc;
}
</style>
</head>
<body>
<div class="wrapper">
<p>HoMeTown</p>
<p>你好朋友</p>
</div>
</body>
頁面展示如下:
因為子元素浮動的原因導致盒子.wrapper高度塌陷,此時我們手動創建BFC區域,再看看效果,改動如下:
.wrapper {
width: 600px;
border: 4px solid #cfc;
overflow: hidden;
}
此時,頁面展示如下:
.wrapper的高度恢復正常!
每個元素的左外邊距與包含塊的左邊界相接觸
我們知道,如果盒子打開了float,脱離文檔流且不佔位,按照BFC的特點,塊內每個元素的左邊距都會與包含塊的左邊距重合,舉個🌰
<style>
body {
position: relative;
}
.main {
width: 300px;
height: 200px;
line-height: 200px;
text-align: center;
background-color: #f3eaff;
color: #8857cd;
font-weight: bold;
border: 2px solid red;
}
.side {
width: 100px;
height: 200px;
line-height: 200px;
text-align: center;
background-color: #f3eaff;
color: #8857cd;
font-weight: bold;
border: 2px solid yellow;
float: left;
}
</style>
</head>
<body>
<div class="side">你好朋友</div>
<div class="main">HoMeTown</div>
</body>
頁面展示如下:
.side開啓浮動,左外邊距與body的左邊重合,.main也是,這並不是我們想看到的,那麼,可以利用BFC的特點,BFC包含上下文元素中的所有子元素,但不包括內創建了新的BFC的子元素的內部元素,手動給.main創建BFC,改動如下:
.main {
...
overflow: hidden;
}
此時頁面展示如下:
成功!
總結
BFC內部的渲染規則,在現代flex佈局中其實有更多的解決方案,但是作為一個職業前端,還是需要了解一下。以上就是我的見解,不喜勿噴。