1. IFC與line box
IFC的英文全稱是:Inline Formatting Contexts,直譯為“行內格式化上下文”。
IFC由一個不包含塊級盒的塊容器盒生成。
在行內格式化上下文中,盒從包含塊的頂部開始一個接一個地水平擺放。盒水平方向的外邊距、邊框和內邊距在布局時都會考慮在內。盒的垂直對齊方式則不一:可能按底部或者頂部對齊,又或者按它們內容文本的基線對齊。包含了形成一行的那些盒的矩形區域被稱為行盒 Line Box 。
2. 行盒的高度
用戶代理將行內級盒流入到一個行盒組成的垂直棧中。行盒的高度計算規則如下:
計算行盒內每個行內級盒的高度。對于替換元素replaced elements、行內塊元素nline-block elements以及行內表格元素inline-table elements,高度是其margin box的高度;對于行內盒,高度是其 line-height。(參考 "Calculating heights and margins" 和 在 "Leading and half-leading"里的height of inline boxes)
行內級盒根據其 vertical-align 屬性垂直對齊。如果它們對齊 top 或 bottom,它們必須對齊,以便使行盒高度最小化。如果這些盒足夠高,則有多種解決方案并且CSS2.2沒有規定此行盒的基線的位置(即,strut的位置,參見下文)。
行盒高度是最上盒頂部到最下盒底部的距離。(包括struct,解釋參見下述 line-height。)
空的行內元素生成空的行內盒,但這些盒仍然有margins, padding, borders 和一個行高line height,因此跟有內容的元素一樣會影響計算。
2.1 行距Leading和半行距half-leading
CSS假定每種字體都有字體指標,用于指定基線以上的特征高度和指定其下的深度。在本節中,我們使用A來表示高度(給定尺寸的給定字體)和D深度。我們還定義AD = A + D,即從頂部到底部的距離。(有關如何為TrueType和OpenType字體查找 A和D的說明,請參閱下面的注釋)請注意,這些是整個字體的度量標準,不需要與任何單個字形的上行和下行對應。
用戶代理必須通過其相關基線將非替換的行內框中的字形彼此對齊。然后,對于每個字形,確定A和D。需要注意的是在單個元素內的字形可能來自不同的字體,因此不需要都具有相同的A和D。如果行內盒完全不包含字形,則認為它包含了一個帶有元素的首個可用字體的A和D的支柱(一個零寬度的不可見字形) 。
接著對每個字符添加行距L,其中 L = line-height - AD。行距的一般添加到A之上,另一半添加到D之下,從而賦予字符以及其行距一個基線之上的完整高度 A' = A + L/2,以及完整深度 D' = D+ L/2。
注:L可能為負。
包含了所有字符以及字符兩側半行距的行內盒的高度正是 line-height。子元素的盒不影響這個高度。
盡管非替換元素的margins, borders和padding不納入行盒的計算,它們仍然渲染在行內盒的周圍。這意味著如果 line-height 指定的高度小于被包含盒的content height,padding和borders的backgrounds和colors可能會滲透到相鄰的行盒。用戶代理應當按文檔順序渲染這些盒。這會造成后面的盒的borders會在前面盒的邊框和文本上繪制。
注:CSS2.1沒有定義什么是行內盒的內容區域(參見文檔-10.6.1 ),因此不同的用戶代理可能把backgrounds和borders繪制在不同地方。
注:推薦OpenType和TrueType字體(在轉換到當前元素的字號后)的A和D使用該字體OS/2表格中的“sTypeAscender”和“sTypeDescender”特性。如果沒有這些特性,則使用HHEA表中的“Ascent”和“Descent”特性。
2.2 行高屬性line-height
在內容由行內級元素組成的塊容器元素上,line-height 指定該元素內行盒的最小高度minimal height。最小高度由基線上方的最小高度和下方的最小深度組成,就如同每個行盒以一個具有該元素字體和行高屬性的零寬度行內盒開始一樣。我們稱此虛構盒為“支柱 Strut ”。(該命名靈感源于Tex。)
字體在基線之上的高度和和基線之下的深度被假定為包含在字體內的特性。(更多細節,參見CSS3。)
在一個非替換行內元素上,line-height 指定一個高度用于計算行盒的高度。
line-height屬性的值具有如下意義:
normal:
讓用戶代理設使用值為一個基于元素字體的“合理”值。該值與< number >意義相同。我們推薦 normal 的使用值在1.0到1.2之間。計算值為 normal。< length >
指定長度用于計算行盒高度。負值非法。< number >
屬性的使用值為此數值乘以元素的字號。負值非法。計算值與指定值相同。< percentage >
屬性的計算值為此百分比乘以元素的字號計算值。負值非法。
下面例子中的三條規則的行高結果相同:
div { line-height: 1.2; font-size: 10pt } /* number */
div { line-height: 1.2em; font-size: 10pt } /* length */
div { line-height: 120%; font-size: 10pt } /* percentage */
當元素包含以多種字體渲染的文本時,用戶代理會根據最大字號來決定 normal 的 line-height 值。
注:如一個塊容器盒中的所有行內盒僅有一個 line-height 值并且所有行內盒字體相同(并且行內盒中不存在替換元素、行內塊元素等),上述將確保相鄰行的基線正好相隔 line-height。這在不同字體的文本列必須對齊時非常重要,比如在table中。
2.3 垂直對齊屬性vertical-align
此屬性影響行內級元素生成的盒子在行盒內的垂直定位。
注:該屬性值在表格上下文中有不同含義。請查閱table height algorithms一節了解詳情。
下述值僅相對于 父行內元素(parent inline element) 或 父塊容器元素的struct (the struct of a parent block container element)有意義。
在下述定義中,對行內非替換元素而言,用于對齊的盒是高度為 line-height 的盒(包括了盒的字形glyphs以及兩側的半行距half-leading,參見上面)。對于其他所有元素,用于對齊的盒是margin box。
baseline
將盒的基線與父盒的基線對齊。如果盒沒有基線,將其bottom margin edge與父盒的 baseline 對齊。middle
把盒的垂直中點同父盒的基線加上父盒一半的 x-height 對齊。sub
把盒的基線降到父盒的下標的適當位置。(此值對元素文本的字號無影響。)super
把盒的基線升到父盒的上標的適當位置。(此值對元素文本的字號無影響。)text-top
把盒的頂部同父級的內容區域的頂部對齊(參見 10.6.1)。text-bottom
把盒的底部同父級的內容區域的底部對齊(參見 10.6.1)。
< percentage >
把盒提升(正值)或降低(負值)指定距離(line-height 值的百分比)。值0% 意味著與 baseline 相同。< length >
把盒提升(正值)或降低(負值)指定距離。值0cm 意味著與 baseline 相同。
下面的值使元素相對于行盒對齊。由于元素可能有子元素相對于該元素對齊(子元素又可能擁有后代相對于子元素對齊),因此下面的值使用對齊子樹 aligned subtree 的邊界。一個行內元素的對齊子樹包括該元素以及 vertical-align 值不為 top 或 bottom 的所有子行內元素的所有對齊子樹。該對齊子樹的top是子樹內最高的盒頂部,bottom也是類似這樣。
top
把對齊子樹的頂部與行盒頂部對齊。bottom
把對齊子樹的底部與行盒底部對齊。
行內表格inline-table的基線是表格首行的基線。
行內塊的基線是其標準流內最后一個行盒的基線,除非該行內塊沒有 處于標準流內的行盒或者其 overflow 屬性計算值不為 visible,這種情況下基線為bottom margin edge緣。
綜合以上,行盒的高度總是足以容納其包含的所有盒。然而,它可能高于其所包含的最高盒(例如,如果盒子是對齊的,以便基線對齊)。當一個盒子B的高度小于包含它的行盒的高度時, 行盒內 B 的垂直對齊方式由 vertical-align 屬性決定。當在水平方向上幾個行內級盒不能完全被單個行盒包含時,它們會被分配到兩個或者多個垂直堆疊的行盒中。因此,一個段落就是多個行盒的垂直堆疊。行盒的堆疊沒有垂直間距(除非有特別聲明)并且從不重疊。
3. 行盒的寬度
一般來說,行盒的左邊緣緊貼其包含塊的左邊緣,其右邊緣緊貼包含塊的右邊緣。然而,浮動盒可能被置于包含塊和行盒邊緣之間。因此,盡管在同一行內格式化上下文中的行盒是等寬的(包含塊的寬度),由于浮動會造成可用的水平空間減少,行盒的寬度仍可能變動。同一行內格式化上下文中的行盒在高度上通常是變動的(比如,一行可能包含圖片但其他行僅包含文本)。
當一行中的行內級盒的總寬度小于包含它們的包含塊的時候,它們在行里的水平分布取決于 text-align 屬性。如果取 justify 值,用戶代理可能拉伸行內盒( inline-table 和 inline-block 盒除外)中的空格和字間距。
當行內盒的寬度超過行盒寬度時,行內盒將被分為多個盒,被分解出的盒則又分布在多個行盒中。如果一個行內盒不可切割(比如,行內盒包含的是單個字符或者語言指定的斷字規則不允許斷字,又或者行內盒的 white-space 屬性值為 nowrap 或 pre ),那么該行內盒將溢出行盒。
當行內盒被分割,外邊距、邊框和內邊距在任何斷點處都不會產生視覺影響。
行內盒也可能由于雙向文本處理而在一個行盒內被切割成多個盒。
為了包含行內格式化上下文中的行內級內容,行盒按需創建。對于“不包含文本,沒有保留的空白區域,沒有margins、padding、border不為零的行內元素,也沒有其他在標準流內 In-flow 內容(如圖片、行內塊或行內表格),并且不以保留的換行符結尾”的行盒,如果是為決定它們所包含的元素的定位,則必須視其為零高度的行盒,除此之外的其他目的下應視其為不存在。
下面是一個行內盒構造的例子。以下段落(由HTML塊級元素 p 創建)包含了穿插有 em 和 strong 匿名文本。
<p>Several <em>emphasized words</em> appear
<strong>in this</strong> sentence, dear.</p>
p 元素生成了一個包含五個行內盒的塊盒,其中三個行內盒是匿名的:
- 匿名:"Several"
- em:"emphasized words"
- 匿名:"appear"
- strong:"in this"
- 匿名:"sentence, dear."
為了格式化該段落,客戶端將五個行內盒放進若干行盒line boxes中。在這個例子中,由 p 元素生成的盒創建了這些行盒的包含塊。
如果該包含塊足夠寬,所有的行內盒將放置在單個行盒中,如下:
如果寬度不夠,行內盒就會被分割并分布在多個行盒中。段落可能就變成了:
或者:
在最后這個情況里, em 盒被分割成了兩個 em 盒(現稱之為 split1 和 split2 )。Margins, borders, padding, 或者 text decorations在 split1 之后或者 split2 之前都沒有視覺效果。看如下示例:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>Example of inline flow on several lines</title>
<style type="text/css">
EM {
padding: 2px;
margin: 1em;
border-width: medium;
border-style: dashed;
line-height: 2.4em;
}
</style>
</head>
<body>
<p>Several <em>emphasized words</em> appear here.</p>
</body>
</html>
根據 p 的寬度,這些盒可能按如下情況分布:
可以看到:
- 外邊距插在了 emphasized 之前和 words 之后
- 內邊距被插在了 emphasized 之前、上、下, words 值后、上、下。虛線邊框渲染在了每個單詞的三邊。
就好像這個盒子在單行排好以后被直接掰開成兩個一樣。
參考
https://www.w3.org/TR/CSS22/visuren.html#visual-model-intro
https://www.w3.org/TR/CSS2/visuren.html
CSS規范 > 9 視覺格式化模型 Visual Formatting Model
CSS規范 > 10 視覺格式化模型詳述 Visual Formatting Model Details
css中的IFC
css中的bfc和ifc
[譯]:BFC與IFC
淺析css中的BFC、IFC、GFC和FFC
css IFC 與 BFC分析