CSS進階05-行內格式上下文IFC

1. IFC與line box

IFC的英文全稱是:Inline Formatting Contexts,直譯為“行內格式化上下文”。
IFC由一個不包含塊級盒的塊容器盒生成。
在行內格式化上下文中,盒從包含塊的頂部開始一個接一個地水平擺放。盒水平方向的外邊距、邊框和內邊距在布局時都會考慮在內。盒的垂直對齊方式則不一:可能按底部或者頂部對齊,又或者按它們內容文本的基線對齊。包含了形成一行的那些盒的矩形區域被稱為行盒 Line Box 。

2. 行盒的高度

用戶代理將行內級盒流入到一個行盒組成的垂直棧中。行盒的高度計算規則如下:

  1. 計算行盒內每個行內級盒的高度。對于替換元素replaced elements、行內塊元素nline-block elements以及行內表格元素inline-table elements,高度是其margin box的高度;對于行內盒,高度是其 line-height。(參考 "Calculating heights and margins" 和 在 "Leading and half-leading"里的height of inline boxes)

  2. 行內級盒根據其 vertical-align 屬性垂直對齊。如果它們對齊 top 或 bottom,它們必須對齊,以便使行盒高度最小化。如果這些盒足夠高,則有多種解決方案并且CSS2.2沒有規定此行盒的基線的位置(即,strut的位置,參見下文)。

  3. 行盒高度是最上盒頂部到最下盒底部的距離。(包括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

在內容由行內級元素組成的塊容器元素上,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

vertival-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 的寬度,這些盒可能按如下情況分布:


image.png

可以看到:

  • 外邊距插在了 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分析

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,835評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,676評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,730評論 0 380
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,118評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,873評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,266評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,330評論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,482評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,036評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,846評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,025評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,575評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,279評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,684評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,953評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,751評論 3 394
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,016評論 2 375

推薦閱讀更多精彩內容

  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標簽默認的外補...
    _Yfling閱讀 13,776評論 1 92
  • 一、BFC是什么? 它是 Block Formatting Context (塊級格式化上下文) 的簡稱,接下來通...
    07120665a058閱讀 3,812評論 15 40
  • (注1:如果有問題歡迎留言探討,一起學習!轉載請注明出處,喜歡可以點個贊哦!)(注2:更多內容請查看我的目錄。) ...
    love丁酥酥閱讀 662評論 0 3
  • 這是我第一次在簡書這個平臺寫一些感想,也是第一次將自己生活中的感想通過寫文章的方式表達出來。 今天換乘地鐵的時候,...
    顧堯閱讀 444評論 0 0
  • Acitvity的LaunchMode 多次啟動同一個Activity時,系統會創建多個實例并把它們一一放入任務棧...
    zhuzhiqiang00閱讀 156評論 0 0