All About The Containing Block
所有含块包
元素的大小和位置通常受其含块包的
影响。大多数情况下,包含块是元素最近的块级祖先的内容区域,但情况并非总是如此。
当用户代理(如浏览器)布局文档时,它会为每个元素生成一个框。每个盒子分为四个区域:
- 内容区域
许多开发人员认为,元素的包含块始终是其父项的内容区域。但这是错误的!继续阅读...
为什么识别包含块很重要?
元素的大小和位置通常受其包含块的影响。被施加到所述百分比值width
,height
,padding
,margin
,和offset
绝对定位的元素(即,其具有它的性能position
设置为absolute
或fixed
)从元件的包含块计算的。
我们如何识别containing block
标识包含块的过程完全取决于元素position
属性的值:
- 如果
position
属性为static
或relative
,则包含块由作为块容器
的最近的祖先元素(例如内嵌块,块或列表项元素)的内容框
的边缘形成,或者其建立格式化上下文
(如表格容器,弹性容器,网格容器或块容器本身)。
注意:根元素(<html>)所在的包含块是一个称为初始包含块的矩形。它具有视口的尺寸(用于连续媒体)或页面区域(用于分页媒体)。
计算来自包含块的百分比值
如上所述,当给定某个属性的百分比值时,计算值取决于该元素的包含块。以这种方式工作的属性是框模型属性和偏移属性:
height
,top
和bottom
properties计算包含块的_height
_的百分比值。如果height
of包含块取决于它的内容,这些值成为0
当含块具有position
的relative
或static
。
例子
我们所有例子的HTML代码是:
<body>
<section>
<p>This is a paragraph!</p>
</section>
</body>
例1
在这个例子中,段落是静态定位的,所以它的包含块是<section>因为它是最接近块的容器的先例。
body {
background: beige;
}
section {
display: block;
width: 400px;
height: 160px;
background: lightgray;
}
p {
width: 50%; /* == 400px * .5 = 200px */
height: 25%; /* == 160px * .25 = 40px */
margin: 5%; /* == 400px * .05 = 20px */
padding: 5%; /* == 400px * .05 = 20px */
background: cyan;
}
例2
在这个例子中,段落的包含块是<body>元素,因为<section>它不是块容器,并且不建立格式化上下文。
body {
background: beige;
}
section {
display: inline;
background: lightgray;
}
p {
width: 50%; /* == half the body's width */
height: 200px; /* Note: a percentage would be 0 */
background: cyan;
}
例3
在这个例子中,段落的包含块是<section>,因为后者的position是absolute。段落的百分比值受其包含块的填充影响,但如果包含块的box-sizing值是border-box这种情况,情况就不会如此。
body {
background: beige;
}
section {
position: absolute;
left: 30px;
top: 30px;
width: 400px;
height: 160px;
padding: 30px 20px;
background: lightgray;
}
p {
position: absolute;
width: 50%; /* == (400px + 20px + 20px) * .5 = 220px */
height: 25%; /* == (160px + 30px + 30px) * .25 = 55px */
margin: 5%; /* == (400px + 20px + 20px) * .05 = 22px */
padding: 5%; /* == (400px + 20px + 20px) * .05 = 22px */
background: cyan;
}
例4
在这个例子中,段落position
是fixed
,所以它的包含块是初始包含块(在屏幕上,视口)。因此,段落的尺寸会根据浏览器窗口的大小而变化。
body {
background: beige;
}
section {
width: 400px;
height: 480px;
margin: 30px;
padding: 15px;
background: lightgray;
}
p {
position: fixed;
width: 50%; /* == (50vw - (width of vertical scrollbar)) */
height: 50%; /* == (50vh - (height of horizontal scrollbar)) */
margin: 5%; /* == (5vw - (width of vertical scrollbar)) */
padding: 5%; /* == (5vw - (width of vertical scrollbar)) */
background: cyan;
}
例5
在这个例子中,段落的position是absolute,所以它的包含块是<section>,这是最近的先例与一个transform属性不是none。
body {
background: beige;
}
section {
transform: rotate(0deg
width: 400px;
height: 160px;
background: lightgray;
}
p {
position: absolute;
left: 80px;
top: 30px;
width: 50%; /* == 200px */
height: 25%; /* == 40px */
margin: 5%; /* == 20px */
padding: 5%; /* == 20px */
background: cyan;
}