熟悉又陌生的containing block

什麼是containing block?

若是乾巴巴的問一個前端什麼是containing block。大部分都不知所云。官方示意以下:css

The size and position of an element are often impacted by its containing block. Most often, the containing block is the content area of an element's nearest block-level ancestor, but this is not always the case. In this article, we examine the factors that deterime an element's containing block.前端

簡單來講就是——無特殊狀況下,containing block(包含塊)就是最近的塊元素的content area(內容區)chrome

什麼是內容區?

以這個經典的盒模型圖:瀏覽器

最內部的即爲內容區。less

咱們平時用到過嗎?

這個概念雖然可能不熟悉,可是實際上咱們常常用到:佈局

/* <div class="outer"> <div class="inner"></div> </div> */
.outer {
    width: 200px;
    box-sizing: border-box;
}
.inner {
    width: 80%;
}
複製代碼

inner的寬度是多少呢?毫無疑問,是160px。那稍微加一點戲,若是outer增長一條屬性padding: 50px,這時候inner的寬度是多少?ui

不少人會遲疑一下,由於不知道背後的原理,只能根據經驗推斷,若是經驗老道,會給出正確答案:80pxthis

實際上,這些百分比值的運做原理都是經過包含塊來計算出最後結果。再回想一下以前的規範,包含塊是最近的塊元素的內容區,就能夠很清晰的理解padding值在這個例子中起的做用了。spa

元素的尺寸和位置常常受其包含塊的影響。3d

特殊狀況

若是敏感的人看到這可能會產生一個疑惑,若是把例子改爲這樣?

.outer {
    position: relative;
    width: 200px;
    padding: 50px;
    box-sizing: border-box;
}
.inner {
    position: absolute;
    width: 80%;
}
複製代碼

這時候inner width又是多少呢?是160px

好不容易剛消化的知識就給了當頭一棍。。。而後回想一下平時用的時候好像確實是這樣!

因此規範提到了無特殊狀況下,而特殊狀況是:

  • 若是position是absolute,包含塊就是它最近的position值不是static的元素的padding area
  • 若是position是fixed,包含塊就是視圖。
  • 若是position是absolutefixed,包含塊是最近的知足下列條件的元素的padding area
    • transform或perspective值不是none
    • filter值不是none
    • will change值包含transform、perspective、或filter(只有Firefox有效)

position: fixed

瞭解了包含塊的規範,能夠更好的理解平時經常使用的一些特性的運行原理。而特殊狀況的最後一點,其實還有一些場景能夠利用。

好比以下場景:

引入了一個三方ui庫,內部有一個彈窗組件,很正常的使用了fixed定位,那它的包含塊就是視圖了。若是這時,須要將它的位置進行調整,那怎麼辦?

能夠利用transform/perspective/filter來改變這個彈窗所在的內容塊,從而起到定位的做用。

contain

理解了包含塊,可以將特性運用到一些特定場景中,已經說明知識點消化的足夠好了。可是下面的彩蛋知識點,還須要一點運氣才能得到~由於它並無在包含塊的MDN文檔中被說起。

chrome率先實現了一個實驗特性contain。它容許開發者聲明當前元素和它的內容儘量的獨立於 DOM 樹的其餘部分。從而使得瀏覽器在從新計算佈局、樣式、繪圖或它們的組合的時候,只會影響到有限的 DOM 區域,而不是整個頁面。

在它的可選值中,paint的做用是使得該元素的子孫節點不會超出它的邊緣。

那父元素contain: paint和子元素position: fixed結合會如何呢?

實驗結果是,fixed的元素表現得像是父元素設置了transform/perspective/filter同樣,說明它的包含塊被contain: paint屬性所影響。

MDN文檔中沒提到,那是Chrome意外實現了一個彩蛋嗎?

確認了規範之後證明,Chrome並非xjb實現的~

The element acts as a containing block for absolutely positioned and fixed positioned descendants.




參考

  1. Layout and the containing block
  2. contain
  3. containment-paint
相關文章
相關標籤/搜索