BFC與IFC概念理解+佈局規則+造成方法+用處

想要理解BFC與IFC,首先要理解另外兩個概念:BoxFC(即 formatting context)。css

Box

一個頁面是由不少個 Box 組成的,元素的類型和 display 屬性決定了這個 Box 的類型。不一樣類型的 Box,會參與不一樣的 Formatting Context。html

Block level的box會參與造成BFC,好比display值爲block,list-item,table的元素。css3

Inline level的box會參與造成IFC,好比display值爲inline,inline-table,inline-block的元素。less

參考:W3C文檔block-levelide

FC(Formatting Context)

它是W3C CSS2.1規範中的一個概念,定義的是頁面中的一塊渲染區域,而且有一套渲染規則,它決定了其子元素將如何定位,以及和其餘元素的關係和相互做用佈局

常見的Formatting Context 有:Block Formatting Context(BFC | 塊級格式化上下文) 和 Inline Formatting Context(IFC |行內格式化上下文)。flex

下面就來介紹IFC和BFC的佈局規則。spa

IFC佈局規則:

在行內格式化上下文中,框(boxes)一個接一個地水平排列,起點是包含塊的頂部。水平方向上的 marginborderpadding在框之間獲得保留。框在垂直方向上能夠以不一樣的方式對齊:它們的頂部或底部對齊,或根據其中文字的基線對齊。包含那些框的長方形區域,會造成一行,叫作行框。3d

BFC佈局規則:

W3C原文:code

Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with 'overflow' other than 'visible' (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents.

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 may become narrower due to the floats).

整理爲中文:

  1. 內部的Box會在垂直方向,一個接一個地放置。

  2. Box垂直方向的距離由margin決定。屬於同一個BFC的兩個相鄰Box的margin會發生重疊

  3. 每一個元素的左外邊緣(margin-left), 與包含塊的左邊(contain box left)相接觸(對於從左往右的格式化,不然相反)。即便存在浮動也是如此。除非這個元素本身造成了一個新的BFC。

  4. BFC的區域不會與float box重疊。

  5. BFC就是頁面上的一個隔離的獨立容器,容器裏面的子元素不會影響到外面的元素。反之也如此。

  6. 計算BFC的高度時,浮動元素也參與計算

參考:
W3C文檔inline-formatting
W3C文檔block-formatting

怎樣造成一個BFC?

塊級格式化上下文由如下之一建立:

  1. 根元素或其它包含它的元素

  2. 浮動 (元素的 float 不是 none)

  3. 絕對定位的元素 (元素具備 positionabsolutefixed)

  4. 非塊級元素具備 display: inline-block,table-cell, table-caption, flex, inline-flex

  5. 塊級元素具備overflow ,且值不是 visible

整理到這兒,對於上面第4條產生了一個small small的疑問:爲何display: inline-block;的元素是inline level 的元素,參與造成IFC,卻能建立BFC?

後來以爲答案是這樣的:inline-block的元素的內部是一個BFC,可是它自己能夠和其它inline元素一塊兒造成IFC。

BFC用處

1. 清除浮動

<div class="wrap">
<section>1</section>
<section>2</section>
</div>
.wrap {
  border: 2px solid yellow;
  width: 250px;
}
section {
  background-color: pink;
  float: left;
  width: 100px;
  height: 100px;
}

能夠看到,因爲子元素都是浮動的,受浮動影響,邊框爲黃色的父元素的高度塌陷了。

BFC1

解決方案:爲 .wrap 加上 overflow: hidden;使其造成BFC,根據BFC規則第六條,計算高度時就會計算float的元素的高度,達到清除浮動影響的效果。

BFC2

2. 佈局:自適應兩欄佈局

<div>
<aside></aside>
<main>我是好多好多文字會換行的那種蛤蛤蛤蛤蛤蛤蛤蛤蛤蛤蛤蛤蛤</main>
</div>
div {width: 200px;}
aside {
  background-color: yellow;
  float: left;
  width: 100px;
  height: 50px;
}
main {
  background-color: pink;
}

能夠看到右側元素的一部分跑到了左側元素下方。

BFC3

解決方案:爲main設置 overflow: hidden; 觸發main元素的BFC,根據規則第四、5條,BFC的區域是獨立的,不會與頁面其餘元素相互影響,且不會與float元素重疊,所以就能夠造成兩列自適應佈局

BFC4

3. 防止垂直margin合併

<section class="top">1</section>
<section class="bottom">2</section>
section {
  background-color: pink;
  margin-bottom: 100px;
  width: 100px;
  height: 100px;
}
.bottom {
  margin-top: 100px;
}

BFC5

能夠看到,明明.top.bottom中間加起來有200px的margin值,可是咱們只能看到100px。這是由於他們的外邊距相遇發生了合併。

怎樣解決:爲其中一個元素的外面包裹一層元素。併爲這個外層元素設置 overflow: hidden;,使其造成BFC。由於BFC內部是一個獨立的容器,因此不會與外部相互影響,能夠防止margin合併。

BFC6

<section class="top">1</section>
<div class="wrap">
<section class="bottom">2</section>
</div>
.wrap {
  overflow: hidden;
}
相關文章
相關標籤/搜索