佈局和包含塊
元素的大小和位置通常會受到其**包含塊**的影響。大多數情況下,包含塊是元素最近的**塊級**祖先的**內容區域**,但這並非總是如此。在本文中,我們將探討確定元素包含塊的因素。
當用戶代理(如您的瀏覽器)佈局文件時,它會為每個元素生成一個盒子。每個盒子被分成四個區域
- 內容區域
- 填充區域
- 邊框區域
- 外邊距區域
許多開發人員認為元素的包含塊始終是其父元素的內容區域,但這並不一定正確。讓我們研究一下決定元素包含塊的因素。
包含塊的影響
在瞭解是什麼決定了元素的包含塊之前,瞭解它為什麼重要是有幫助的。
元素的大小和位置通常會受到其包含塊的影響。應用於絕對定位元素的**width**、**height**、**padding**、**margin**和偏移屬性的百分比值(即其**position**設定為**absolute**或**fixed**)是根據元素的包含塊計算的。
識別包含塊
識別包含塊的過程完全取決於元素的**position**屬性的值
- 如果**
position**屬性是**static**、**relative**或**sticky**,則包含塊由最近祖先元素的內容框邊緣形成,該祖先元素要麼是**塊級容器**(例如內聯塊、塊或列表項元素),要麼**建立格式化上下文**(例如表格容器、flex 容器、網格容器或塊級容器本身)。 - 如果**
position**屬性是**absolute**,則包含塊由最近祖先元素的填充框邊緣形成,該祖先元素的**position**值不為**static**(**fixed**、**absolute**、**relative**或**sticky**)。 - 如果**
position**屬性是**fixed**,則包含塊由**視窗**(在連續媒體的情況下)或頁面區域(在分頁媒體的情況下)建立。 - 如果**
position**屬性是**absolute**或**fixed**,則包含塊也可以由最近祖先元素的填充框邊緣形成,該祖先元素具有以下任何屬性- **
filter**、**backdrop-filter**、**transform**或**perspective**值不為**none**。 - 當
contain屬性的值為layout、paint、strict或content(例如contain: paint;)時。 - 當
container-type屬性的值不為normal時。 - 當
will-change屬性的值包含一個屬性,該屬性的非初始值會形成包含塊(例如filter或transform)時。 - 當
content-visibility屬性的值為auto時。
- **
注意: 根元素(<html>)所在的包含塊是一個稱為初始包含塊的矩形。它的尺寸與視窗(對於連續媒體)或頁面區域(對於分頁媒體)的尺寸相同。
注意: 瀏覽器在 perspective 和 filter 屬性是否參與形成包含塊方面存在不一致。
從包含塊計算百分比值
一些示例
我們所有示例的 HTML 程式碼如下:
<body>
<section>
<p>This is a paragraph!</p>
</section>
</body>
以下每個示例中只更改 CSS。
示例 1
在本例中,段落是靜態定位的,因此它的包含塊是 <section>,因為它是最接近的祖先,並且是一個塊級容器(由於 display: block)。
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> 不是一個塊級容器(由於 display: inline),並且沒有建立格式化上下文。
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。段落的百分比值受其包含塊的 padding 影響,但是如果包含塊的 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>,它是具有非 none 的 transform 屬性的最接近的祖先。
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;
}
另請參閱
all屬性contain屬性aspect-ratio屬性box-sizing屬性min-content和max-content尺寸值- 構建塊:在 CSS 中對專案進行尺寸設定
- 盒子模型
- CSS 盒模型 模組
- 佈局模式
- 視覺格式化模型
- 塊級格式化上下文
- 堆疊上下文
- 邊距摺疊
- 初始、計算、使用 和 實際 值
- 替換元素
- 內在尺寸