解析 CSS 格式化上下文

JS菌發表於2019-04-16

art-materials-art-supplies-blocks-1148496.jpg

⭐️ 更多前端技術和知識點,搜尋訂閱號 JS 菌 訂閱

✴️ BFC 塊級格式化上下文

BFC(Block Formatting Contexts),塊級格式化上下文。BFC 實際上就是頁面中一塊渲染區域,該區域與其他區域隔離開來。容器裡面子元素不會影響到外部,外部的元素也不會影響到容器裡面的子元素。 ?

20190415083216.png

規範

BFC 內部的盒子會從上至下一個接著一個順序排列。BFC 內的垂直方向的盒子距離以 margin 屬性為準,上下 margin 會疊加。每個元素的左側最外層邊界與包含塊 BFC 的左邊相接觸(對於從左往右的格式化,否則相反)。即使存在浮動也是如此。BFC 的區域不會與 float box 摺疊。BFC 的高度也會受到浮動元素的影響,浮動元素參與計算。 ?

主要作用

  • 建立獨立的渲染環境
  • 防止因浮動導致的高度塌陷
  • 防止上下相鄰的外邊距摺疊

如何建立 BFC

  • html 元素本身就是 BFC
  • display === flow-root/inline-block/table-cell/table-caption/table/table-row/table-row-group/table-header-group/table-footer-group/inline-table/flex/inline-flex/grid/inline-grid
  • position === absolute/fixed
  • contain === strict/layout/paint/content
  • float !== none
  • overflow !== visible ✔️ 最常用
  • column-count !== auto
  • column-width !== auto
  • column-span === all

display 為 table 會產生一個匿名的 table-cell;display 為 flow-rot 是一種 flow 佈局,在 CSS2 中被引入。contain 屬性可以更有效率的渲染元素,但相容性差,詳情見:developers.google.com/web/updates… 佈局、grid 佈局產生的格式化上下文,有時也被人稱為 FFC/GFC

幾個例子

防塌陷 ?

div {
    border: 1px solid gray;
    /* overflow: hidden; */
}
p {
    float: left;
}
複製程式碼
<div>
    <p></p>
</div>
複製程式碼

20190415162559.png

建立 BFC 後

20190415162746.png

避免摺疊 ?

div:nth-of-type(2) {
    background: red;
    /* overflow: hidden; */
}
.this {
    border: 1px solid gray;
    margin: 20px 0;
}
複製程式碼
<div class="this">1️⃣</div>
<div>
    <div class="this">2️⃣</div>
</div>
複製程式碼

20190415163838.png

建立 BFC 後

20190415163855.png

✳️ IFC 內聯格式化上下文

IFC(Inline Formatting Contexts),內聯格式化上下文。IFC 中的 line-box (也稱行盒)的高度是根據包含行內元素中最高的實際高度計算而來。(不受垂直方向的 padding/margin 的影響) ?

相關知識點

頂點、中線、基線、底線,以及行距、半行距、font-size 大小、line-height 大小見圖:

20190415105958.png

  • inline-box 行內框,高度由 font-size 決定
  • line-box 行框,高度由該行框內最大高度的行內框決定
  • content area 內容區域,高度是 font-size 和 padding 的和
  • containing box 包含框,最外層的包裹盒子

20190415110851.png

line-height 的計算方法:

  • 固定值,如果設定了固定的值,如 20px,那麼行高即為 20px
  • 百分比,當前 font-size * 百分比,即為行高
  • normal 或數字,normal 則是瀏覽器預設設定的值,一般為 1.2,如果是自定義的數值,比如 1.5,那麼行高即為 font-size * 1.5

有關 line-height 的計算方法見這篇文章 segmentfault.com/a/119000000…

規範

行內元素從包含塊頂端水平方向上逐一排列,水平方向上的 margin/border/padding 生效。行內元素在垂直方向上可按照頂部、底部或基線對其。

當幾個行內元素不能在一個單獨的行盒中水平放置時,他們會被分配給兩個或更多的(vertically-stacked line boxes)垂直棧上的行盒,因此,一個段落是很多行盒的垂直棧。這些行盒不會在垂直方向上被分離(除非在其他地方有特殊規定),並且他們也不重疊。

  • 垂直方向上,當行內元素的高度比行盒要低,那麼 vertical-align 屬性決定垂直方向上的對齊方式。
  • 水平方向上,當行內元素的總寬度比行盒要小,那麼行內元素在水平方向上的分部由 text-align 決定。
  • 水平方向上,當行內元素的總寬度超過了行盒,那麼行內元素會被分配到多個行盒中去,如果設定了不可折行等屬性,那麼行內元素會溢位行盒。
  • 行盒的左右兩邊都會觸碰到包含塊,而 float 元素則會被放置在行盒和包含快邊緣的中間位置。

折行:

<p>balabala ...<span class="hl">hello world</span> inline formating context</p>
複製程式碼

空間不足的折行:

20190415161348.png

主要作用

  • 行內元素按照 text-align 進行水平居中
  • 行內元素撐開父元素高度,通過 vertical-align 屬性進行垂直居中

水平垂直居中 ?

<p>hello <span class="big">world</span> inline formating context</p>
複製程式碼
p {
    border: 1px solid gray;
    text-align: center;
}

.big {
    font-size: 60px;
    vertical-align: middle;
}
複製程式碼

其他還有 GFC、FFC 就是二維的網格佈局和自適應的 Flex 佈局。兩種佈局產生網格佈局格式化上下文和自適應格式化上下文。

參考:

JS 菌公眾賬號

請關注我的訂閱號,不定期推送有關 JS 的技術文章,只談技術不談八卦 ?

相關文章