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阅读 219,753评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,668评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,090评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,010评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,054评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,806评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,484评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,380评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,873评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,021评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,158评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,838评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,499评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,044评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,159评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,449评论 3 374
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,136评论 2 356

推荐阅读更多精彩内容

  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,754评论 1 92
  • 一、BFC是什么? 它是 Block Formatting Context (块级格式化上下文) 的简称,接下来通...
    07120665a058阅读 3,808评论 15 40
  • (注1:如果有问题欢迎留言探讨,一起学习!转载请注明出处,喜欢可以点个赞哦!)(注2:更多内容请查看我的目录。) ...
    love丁酥酥阅读 653评论 0 3
  • 这是我第一次在简书这个平台写一些感想,也是第一次将自己生活中的感想通过写文章的方式表达出来。 今天换乘地铁的时候,...
    顾尧阅读 402评论 0 0
  • Acitvity的LaunchMode 多次启动同一个Activity时,系统会创建多个实例并把它们一一放入任务栈...
    zhuzhiqiang00阅读 151评论 0 0