文章將陸續整理並更新至個人部落格。
每個元素會生成零(display: none 時)至多個盒子(例如 display 為 list-item 時),盒子(box)可以裝盒子,不同的盒子會依據它所屬的格式化上下文(formatting context)類型來排列,不同的格式化上下文有不同的佈局規則。在正式介紹格式化上下文之前,需要先了解包含塊(Containing block)
是什麼,它攸關元素的位置
、寬高
、內外距
的計算。
每個元素會生成一個盒子,甚至多個盒子,而盒子的位置
與尺寸
會以它的包含塊
(containing block)為基準
來計算。例如在元素設定寬度
(width)、高度
(height)、內距
(padding)、外距
(margin)這些屬性時,若屬性值給予百分比
,將會以元素的包含塊為基準
去做計算,再例如,使用 position
屬性時,也是以包含塊作為參考定位
。
[W3C]對於包含塊的定義為:
A rectangle that forms the basis of sizing and positioning for the boxes associated with it (usually the children of the box that generated it). Notably, a containing block is not a box (it is a rectangle), however it is often derived from the dimensions of a box. If properties of a containing block are referenced, they reference the values on the box that generated the containing block.
一個元素的尺寸和位置會受到其包含塊的影響,包含塊是一個矩形
(rectangle),一個由內容區
(content area)或內距邊緣
(padding edge)所圍繞的範圍。
根元素
<html> 的包含塊稱為初始包含塊
(initial containing block)。
若元素 position
屬性值為 static
、relative
或 sticky
,包含塊為距離它最近
的祖先塊元素
或格式化上下文
(formatting context)的內容區邊緣
組成。
position
屬性為 absolute
,包含塊為距離它最近
且 position
屬性值不是 static
(即為fixed、absolute、relative 或 sticky)的祖先元素
的內距邊緣
組成。若元素 position
屬性為 fixed
,包含塊為 viewport
。
如果 position
屬性是 absolute
或 fixed
,包含塊也可能是由滿足以下條件的最接近祖先元素
的內容區邊緣組成:
transform
屬性值不為 none
。contain
屬性值不為 none
。註:若祖先塊元素皆無 position 屬性為非 static,則最後將以根元素 <html> 為參考定位。
找出 <p> 的包含塊,並且計算出 <p> 最終的寬、高、內距與外距。
在此例子中,因為 <p> 的 position 值為預設的 static,故其包含塊為距離它最近的塊元素 <section> 的內距邊緣所圍範圍。<p> 的 width、 height、margin 與 padding 皆會以 <section> 為基準來計算。
需特別注意的是,margin
與 padding
是以包含塊
的寬度為基準
。
<body>
<section>
<p>This is a paragraph!</p>
</section>
</body>
section {
display: block;
width: 400px;
height: 160px;
}
p {
width: 50%; /* == 400px * .5 = 200px */
height: 25%; /* == 160px * .25 = 40px */
margin: 5%; /* == 400px * .05 = 20px */
padding: 5%; /* == 400px * .05 = 20px */
}
現在將 <section> 改為 display: inline。
找出 <p> 的包含塊,並且計算出 <p> 最終的寬度。
在此例子中,<p> 的 position 依舊是預設的 static,但是 <section> 不再是塊容器,沒有形成一個格式化上下文,故 <p> 的包含塊為 <body> 內距邊緣所圍範圍。
<p> 的寬度將以 <body> 為基準計算。
<body>
<section>
<p>This is a paragraph!</p>
</section>
</body>
section {
display: inline;
}
p {
width: 50%; /* == half the <body>'s width */
height: 200px; /* Note: a percentage would be 0 */
}
包含塊有內距(padding)。
找出 <p> 的包含塊,並且計算出 <p> 的最終寬度、高度、外距與內距。
在此例中,P元素的包含塊是 <section>,因為 <section> 的 position 值非 static。
<p> 百分值會受其包含塊 <section> 的 padding 所影響。若將包含塊的 box-sizing 值設置為 border-box,就可以避免這個問題。
<body>
<section>
<p>This is a paragraph!</p>
</section>
</body>
section {
position: absolute;
left: 30px;
top: 30px;
width: 400px;
height: 160px;
padding: 30px 20px;
}
p {
position: absolute;
width: 50%; /* == (400px + 20px + 20px) * 50% = 220px */
height: 25%; /* == (160px + 30px + 30px) * 25% = 55px */
margin: 5%; /* == (400px + 20px + 20px) * 5% = 22px */
padding: 5%; /* == (400px + 20px + 20px) * 5% = 22px */
}
包含塊的介紹就告一段落囉!
明天見~
此文章為學習筆記,如有錯誤,麻煩告知,非常感謝!
W3C-Containing blocks
MDN-Layout and the containing block
每天來點 CSS Specification-Visual Formatting Model - 定義、containing block
讚啦包含塊,前端一定要知道的 containing block 被你解釋得好清楚
...Askie大神講話要憑良心啊
說得超精細的,推推~~
看RU~大師的鐵人寫鐵人
竟然沒把 Ru 大師的經典放在參考資源
哈哈哈哈已補!!
長知識了
今天是什麼風把三位大神吹來了...
我是隔壁村.平凡.不會打怪.樸實鄉民 跟著來看熱鬧! 推推
你是同村.不平凡.狂升等.GM 根本是來湊熱鬧 XD
集滿四位大神~!