首頁  >  文章  >  web前端  >  深入淺析CSS 佈局和 BFC

深入淺析CSS 佈局和 BFC

青灯夜游
青灯夜游轉載
2020-10-12 17:49:192256瀏覽

深入淺析CSS 佈局和 BFC

CSS佈局中有一些概念,一旦你了解它們,就能真正提升你的 CSS 佈局能力。本文是關於區塊格式化上下文(BFC)的。你可能從未聽說過這個術語,但是如果你曾經用CSS做過佈局,你可能知道它是什麼,理解什麼是BFC,怎麼工作以及如何創建BFC 非常有用,這些可以幫助你理解CSS中的佈局是如何運作的。

(推薦教學:CSS教學

#在本文中,透過熟悉的範例來解釋什麼是 BFC。然後說明 display 的一個新值,只有當你理解了什麼是 BFC 以及為什麼需要它時,它才有意義。

什麼是 BFC

在網路頁面的CSS渲染中,區塊層級格式化上下文 (Block Fromatting Context)是按照區塊級盒子佈局的。 W3C對BFC的定義如下:

浮動元素和絕對定位元素,非塊級盒子的塊級容器(例如inline-blocks, table-cells, 和table-captions),以及overflow值不為“ visiable」的塊級盒子,都會為他們的內容創建新的BFC(塊級格式上下文)。

BFC是一個獨立的佈局環境,其中的元素佈局是不受外界的影響,並且在一個BFC 中,塊盒與行盒(行盒由一行中所有的內聯元素所組成)都會垂直的沿著其父元素的邊框排列。

區塊格式化上下文(BFC)的行為透過一個簡單的float範例很容易理解。在下面的範例中,我有一個框,其中包含向左浮動的圖像和一些文字。如果我們有足夠的文本,它會環繞浮動的圖像和邊框,然後環繞整個區域。

// html
<p>
  </p><p>I am a floated element.</p>
  I am text inside the outer box.


// css
.outer {
  border: 5px dotted rgb(214,129,137);
  border-radius: 5px;
  width: 450px;
  padding: 10px;
  margin-bottom: 40px;
}

.float {
  padding: 10px;
  border: 5px solid rgba(214,129,137,.4);
  border-radius: 5px;
  background-color: rgba(233,78,119,.4);
  color: #fff;
  float: left;  
  width: 200px;
  margin: 0 20px 0 0;
}

深入淺析CSS 佈局和 BFC

如果我刪除了一些文本,那麼就沒有足夠的內容來包圍圖像,而且由於浮動被從文檔流中脫離,所以邊框會上升,並在圖像下方,直到文字的高度。

深入淺析CSS 佈局和 BFC

這是因為當我們浮動一個元素時,文字所在的框的寬度保持不變,為給浮動元素騰出空間而縮短的是文字的行框。這就是為什麼背景和邊框會出現在浮動後面的原因。

我們通常有兩種方法來解決這個佈局問題。一種方法是使用 clearfix hack,它的作用是在文字和圖像下面插入一個元素,並將其設為 clear:both。另一種方法是使用 overflow 屬性,其值不是預設值 visible

.outer {
  overflow: auto;
}

深入淺析CSS 佈局和 BFC

查看示範:https://codepen.io/anon/embed/XzYWZj?height=500&theme-id=0&slug-hash=XzYWZj&user=&default- tab=

overflow 以此方式運作的原因是,使用visible 的初值以外的任何值都會建立一個區塊格式化上下文,而BFC 的一個特性是它包含浮動。

BFC 是佈局中的一個迷你佈局

你可以將 BFC 看作是頁面內的一個迷你佈局。一旦一個元素創建了一個 BFC,它就包含了所有的內容。正如我們所看到的,這包括浮動的元素,它們不再從盒子底部伸出來。 BFC 也會導致一些其他有用的行為。

BFC 可以防止 margin 折疊

了解邊距合併是另一個被低估的 CSS 技能。在下一個範例中,假設有一個背景顏色為灰色的 p

這個 p 包含兩個標籤 p。外部 p 元素的 margin-bottom 為 40 個像素,標籤 p 的頂部和底部 margin 都是 20 像素。

// html
<p>
  </p><p>I am paragraph one and I have a margin top and bottom of 20px;</p>
  <p>I am paragraph one and I have a margin top and bottom of 20px;</p>

  
// css
.outer {
   background-color: #ccc;
  margin: 0 0 40px 0;
}

p {
  padding: 0;
  margin: 20px 0 20px 0;
  background-color: rgb(233,78,119);
  color: #fff;
}

因為p 元素的margin 和外部p 上的margin 之間沒有任何東西,所以兩個會折疊,因此p最終與p 的頂部和底部齊平。我們在 p 的上方和下方看不到任何灰色。

深入淺析CSS 佈局和 BFC

在CSS當中,相鄰的兩個盒子(可能是兄弟關係也可能是祖先關係)的外邊距可以結合成一個單獨的外邊距。這種合併外邊距的方式稱為折疊,因而結合成的外邊距稱為折疊外邊距。折疊的結果依照以下規則計算:

  1. 两个相邻的外边距都是正数时,折叠结果是它们两者之间较大的值。
  2. 两个相邻的外边距都是负数时,折叠结果是两者绝对值的较大值。
  3. 两个外边距一正一负时,折叠结果是两者的相加的和。

产生折叠的必备条件:margin必须是邻接的!

如果我们把盒子设为 BFC,它现在包含了标签 p 和它们的边距,这样它们就不会折叠,我们可以看到边距后面容器的灰色背景。

.outer {
  background-color: #ccc;
  margin: 0 0 40px 0;
  overflow: auto;
}

深入淺析CSS 佈局和 BFC

查看演示:https://codepen.io/anon/embed/YEvzRv?height=500&theme-id=0&slug-hash=YEvzRv&user=&default-tab=

再一次,BFC 的工作是把东西装在盒子里,防止它们从盒子里跑出来。

BFC 可以阻止元素被浮动元素覆盖

你将熟悉 BFC 的这种行为,因为使用浮动的任何列类型布局都是这样工作的。如果一个项目创建了一个 BFC,那么该项目将不会包裹任何浮动元素。在下面的例子中,有如下 html 结构:

<p>
  </p><p>I am a floated element.</p>
  <p>I am text</p>

带有 float 类的项被向左浮动,因此 p 中的文本在它环绕 float 之后。

深入淺析CSS 佈局和 BFC

我可以通过将包裹文本的 p 设置为 BFC 来防止这种包裹行为。

.text {
  overflow: auto;
}

深入淺析CSS 佈局和 BFC

这实际上是我们创建具有多个列的浮动布局的方法。浮动项还为该项创建了一个 BFC,因此,如果右边的列比左边的列高,那么我们的列就不会相互环绕。

查看演示:https://codepen.io/anon/embed/qVKEpJ?height=500&theme-id=0&slug-hash=qVKEpJ&user=&default-tab=

在多列布局中使用 BFC

如果我们创建一个占满整个容器宽度的多列布局,在某些浏览器中最后一列有时候会掉到下一行。这可能是因为浏览器四舍五入了列宽从而所有列的总宽度会超出容器。但如果我们在多列布局中的最后一列里创建一个新的BFC,它将总是占据其他列先占位完毕后剩下的空间。

例如:

<p>
    </p><p>column 1</p>
    <p>column 2</p>
    <p>column 3</p>

对应的CSS:

.column {
    width: 31.33%;
    background-color: green;
    float: left;
    margin: 0 1%;
}
.column:last-child {
  float: none;
}

未创建 BFC 之前:

深入淺析CSS 佈局和 BFC

添加以下样式创建一个 BFC:

.column:last-child {
  float: none;
  overflow: hidden; 
}

深入淺析CSS 佈局和 BFC

现在尽管盒子的宽度稍有改变,但布局不会打破。当然,对多列布局来说这不一定是个好办法,但能避免最后一列下掉。这个问题上弹性盒或许是个更好的解决方案,但这个办法可以用来说明元素在这些环境下的行为。

还有什么能创建 BFC?

除了使用 overflow 创建 BFC 外,其他一些 CSS 属性还创建 BFC。正如我们所看到的,浮动元素创建了 BFC。你的浮动项将包含它里面的任何东西。

使用以下方式都能创建 BFC

  • float 的值不是 none。
  • position 的值不是 static 或者 relative。
  • display 的值是 inline-block、table-cell、flex、table-caption 或者inline-flex
  • overflow 的值不是 visible

创建 BFC 的新方式

使用overflow或其他的方法创建BFC时会有两个问题。首先,这些方法本身是有自身的设计目的,所以在使用它们创建BFC时可能会产生副作用。例如,使用overflow创建BFC后在某些情况下可能会看到出现一个滚动条或者元素内容被裁切。

这是由于overflow属性的设计是用来让你告诉浏览器如何定义元素的溢出状态的。浏览器执行了它最基本的定义。

即使在没有任何不想要的副作用的情况下,使用 overflow 也可能会让其他开发人员感到困惑。为什么 overflow 设置为 autoscroll?最初的开发者的意图是什么?他们想要这个组件上的滚动条吗?

最安全的做法应该是创建一个 BFC 时并不会带来任何副作用,它内部的元素都安全的呆在这个迷你布局中,这种方法不会引起任何意想不到的问题,也可以理解开发者的意图。CSS 工作组也十分认同这种想法,所以他们定制了一个新的属性值:display:flow-root

flow-root 浏览器支持情况

你可以使用display:flow-root安全的創建BFC,來解決上文中提到的各種問題:包裹浮動元素、阻止外邊距疊加和阻止圍繞浮動元素。

深入淺析CSS 佈局和 BFC

瀏覽器對該屬性的支援目前還是有限的,如果你覺得這個屬性值很方便,請投票去讓Edge也支援它。不過無論如何,你現在應該已經理解了什麼是BFC,以及如何使用overflow 或其他方法來包裹浮動,以及知道了BFC 可以阻止元素去環繞浮動元素,如果你想使用彈性或網格佈局可以在一些不支援他們的瀏覽器中使用BFC 的這些特性做降級處理。

理解瀏覽器如何佈置網頁是非常基礎的。雖然有時看起來無關緊要,但這些小知識可以加快創建和調試 CSS 佈局所需的時間。

以上是深入淺析CSS 佈局和 BFC的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除