熟悉又陌生的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
相关文章
相关标签/搜索