首頁 > web前端 > css教學 > 什麼是BFC?深入了解BFC,聊聊作用

什麼是BFC?深入了解BFC,聊聊作用

青灯夜游
發布: 2022-07-08 11:29:00
轉載
5831 人瀏覽過

什麼是BFC?以下這篇文章帶大家了解BFC,聊聊BFC的作用。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有幫助。

什麼是BFC?深入了解BFC,聊聊作用

之前在面試位元組的時候,面試官問了我有了解BFC嗎,我當時其實有看很多文章,但是總是記不住,感覺每個文章講的都差不多,然後面試時候也沒答出來,但是在聽了王紅元老師講解的之後,感覺茅塞頓開,所以想分享給大家。以下內容都是根據王紅元老師的前端系統課學習的總結,覺得講的非常清晰,非常感謝王紅元老師

在了解BFC(Block Formatting Context)之前,我們先來看看FC(Formatting Context)是什麼:

什麼是BFC?深入了解BFC,聊聊作用

#這段話來自W3C官網,我們可以得到以下資訊:

  • 所有的盒子都屬於一個FC

  • 區塊級元素的佈局屬於一個BFC。例如div/p/h1等 -> BFC佈局中

  • 行內級元素的佈局屬於一個IFC。例如img/a/span/i -> IFC佈局中

簡單理解:塊級元素所在的佈局和上下文就是BFC,行內級元素所在的佈局和上下文就是IFC

問題1.區塊級元素都是在BFC中佈局的,那麼這個BFC在哪裡呢

##首先我們先看一下W3C的官方解釋:

什麼是BFC?深入了解BFC,聊聊作用

MDN上整理出的下了情況會創建BFC:

    根元素(html)
  • 浮動元素(元素的float值不是none)
  • 絕對定位元素(元素的position為absolute或fixed)
  • 行內塊元素(元素的display為inline-block)
  • #表格單元格(元素的display為table-cell,HTML表格單元格預設為該值,表格標題(元素的display為table-caption,HTML表格標題預設為該值)row,tbody,thead,tfoot的預設屬性)或inline -table)
  • overflow計算值(Computed)不為visible的區塊元素
  • #彈性元素(display為flex或inline-flex元素的直接子元素)
  • 網格元素(display為grid或inline-grid元素的直接子元素)
  • display值為flow-root的元素
由此可見

<!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>Document</title>
  </head>
  <body>
    <div></div>
    <div></div>
  </body>
</html>
登入後複製

這段程式碼中的box1和box2都是在html根元素的BFC中佈局的

問題2.BFC的作用

先看一下官方文件對BFC作用的描述:

什麼是BFC?深入了解BFC,聊聊作用

我們可以得到的資訊:

  • 在一個BFC中,盒子會從包含區塊的頂部開始,在垂直方向上會一個挨著一個擺放,可能很多人都對這一點習以為常,但這點是BFC幫助我們實現的。當我們對某個盒子設定一個margin-top的時候,BFC會幫助我們解析,然後會在盒子佈局時候給一個上邊距

  • 在一個BFC中,每個元素的左邊緣都會緊貼著包含塊的左邊緣

  • 在同一個BFC中,在垂直方向上,相鄰兩個盒子的margin會重疊,值取兩者中較大的(可以利用此特性解決margin重疊問題)

#作用1:利用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>Document</title>
    <style>
      .box1 {
        height: 200px;
        width: 400px;
        background-color: orange;

        margin-bottom: 30px;
      }
      .box2 {
        height: 150px;
        background-color: purple;

        margin-top: 50px;
      }
    </style>
  </head>
  <body>
    <div></div>
    <div></div>
  </body>
</html>
登入後複製

此時box1和box1此時同處於html的BFC中,且box1和box2在垂直方向上相鄰,所以會出現margin重疊,取兩者其中較大的值50px

什麼是BFC?深入了解BFC,聊聊作用

如何解決呢? 可能很多人會想到直接為box1增加一個BFC,所以直接為box1加上個overflow:hidden屬性

<!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>Document</title>
    <style>
      .box1 {
        height: 200px;
        width: 400px;
        background-color: orange;

        margin-bottom: 30px;

        overflow: hidden;
      }
      .box2 {
        height: 150px;
        background-color: purple;

        margin-top: 50px;
      }
    </style>
  </head>
  <body>
    <div></div>
    <div></div>
  </body>
</html>
登入後複製

結果呢?

什麼是BFC?深入了解BFC,聊聊作用

發現並不起作用。或許此時很多人就懵了,box1此時不是明明已經形成了BFC了嘛,為什麼還會重疊?讓我來給你解釋一下,首先此時box1確實是已經形成了BFC(可以理解成box1內部形成了BFC),但是對於box1這個元素的本身,還是和box2同屬於html的BFC中,所以還是會發生margin重疊

所以我們要給box1套一層,然後給box1外層的盒子設定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>Document</title>
    <style>
      /* 给box1外层增加一个container盒子,并设置BFC */
      .container {
        overflow: hidden;
      }
      .box1 {
        height: 200px;
        width: 400px;
        background-color: orange;

        margin-bottom: 30px;
      }
      .box2 {
        height: 150px;
        background-color: purple;

        margin-top: 50px;
      }
    </style>
  </head>
  <body>
    <div>
      <div></div>
    </div>
    <div></div>
  </body>
</html>
登入後複製

此時box1屬於container的BFC,而box2屬於html的BFC,不屬於同一個BFC,所以就能解決margin重疊問題

什麼是BFC?深入了解BFC,聊聊作用

作用2:解决浮动高度塌陷问题

当我们给container里面的四个item设置浮动的时候,很明显,这几个元素都会脱离文档流,此时container不会有高度

<!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>Document</title>
    <style>
      .container {
        background-color: orange;
      }

      .item {
        width: 400px;
        height: 200px;
        box-sizing: border-box;
        border: 1px solid #000;
        float: left;
        background-color: #f00;
      }
    </style>
  </head>
  <body>
    <div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
    </div>
  </body>
</html>
登入後複製

什麼是BFC?深入了解BFC,聊聊作用

很多网上博主说,通过给container设置一个BFC,内部的浮动元素就会向其汇报高度,然后container就能解决浮动高度塌陷问题,这个做法是正确的,但是这个说法其实是错误,并不是因为其内部的浮动元素向其汇报了高度

事实上,想通过BFC解决高度塌陷问题需要满足两个条件:

  • 浮动元素的父元素触发BFC,形成独立的块级格式化上下文(BFC)

  • 浮动元素的父元素高度为auto

首先我们先看一段W3C的描述

什麼是BFC?深入了解BFC,聊聊作用

大致意思为BFC的高度是auto情况下,高度是这样计算:

  • 如果只有inline-level,是行高的顶部和底部的距离
  • 如果有block-level,是有最底层的块上边缘和最底层块盒子的下边缘之间的距离(有margin也会计算在内)
  • 如果有绝对定位元素,将被忽略(所有我们无法通过BFC解决绝对定位的高度塌陷问题)
  • 如果有浮动元素,那么会增加高度以包括这些浮动元素的下边缘(这才是BFC能解决浮动元素塌陷问题的原因,并不是因为浮动元素向上汇报了高度)

所以我们直接给container通过添加overflow属性设置BFC,则由于上述第四条4特性,container会增加高度来包括内部四个item浮动元素下边缘,所以解决了浮动塌陷问题

<!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>Document</title>
    <style>
      .container {
        background-color: orange;
        /* 通过overflow形成BFC */
        overflow: hidden;
      }

      .item {
        width: 400px;
        height: 200px;
        box-sizing: border-box;
        border: 1px solid #000;
        float: left;
        background-color: #f00;
      }
    </style>
  </head>
  <body>
    <div>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
    </div>
  </body>
</html>
登入後複製

什麼是BFC?深入了解BFC,聊聊作用

(学习视频分享:web前端入门

以上是什麼是BFC?深入了解BFC,聊聊作用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:juejin.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板