定位和层叠上下文
布局
块级上下文
层叠上下文
布局与包含块
一个元素的尺寸和位置经常受其**包含块(containing block)**的影响。大多数情况下,包含块就是这个元素最近的祖先块元素的内容区,但也不是总是这样。在本文中,我们来过一遍确定包含块的所有因素。
当一个客户端代理(比如说浏览器)展示一个文档的时候,对于每一个元素,它都产生了一个盒子。每一个盒子都被划分为四个区域:
- 内容区
- 内边距区
- 边框区
- 外边距区

许多开发者认为一个元素的包含块就是他的父元素的内容区。但事实并非如此。接下来让我们来看看,确定元素包含块的因素都有哪些。
包含块的影响
在学习如何确定元素包含块之前,先了解一下它的重要性。
元素的尺寸及位置,常常会受它的包含块所影响。对于一些属性,例如 width, height, padding, margin,绝对定位元素的偏移值 (比如 position 被设置为 absolute 或 fixed),当我们对其赋予百分比值时,这些值的计算值,就是通过元素的包含块计算得来。
确定包含块
确定一个元素的包含块的过程完全依赖于这个元素的 position 属性:
- 如果
position属性为static、**relative** 或sticky,包含块可能由它的最近的祖先块元素(比如说inline-block,block或list-item元素)的内容区的边缘组成,也可能会建立格式化上下文(比如说a table container,flex container,grid container, 或者是the block container自身)。 - 如果
position属性为absolute,包含块就是由它的最近的position的值不是static(也就是值为fixed,absolute,relative或sticky)的祖先元素的内边距区的边缘组成。 - 如果
position属性是 **fixed**,在连续媒体的情况下(continuous media)包含块是 viewport ,在分页媒体(paged media)下的情况下包含块是分页区域(page area)。 - 如果 position 属性是**
absolute或fixed**,包含块也可能是由满足以下条件的最近父级元素的内边距区的边缘组成的:transform或perspective的值不是nonewill-change的值是transform或perspectivefilter的值不是none或will-change的值是filter(只在Firefox下生效).contain的值是paint(例如:contain: paint;)
注意: 根元素(
<html>)所在的包含块是一个被称为初始包含块的矩形。他的尺寸是视口 viewport (for continuous media) 或分页媒体 page media (for paged media).
根据包含块计算百分比值
如上所述,如果某些属性被赋予一个百分值的话,它的计算值是由这个元素的包含块计算而来的。这些属性包括盒模型属性和偏移属性:
- 要计算
heighttop及bottom中的百分值,是通过包含块的height的值。如果包含块的height值会根据它的内容变化,而且包含块的position属性的值被赋予relative或static,那么,这些值的计算值为 auto。 - 要计算
width,left,right,padding,margin这些属性由包含块的width属性的值来计算它的百分值。
示例:
1 | <body> |
例一:position:static
这个示例中,P 标签设置为静态定位,所以它的包含块为 <section> ,因为距离最近的父节点即是她的包含块。
1 | body { |

例二:position:static
在这个示例中,P 标签的包含块为 <body> 元素,因为 <section> 不再是一个块容器,所以并没有形成一个格式上下文。
1 | body { |

例三:position:absolute
这个示例中,P元素的包含块是 <section>,因为 <section> 的 position 为 absolute 。P 元素的百分值会受其包含块的 padding 所影响。不过,如果包含块的 box-sizing 值设置为 border-box ,就没有这个问题。
1 | body { |

例四:position:fixed
这个示例中,P 元素的 position 为 fixed,所以它的包含块就是初始包含块(在屏幕上,也就是 viewport)。这样的话,P 元素的尺寸大小,将会随着浏览器窗框大小的变化,而变化。
1 | body { |

例五:position:absolute
这个示例中,P 元素的 position 为 absolute,所以它的包含块是 <section>,也就是距离它最近的一个 transform 值不为 none 的父元素。
1 | body { |




