CSS

All About The Containing Block

所有含块包

元素的大小和位置通常受其含块包的影响。大多数情况下,包含块是元素最近的块级祖先的内容区域,但情况并非总是如此。

当用户代理(如浏览器)布局文档时,它会为每个元素生成一个框。每个盒子分为四个区域:

  • 内容区域

许多开发人员认为,元素的包含块始终是其父项的内容区域。但这是错误的!继续阅读...

为什么识别包含块很重要?

元素的大小和位置通常受其包含块的影响。被施加到所述百分比值widthheightpaddingmargin,和offset绝对定位的元素(即,其具有它的性能position设置为absolutefixed)从元件的包含块计算的。

我们如何识别containing block

标识包含块的过程完全取决于元素position属性的值:

  • 如果position属性为staticrelative,则包含块由作为块容器的最近的祖先元素(例如内嵌块,块或列表项元素)的内容框的边缘形成,或者其建立格式化上下文(如表格容器,弹性容器,网格容器或块容器本身)。

注意:根元素(<html>)所在的包含块是一个称为初始包含块的矩形。它具有视口的尺寸(用于连续媒体)或页面区域(用于分页媒体)。

计算来自包含块的百分比值

如上所述,当给定某个属性的百分比值时,计算值取决于该元素的包含块。以这种方式工作的属性是框模型属性和偏移属性:

  • heighttopbottomproperties计算包含块的_height_的百分比值。如果heightof包含块取决于它的内容,这些值成为0当含块具有positionrelativestatic

例子

我们所有例子的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

在这个例子中,段落positionfixed,所以它的包含块是初始包含块(在屏幕上,视口)。因此,段落的尺寸会根据浏览器窗口的大小而变化。

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; }