什么是containing block?

什么是containing block?

如果干巴巴的问一个前端什么是containing block。大部分都不知所云。官方示意如下:

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(内容区)

什么是内容区?

以这个经典的盒模型图:

最内部的即为内容区。

我们平时用到过吗?

这个概念虽然可能不熟悉,但是实际上我们经常用到:

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

inner的宽度是多少呢?毫无疑问,是160px。那稍微加一点戏,如果outer增加一条属性padding: 50px,这时候inner的宽度是多少?

很多人会迟疑一下,因为不知道背后的原理,只能根据经验推断,如果经验老道,会给出正确答案:80px

实际上,这些百分比值的运作原理都是通过包含块来计算出最后结果。再回想一下之前的规范,包含块通常是最近的块元素的内容区,就可以很清晰的理解padding值在这个例子中起的作用了。

元素的尺寸和位置经常受其包含块的影响。

特殊情况

如果敏感的人看到这可能会产生一个疑惑,如果把例子改成这样?

.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,包含块就是视图,就是整个view可视范围视窗。
  • 如果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

知识共享署名4.0国际许可协议,转载请保留出处; 部分内容来自网络,若有侵权请联系我:前端学堂 » 什么是containing block?

赞 (3) 打赏

评论 0

如果对您有帮助,别忘了打赏一下宝宝哦!

支付宝扫一扫打赏

微信扫一扫打赏