這一次終於弄懂了 CSS BFC、清除浮動、外邊距摺疊

BFC

塊格式化上下文(Block Formatting Context,BFC) 是 Web 頁面的可視化 CSS 渲染的一部分,是塊盒子的佈局過程發生的區域,也是浮動元素與其餘元素交互的區域。css

下列方式會建立塊格式化上下文:html

  • 根元素(<html>)
  • 浮動元素(元素的 float 不是 none
  • 絕對定位元素(元素的 positionabsolutefixed
  • 行內塊元素(元素的 displayinline-block
  • 表格單元格(元素的 displaytable-cell
  • 表格標題(元素的 displaytable-caption
  • 匿名錶格單元格元素(元素的 displaytableinline-table
  • display 值爲 flow-root 的元素(兼容性很差)
  • 彈性元素(displayflexinline-flex 元素的直接子元素)
  • 元素(displaygridinline-grid 元素的直接子元素)
  • overflow 值不爲 visible 的塊元素

上述建立BFC的CSS列爲如下幾類:佈局

  • html 根元素
  • float(不爲 none 便可)
    • left
    • right
  • position
    • absolute
    • fixed
  • display
    • inline-block
    • flex、inline-flex
    • grid、inline-grid
    • tabletable-celltable-caption
    • flow-root

塊格式化上下文對浮動定位(參見 float)與清除浮動(參見 clear)都很重要。學習

總結:flex

  • 浮動定位和清除浮動時只會應用於同一個 BFC 內的元素,浮動不會影響其它 BFC 中元素的佈局;
  • 而清除浮動只能清除同一 BFC 中在它前面的元素的浮動
  • 外邊距摺疊(Margin collapsing)也只會發生在屬於同一 BFC 的塊級元素之間
  • BFC就是頁面上的一個隔離的獨立容器,容器裏面的子元素不會影響到外面的元素,反之亦然
  • 計算BFC的高度時,考慮BFC所包含的全部元素,連浮動元素也參與計算
  • 浮動盒區域不疊加到BFC上

高度坍塌和清除浮動

高度坍塌是指父元素原本應該包括子元素的高度,可是實際上父元素比子元素的高度要小。ui

<!DOCTYPE html>
<html lang="en">
  <head>
    <style> .container { margin-left: 50px; background: red; } .box1 { float: left; width: 200px; height: 200px; background-color: blue; } .box2 { width: 400px; height: 100px; background: cyan; } </style>
  </head>
  <body>
    <div class="container">
      <div class="box1"></div>
      <div class="box2"></div>
    </div>
  </body>
</html>
複製代碼

高度坍塌

一、box1 浮動以後,父元素的高度就坍塌了,解決辦法是讓父元素觸發 BFC ,這樣 BFC 內的元素就沒法影響到外面了,給 container 加上 overflow: auto; 便可。加上以後變成這樣了。spa

清除浮動

二、也能夠經過給 container 添加 ::after 僞元素,清除左右浮動來防止坍塌。翻譯

.container::after {
  content: "";
  display: block; /* 不能少 */
  clear: left;
}
複製代碼

三、還能夠經過在父元素的最後添加一個塊級元素清除浮動3d

<div class="container">
  <div class="box1"></div>
  <div class="box2"></div>
  <div style="clear: both;"></div>
</div>
複製代碼

四、圖中有另一個問題是 box2box1 蓋住了一部分,這是由於 box1 浮動起來了,顯然只須要清除浮動便可。使用 BFC 清除,對應的規則是 浮動盒區域不疊加到BFC上,給 box2 添加 overflow: auto; 以後顯示正常。code

image

五、一樣咱們也能夠經過 clear:both; 來清除浮動,只須要給 box2 添加 clear: both;,可是效果和 BFC 清除有點不同,由於 clear: both; 表示元素下移清除左右浮動

box2 被下移了

外邊距摺疊

塊級元素的上外邊距和下外邊距有時會合並(或摺疊)爲一個外邊距,其大小取其中的最大者,這種行爲稱爲外邊距摺疊(margin collapsing),有時也翻譯爲外邊距合併。注意浮動元素和絕對定位元素的外邊距不會摺疊。

外邊距摺疊的基本狀況:

相鄰元素之間 毗鄰的兩個元素之間的外邊距會摺疊(除非後一個元素須要清除以前的浮動)。

父元素與其第一個或最後一個子元素之間 若是在父元素與其第一個子元素之間不存在邊框內邊距行內內容,也沒有建立塊格式化上下文、或者清除浮動將二者的 margin-top 分開;或者在父元素與其最後一個子元素之間不存在邊框、內邊距、行內內容、height、min-height、max-height 將二者的 margin-bottom 分開,那麼這兩對外邊距之間會產生摺疊。此時子元素的外邊距會「溢出」到父元素的外面。

從上面一段話總結下能夠去除外邊距摺疊的方法:

  1. 父元素添加邊框(border);
  2. 父元素添加內邊距(padding);
  3. 父子元素之間存在行內元素 <span> 匿名元素
  4. 父子元素之間存在觸發 BFC 的元素(插入一個 display: flex 的塊級元素);
  5. 父元素觸發 BFC(overflow: auto; 等);

外邊距摺疊的一些規則:

  • 即便某一外邊距爲 0,這些規則仍然適用。所以就算父元素的外邊距是 0,第一個或最後一個子元素的外邊距仍然會「溢出」到父元素的外面。
  • 若是參與摺疊的外邊距中包含負值,摺疊後的外邊距的值爲最大的正邊距與最小的負邊距(即絕對值最大的負邊距)的和。
  • 若是全部參與摺疊的外邊距都爲負,摺疊後的外邊距的值爲最小的負邊距的值。這一規則適用於相鄰元素和嵌套元素。

如下面代碼爲例:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <style> .container { background-color: deeppink; } .child { } div { background-color: cyan; } body { margin: 0; background-color: yellow; } </style>
  </head>
  <body>
    <div class="container" style="margin-top: 10px;">
      <div class="child" style="margin-top: 50px;">word</div>
    </div>
  </body>
</html>
複製代碼

因爲外邊距摺疊且外邊距都爲正,因此取大的 50px

初始狀態

一、給 container 添加 border,成功去除摺疊。

.container {
  background-color: deeppink;
  border: 1px solid #000000;
}
複製代碼

父元素添加 border

二、給父元素增長 padding,正常了。

.container {
  background-color: deeppink;
  padding: 1px;
}
複製代碼

給父元素增長 padding

三、給父子元素之間添加內聯或者匿名元素,添加一個 &nbsp;,去除摺疊了,可是新增的元素會佔據額外的空間,因此不推薦。

<div class="container" style="margin-top: 10px;">
  &nbsp;
  <div class="child" style="margin-top: 50px;">word</div>
</div>
複製代碼

父子元素之間添加內聯或者匿名元素

四、父子元素之間添加觸發了 BFC 的元素,正常了。

<div class="container" style="margin-top: 10px;">
  <div style="display: flex;"></div>
  <div class="child" style="margin-top: 50px;">word</div>
</div>
複製代碼

父子元素之間添加觸發了 BFC 的元素

五、父元素觸發 BFC,正常了。

.container {
  background-color: deeppink;
  overflow: auto;
}
複製代碼

父元素觸發 BFC


今天的文章就到這裏,感謝閱讀~

歡迎你們關注個人掘金和公衆號,學習之路有人交流討論會輕鬆不少~

公衆號
相關文章
相關標籤/搜索