1. 书写模式简介
CSS 书写模式第四级定义了支持多种国际书写模式的 CSS 功能,例如从左到右(例如拉丁文或印度文)、从右到左(例如希伯来文或阿拉伯文)、双向(例如混合的拉丁文和阿拉伯文)和垂直(例如亚洲文字)书写模式。
CSS 中的书写模式由 writing-mode、direction 和 text-orientation 属性决定。主要通过其 行内基础方向 和 块流方向 来定义:
行内基础方向是内容在一行中的主要排序方向,并定义了行的“开始”和“结束”各在何处。direction 属性指定了盒子的行内基础方向,并与 unicode-bidi 属性及任何文本内容的固有方向性一起,决定了行内级内容的排序。
块流方向是块级盒子堆叠的方向以及行盒在块容器内的堆叠方向。writing-mode 属性决定了块流方向。
排版模式决定文本是否应应用特定于垂直流的排版惯例,用于 垂直书写系统。这一概念将垂直书写系统的垂直流与旋转的水平流区分开来。
水平书写模式指具有水平文本行的书写模式,即向下或向上块流。垂直书写模式指具有垂直文本行的书写模式,即向左或向右块流。
这些术语不应与垂直块流(即向下或向上块流)和水平块流(即向左或向右块流)混淆。为避免混淆,CSS 规范避免使用后一组术语。
书写系统通常具有一种或两种原生书写模式。例如:
- 基于拉丁文的系统通常使用从左到右的行内方向和向下(从上到下)的块流方向。
- 基于阿拉伯文的系统通常使用从右到左的行内方向和向下(从上到下)的块流方向。
- 基于蒙古文的系统通常使用从上到下的行内方向和向右(从左到右)的块流方向。
- 基于汉字的系统通常使用从左到右的行内方向和向下(从上到下)的块流方向,或使用从上到下的行内方向和向左(从右到左)的块流方向。许多杂志和报纸会在同一页上混合这两种书写模式。
书写模式的 text-orientation 组件控制字形方向。
有关书写模式和垂直文本的更深入介绍,请参阅 Unicode 技术笔记 #22 [UTN22](HTML 版本)。
1.1. 模块交互
本模块替换并扩展了 unicode-bidi 和 direction 功能,这些功能在 [CSS2] 第 8.6 和 9.10 节中定义。其特性与其他文本操作在设定文本行中的交互在 CSS Text 3 § 文本处理操作顺序 中描述。
计算值 由 writing-mode、direction 和 text-orientation 属性(即使在这些属性本身不适用的元素上 [CSS-CASCADE-4])在很大程度上可以通过诸如字体相对长度的计算或依赖于计算 书写模式或依赖于可能依赖于 书写模式 的字体度量来影响其他不相关属性的计算值。
1.2. 值类型和术语
本规范遵循 CSS 属性定义约定,来自 [CSS2]。在本规范中未定义的值类型在 CSS Values & Units 中定义 [CSS-VALUES-3]。其他 CSS 模块可能会扩展这些值类型的定义。
除了在它们的定义中列出的特定于属性的值外,本规范定义的所有属性还接受作为其属性值的 CSS 宽泛关键字。为提高可读性,这些关键字没有被明确重复。
本规范中使用的其他重要术语和概念在 [CSS2] 和 [CSS-TEXT-3] 中定义。
2. 行内方向和双向性
虽然大多数书写系统的字符是从左到右书写的,但某些书写系统是从右到左书写的。在某些文档中,特别是使用阿拉伯文或希伯来文书写的文档,以及在某些混合语言的上下文中,单个(视觉上显示的)块中的文本可能会显示混合的方向性。这种现象称为双向性,简称“bidi”。
双向性
Unicode 标准(Unicode 标准附录 #9)定义了用于确定双向文本正确排序的复杂算法。该算法由基于字符属性的隐式部分以及用于嵌入和覆盖的显式控件组成。CSS 依赖此算法来实现正确的双向渲染。
两个 CSS 属性,direction 和 unicode-bidi,在 CSS 层提供了显式嵌入、隔离和覆盖控制。由于文本的基本方向性取决于文档的结构和语义,因此 direction 和 unicode-bidi 属性在大多数情况下应仅用于将标记中的双向信息映射到其相应的 CSS 样式中。
HTML 规范([HTML401],第 8.2 节,和 [HTML5],第 10.3.5 节)定义了 HTML 元素的双向行为。
如果文档语言提供用于控制双向性的标记功能,作者和用户应使用这些功能,而不应指定 CSS 规则来覆盖它们。
2.1. 指定方向性:direction 属性
名称: | direction |
---|---|
值: | ltr | rtl |
初始值: | ltr |
适用于: | 所有元素 |
是否继承: | 是 |
百分比: | 不适用 |
计算值: | 指定值 |
规范顺序: | 不适用 |
动画类型: | 不可动画 |
由于 HTML 用户代理可以关闭 CSS 样式,我们建议 HTML 作者使用 HTML dir
属性和 <bdo>
元素来确保在没有样式表的情况下正确的双向布局。作者不应在 HTML 文档中使用 direction。
此属性指定由盒子建立的任何双向段落、嵌入、隔离或覆盖的行内基础方向或方向性。(参见 unicode-bidi。)此外,它还会影响 表格列布局的顺序、水平 溢出 的方向、行内文本的默认对齐方式以及其他依赖于盒子的行内基础方向的布局效果。
此属性的值具有以下含义:
- ltr
- 此值将 行内基础方向(双向方向性)设置为从 行左 到 行右。
- rtl
- 此值将 行内基础方向(双向方向性)设置为从 行右 到 行左。
direction 属性在其 unicode-bidi 值为 normal 的行内盒子上没有双向重排的影响,因为该盒子不会相对于双向算法开启额外的嵌入级别。
当 direction 属性指定给表格列盒子时,不会被列中的单元格继承,因为列不是文档树中单元格的祖先。因此,CSS 无法轻松捕获 [HTML401],第 11.3.2.1 节中描述的 "dir" 属性继承规则。
2.2. 嵌入和覆盖:unicode-bidi 属性
名称: | unicode-bidi |
---|---|
值: | normal | embed | isolate | bidi-override | isolate-override | plaintext |
初始值: | normal |
适用于: | 所有元素,但请参见正文 |
是否继承: | 否 |
百分比: | 不适用 |
计算值: | 指定值 |
规范顺序: | 按语法 |
动画类型: | 不可动画 |
由于 HTML 用户代理可以关闭 CSS 样式,我们建议 HTML 作者使用 HTML dir
属性、<bdo>
元素,以及适当区分文本级与分组级 HTML 元素类型,以确保在没有样式表的情况下正确的双向布局。作者不应在 HTML 文档中使用 unicode-bidi。
通常(即当 unicode-bidi 为 normal 时),行内盒子对 Unicode 双向算法是透明的;内容的排序方式好像盒子的边界不存在。unicode-bidi 属性的其他值会使行内盒子在算法中创建作用域,并覆盖文本的固有方向性。
下表总结了 unicode-bidi 对行内盒子的内部和外部影响:
外部 | |||
---|---|---|---|
强字符 | 中性字符 | ||
内部 | 作用域 | embed | isolate |
覆盖 | bidi-override | isolate-override | |
纯文本 | — | plaintext |
此属性的值具有以下(规范的)含义:
- normal
- 对于双向算法,盒子不会开启额外的嵌入级别。对于行内盒子,隐式重排在盒子边界之间起作用。
- embed
- 如果盒子是行内元素,该值通过开启相对于双向算法的额外嵌入级别来创建方向嵌入。此嵌入级别的方向由 direction 属性决定。在盒子内部,重排是隐式完成的。
此值对非行内盒子没有影响。
- isolate
- 对于行内盒子,该值会双向隔离其内容。这类似于方向嵌入(并相应地增加嵌入级别),不同之处在于不受任何块边界或 强制段落中断的中断,每个行内级盒子序列被视为一个隔离序列:
- 序列内的内容按盒子的 direction 属性指定的基本方向性排序。
- 为包含的双向段落中的双向解析目的,序列被视为一个单独的对象替换字符(U+FFFC)。
此值对非行内盒子没有影响。
- bidi-override
- 此值将盒子的立即行内内容置于方向覆盖中。对于行内元素,这意味着盒子在双向算法中像 方向嵌入 一样作用,不同之处在于它内部的重排严格按照 direction 属性的顺序;忽略双向算法的隐式部分。对于块容器,覆盖应用于包含其所有内容的匿名行内盒子。
- isolate-override
- 它将 隔离 行为与 方向覆盖 行为相结合:对周围内容,它相当于 isolate,但盒子内的内容按 bidi-override 指定的顺序排序。它有效地在 方向覆盖 内部嵌套了一个 隔离序列。
- plaintext
-
此值的行为类似于 isolate,但对于 Unicode 双向算法,盒子的每个 双向段落(如果是块容器)或 隔离序列(如果是行内元素)的基本方向性是通过遵循 Unicode 双向算法规则 P2 和 P3 的启发式方法来确定的(而不是使用盒子的 direction 属性)。
根据 Unicode 双向算法条款 HL3 [UAX9],除 normal 以外的值会在传递段落到 Unicode 双向算法进行重排序之前,实际上将相应的 Unicode 双向控制代码插入文本流中的行内元素的开始和结束位置。(参见 § 2.4.2 CSS–Unicode Bidi Control Translation, Text Reordering。)
unicode-bidi 值 | direction 值 | |||
---|---|---|---|---|
ltr | rtl | |||
开始 | 结束 | 开始 | 结束 | |
normal | — | — | — | — |
embed | LRE (U+202A) | PDF (U+202C) | RLE (U+202B) | PDF (U+202C) |
isolate | LRI (U+2066) | PDI (U+2069) | RLI (U+2067) | PDI (U+2069) |
bidi-override* | LRO (U+202D) | PDF (U+202C) | RLO (U+202E) | PDF (U+202C) |
isolate-override* | FSI,LRO (U+2068,U+202D) | PDF,PDI (U+202C,U+2069) | FSI,RLO (U+2068,U+202E) | PDF,PDI (U+202C,U+2069) |
plaintext | FSI (U+2068) | PDI (U+2069) | FSI (U+2068) | PDI (U+2069) |
* LRO/RLO+PDF 对被应用于包含所有内容的 根行内盒子 的 块容器,如果这些值的 unicode-bidi 在 块容器 上被指定。 |
由于 unicode-bidi 属性不会继承,在块盒子上设置 bidi-override 或 plaintext 不会影响任何后代块。因此,这些值最好用于不包含任何块级结构的块和行内元素。
请注意,unicode-bidi 即使在 plaintext 的情况下也不会影响 direction 属性,因此不会影响 direction 依赖的布局计算。
由于 Unicode 算法的嵌入级别限制为 125 级,因此应注意不要过度使用 unicode-bidi 除 normal 以外的值。尤其是在深层嵌套的行内标记中使用 inherit 值时应极为小心。然而,对于通常意图显示为块的元素,设置 unicode-bidi: isolate 是首选,以便在 display 被更改为 inline 时保持元素完整(参见下方示例)。
2.3. 双向文本示例
以下示例展示了一个包含双向文本的 XML 文档。它说明了一个重要的设计原则:文档语言设计者应当在语言本身(元素和属性)以及任何附带的样式表中考虑双向文本。样式表应当设计成使双向规则独立于其他样式规则,并且这些规则不应被其他样式表覆盖,以保留文档语言的双向行为。
在此示例中,小写字母代表固有的从左到右字符,大写字母表示固有的从右到左字符。以下是按逻辑存储顺序的文本流。
<section dir=rtl> <para>HEBREW1 HEBREW2 english3 HEBREW4 HEBREW5</para> <para>HEBREW6 <emphasis>HEBREW7</emphasis> HEBREW8</para> </section> <section dir=ltr> <para>english9 english10 english11 HEBREW12 HEBREW13</para> <para>english14 english15 english16</para> <para>english17 <quote dir=rtl>HEBREW18 english19 HEBREW20</quote></para> </section>
由于这是任意的 XML,样式表负责设置书写方向。以下是样式表:
/* 双向文本规则 */ [dir=rtl] {direction: rtl; unicode-bidi: isolate; } [dir=ltr] {direction: ltr; unicode-bidi: isolate; } /* 显示规则 */ section, para {display: block;} emphasis {font-weight: bold;} quote {font-style: italic;}
如果行的长度较长,文本的格式可能如下所示:
5WERBEH 4WERBEH english3 2WERBEH 1WERBEH 8WERBEH 7WERBEH 6WERBEH english9 english10 english11 13WERBEH 12WERBEH english14 english15 english16 english17 20WERBEH english19 18WERBEH
第一个 <section>
元素是一个从右到左基方向的块,第二个 <section>
元素是一个从左到右基方向的块。<para>
块继承其父元素的基方向。因此,前两个 <para>
从右上角开始阅读,最后三个从左上角开始阅读。
<emphasis>
元素是行内级别的,由于其 unicode-bidi 的值为 normal(初始值),因此对文本的排序没有影响。
<quote>
元素,另一方面,使用给定的内部方向性创建了一个 隔离序列。请注意,这使得 HEBREW18 位于 english19
的右侧。
如果必须换行,相同的文本可能会这样格式化:
2WERBEH 1WERBEH -EH 4WERBEH english3 5WERB -EH 7WERBEH 6WERBEH 8WERB english9 english10 en- glish11 12WERBEH 13WERBEH english14 english15 english16 english17 18WERBEH 20WERBEH english19
注意,由于必须先读取 HEBREW18,然后再读取 english19,因此它位于 english19 的上一行。仅仅打断之前格式化的长行是不可行的。
还请注意,english19 的第一个音节本来可以适合上一行,但是在右到左的上下文中对从左到右的单词进行连字符断词(反之亦然)通常会被抑制,以避免在一行的中间显示连字符。
2.4. 应用双向重排序算法
支持双向文本的用户代理必须对每个不受任何块边界或“bidi 类型 B” 强制段落中断中断的行内级盒子序列应用 Unicode 双向算法。此序列在双向算法中形成了 段落单元。
2.4.1. 双向段落嵌入级别
在 CSS 中,段落的嵌入级别必须根据段落的包含块的 direction 属性来设置(遵循 UAX9 条款 HL1),而不是按照 Unicode 算法的步骤 P2 和 P3 给出的启发式方法来设置。
然而,有一个例外:当段落的包含块的计算 unicode-bidi 为 plaintext 时,将按照 [UAX9] 中描述的那样使用 P2 和 P3 中的 Unicode 启发式方法,而不会使用 HL1 覆盖。
2.4.2. CSS-Unicode 双向控制转换,文本重排序
每个 双向段落中的字符最终顺序与在 unicode-bidi(上文)中描述的方式添加双向控制代码相同,标记被去除,结果字符序列被传递给实现 Unicode 双向算法的纯文本,以生成与样式化文本相同的换行。
请注意,源文本中的双向控制代码仍然有效,可能与文档树结构不一致。这可能以有趣的方式拆分行内或干扰双向起始/结束控制配对。
2.4.3. 原子行内元素的双向处理
在此过程中,具有 display: inline 的 替换元素被视为中性字符,除非它们的 unicode-bidi 属性为 embed 或 bidi-override,在这种情况下,它们被视为指定元素 direction 的强字符。(这样做是为了在替换元素回退到渲染内联文本内容时,其对周围文本的双向效果与其替换后的渲染保持一致。)
所有其他原子行内级盒子始终被视为中性字符。
2.4.4. 嵌入和隔离内的段落中断
如果一个行内盒子在 双向段落边界处被分割(例如被块或 强制段落中断 分割),则分配给盒子末尾的 HL3 双向控制代码也会在中断之前添加,并且分配给盒子开头的代码也会在中断之后添加。(换句话说,由该盒子启动的任何嵌入级别、隔离或覆盖将在段落中断处关闭并在其另一侧重新开启。)
例如,当 <BR/> 是一个 强制段落中断时,双向顺序在以下两种情况下是相同的:
<para>...<i1><i2>...<BR/>...</i2></i1>...</para>
和
<para>...<i1><i2>...</i2></i1><BR/><i1><i2>...</i2></i1>...</para>
对于行内元素 <i1> 和 <i2> 上的所有 unicode-bidi 值。
请注意,这种行为是 CSS 为应用于盒子树的 CSS 声明的双向控制应用的;它不适用于 Unicode 的双向格式控制,这些格式控制被定义为在双向段落的末尾终止其效果。
2.4.5. 重排序导致的盒子碎片化
由于双向重排序可以分割和重新排列逻辑上连续的文本,双向文本可能导致包含这些文本的 行内盒子被分割,并在行内重新排列其片段。
2.4.5.1. 重排序导致的盒子碎片化条件
当双向重排序由于中间内容而将行内盒子分开时,行内盒子被认为被分割成多个 盒子碎片。[CSS-BREAK-3] 如果在无限长的行上,由于中间内容导致盒子分割,即使换行结果是两个 盒子碎片在行上相邻,也会认为该盒子被碎片化。在这种情况下,两个 盒子碎片中文本的最近共同祖先(决定文本格式的某些方面,如两个 字距调整和对齐之间)被认为是两个 盒子碎片的最近共同祖先,而不是 行内盒子本身。然而,由于双向重排序,如果没有中间内容强制分割,一个行内盒子不会被认为被分割成多个盒子碎片。(这些规则尽可能保持 行内盒子的完整性,同时保持双向引起的碎片化在换行变化时的稳定性。)
在以下示例中,小写字母表示从左到右的字母,大写字母表示从右到左的字母,双向重排序导致 <em>
的 行内盒子 被分割成两个被
<em>
外部文本分开的 盒子碎片。
源代码(逻辑顺序):
<p>这里是 <em>一些混合</em> 文本。</p>
在宽容器块中的渲染(视觉顺序),结果为两个被外部内容分隔的行内盒子碎片:
这里是 一些 文 本 混合。
在窄容器块中的渲染(视觉顺序),结果为相邻的两个行内盒子碎片:
这里是 一些 混合 文本。
相比之下,在这个例子中,混合方向短语通过隔离保持在一起,仅生成一个碎片——周围内容不会将 <em>
的 行内盒子分开,即使在无限长的容器块中也是如此:
源代码(逻辑顺序):
<p>这里是 <em dir=rtl>一些混合</em> 文本。</p>
在宽容器块中的渲染(视觉顺序),结果为一个碎片:
这里是 一些 混合 文 本。
在窄容器块中的渲染(视觉顺序),结果为一个碎片:
这里是 一些 混合 文 本。
2.4.5.2. 重排序导致的盒子碎片的盒子模型
对于每个行盒子,用户代理必须采用每个行内盒子的碎片并按视觉顺序(而不是逻辑顺序)分配边距、边框和填充。在第一个行盒子中出现的最开始的碎片具有 起始边的边距、边框和填充;在最后一个行盒子中出现的最末的碎片具有 结束边的边距、边框和填充。例如,在 horizontal-tb 书写模式中:
- 当父元素的 direction 属性为 ltr 时,第一个行盒子中最左侧的盒子碎片具有左边距、左边框和左填充,最后一个行盒子中最右侧的盒子碎片具有右填充、右边框和右边距。
- 当父元素的 direction 属性为 rtl 时,第一个行盒子中最右侧的碎片具有右填充、右边框和右边距,最后一个行盒子中最左侧的碎片具有左边距、左边框和左填充。
垂直书写模式下也适用类似的规则。
box-decoration-break 属性可以覆盖此行为,以在每个碎片的两侧绘制盒子装饰。[CSS-BREAK-3]
3. 垂直书写模式
除了扩展 CSS2.1 对双向文本的支持之外,本模块还引入了在 CSS 中支持垂直文本布局所需的规则和属性。
3.1. 垂直书写简介
本小节为非规范性内容。
与主要水平布局的拉丁脚本语言不同,中文和日文等亚洲语言可以垂直布局。下方的日文示例展示了相同文本的水平和垂直布局。在水平情况下,文本从左到右、从上到下阅读。在垂直情况下,文本从上到下、从右到左阅读。左到右水平情况下的左侧缩进在上到下垂直情况下则变为顶部缩进。
垂直和水平日文的比较:iBunko 应用程序 (iOS)
对于中文和日文,行可以从右到左或从上到下排列,而对于蒙古文和满文,行则从左到右排列。
从水平书写变为垂直书写不仅会影响布局,还会影响排版。例如,标点符号在其间距框中的位置可能会在水平和垂直情况下发生变化,有时会使用替代字符。
包含拉丁脚本文本或其他通常以水平方式显示的文本的垂直文本,可以以多种方式显示这些文本。例如,拉丁词可以旋转为侧面显示,或者每个字母都保持直立:
日文中的拉丁示例:Daijirin Viewer 1.4 (iOS)
在某些特殊情况下,例如日期中的两位数,文本会紧凑地适应单个垂直字符框:
Mac Fan,2010年12月,第49页
布局中常常混合垂直和水平元素:
垂直和水平元素的混合
垂直文本布局还需要处理双向文本布局,例如,顺时针旋转的阿拉伯语会自下而上排列。
3.2. 块流向:writing-mode 属性
名称: | writing-mode |
---|---|
值: | horizontal-tb | vertical-rl | vertical-lr | sideways-rl | sideways-lr |
初始值: | horizontal-tb |
适用于: | 除表格行组、表格列组、表格行、表格列、ruby 基本容器、ruby 注释容器以外的所有元素 |
继承: | 是 |
百分比: | 不适用 |
计算值: | 指定值 |
规范顺序: | 不适用 |
动画类型: | 不可动画 |
此属性指定文本行是水平还是垂直排列,以及块的流动方向。可能的值:
- horizontal-tb
- 从上到下的块流动方向。 书写模式和排版模式均为水平。
- vertical-rl
- 从右到左的块流动方向。 书写模式和排版模式均为垂直。
- vertical-lr
- 从左到右的块流动方向。 书写模式和排版模式均为垂直。
- sideways-rl
- 从右到左的块流动方向。 书写模式为垂直,而排版模式为水平。
- sideways-lr
- 从左到右的块流动方向。 书写模式为垂直,而排版模式为水平。
writing-mode属性指定块流向, 确定块格式化上下文中块级框的排列方向; 包含内联的块容器中行框的排列方向; 表格中行的排列方向等。 通过确定行框的堆叠方向, writing-mode属性还确定行框的方向(以及书写模式) 是水平还是垂直。 text-orientation属性接着确定文本在行框中的布局方式。
替换元素的内容不会因为书写模式而旋转:
例如,<iframe>
等图像和外部内容保持直立,
以及默认对象大小为300px×150px不会改变方向。
然而,嵌入的涉及文本的替换内容
(如MathML内容或表单元素)
如果UA支持该替换内容的垂直书写模式,
应匹配替换元素的书写模式和行方向。
在以下示例中,由图像(2)分隔的两个块元素(1和3)以不同的流动书写模式呈现。
这是水平书写模式(writing-mode: horizontal-tb
)的示意图:
这是东亚常用的从右到左垂直书写模式(writing-mode: vertical-rl
)的示意图:
最后,这是满文和蒙古文使用的从左到右垂直书写模式(writing-mode: vertical-lr
)的示意图:
在以下示例中,一些表单控件在具有vertical-rl书写模式的块中呈现。表单控件与书写模式匹配。
<style> form { writing-mode: vertical-rl; } </style> ... <form> <p><label>姓名 <input value="艾俐俐"></label> <p><label>语言 <select><option>English <option>français <option>فارسی <option>中文 <option>日本語</select></label> </form>
如果一个框的writing-mode值与其父框不同 (即最近的没有display: contents的祖先):
- 如果该框原本会成为具有计算的in-flow框, 并且其display计算值为inline, 则其display计算为inline-block。
- 如果该框是块容器, 则它会建立一个独立块格式化上下文。
- 更一般地,如果其指定的内部显示类型 是流, 则其计算的内部显示类型变为流根。[CSS-DISPLAY-3]
像所有其他继承的CSS属性一样, writing-mode属性继承到内联到源文档中的SVG元素(而不是链接的元素)。 这可能会导致意外的副作用,例如,一个仅为水平流设计的SVG图像嵌入到垂直流文档中。
作者可以通过添加以下规则来防止这种情况发生:
3.2.1. 已废弃的 SVG1.1 writing-mode 值
SVG1.1 [SVG11] 定义了一些额外的值:lr、lr-tb、rl、rl-tb、tb 和 tb-rl。
这些值在除了 SVG1 文档之外的任何上下文中都是已废弃的,因此对于非 SVG 用户代理来说是可选的。
3.2.1.1. 在 CSS 语法中支持 SVG1.1 writing-mode 值
想要在 CSS 中支持这些值的用户代理必须按以下方式计算它们:
指定值 | 计算值 |
---|---|
lr | horizontal-tb |
lr-tb | |
rl | |
rl-tb | |
tb | vertical-rl |
tb-rl |
SVG1.1 的值也出现在 CSS writing-mode 规范的旧版本中, 该规范已被本规范废弃。 该修订版中额外的 tb-lr 值被 vertical-lr 替代。
3.2.1.2. 在表现属性中支持 SVG1.1 writing-mode 值
为了支持带有表现属性的遗留内容,并允许作者创建支持较旧客户端的文档, SVG 用户代理必须将以下样式表规则添加到其默认的用户代理样式表中:
@namespace svg"http://www.w3.org/2000/svg" ; svg|*[writing-mode=lr], svg|*[writing-mode=lr-tb], svg|*[writing-mode=rl], svg|*[writing-mode=rl-tb] { writing-mode : horizontal-tb; } svg|*[writing-mode=tb], svg|*[writing-mode=tb-rl] { writing-mode : vertical-rl; }
svg|text { writing-mode: tb; writing-mode: vertical-rl; }
4. 行内级对齐
当不同类型的行内级内容在同一行上放置在一起时,内容的基线和 vertical-align 属性的设置会控制它们在行框的横向方向上的对齐方式。 本节讨论什么是基线,如何找到它们,以及如何与 vertical-align 属性一起使用来确定行内级内容的对齐方式。
4.1. 基线简介
本节是非规范性的。
基线 是沿着行框的 行内轴的一条线,用于对齐单个文本字形。 基线引导字体中字形的设计(例如,大多数字母的底部通常与字母基线对齐), 也引导排版时来自不同字体或字体大小的字形对齐。
两种字体大小的字母文本与基线和 em 框
不同的书写系统偏好不同的基线表。
各种书写系统的首选基线
一个构造良好的字体包含一个 基线表, 该表指示字体设计坐标空间中一个或多个基线的位置。(设计坐标空间会随着字体大小而缩放。)
在设计良好的混合脚本字体中,字形在坐标空间中的定位是为了在排版时彼此协调一致。 然后构造基线表以匹配字形的形状,每个基线的位置与其首选脚本的字形匹配。
基线表是字体的属性,各种基线的位置适用于字体中的所有字形。
可以为横向和纵向文本提供不同的基线表。用户代理应在垂直 排版模式中使用垂直基线表,而在其他情况下使用水平基线表。
4.2. 文本基线
在本规范中,仅考虑以下基线:
- 字母基线
- 字母基线, 通常与大写拉丁字母的底部对齐。
- 中心基线
- 中心基线, 通常穿过 em 框的中心。如果字体缺少此基线, 则假设它位于升部(上方)和降部(下方)边缘之间的一半处。
在垂直的 排版模式中, 当 text-orientation 为 mixed 或 upright 时,使用 中心基线 作为主导基线。 否则使用 字母基线。
未来的 CSS 模块将更详细地处理基线问题,并允许选择其他主导基线和对齐选项。
4.3. 原子行内基线
如果一个 原子行内元素(如行内块、行内表或替换行内元素) 没有基线, 则用户代理会这样合成一个基线表:
- 字母基线
- 假设字母基线位于 下方的边缘。
- 中心基线
- 假设中心基线位于 下方和 上方边缘之间的一半处。
在 vertical-align 属性中,[CSS2] 定义了行内表和行内块框的基线,有一些例外。
4.4. 基线对齐
主导基线(可根据 排版模式 更改) 在 CSS 中用于两种情况下的对齐:
- 在同一个行内框中对齐来自不同字体的字形。通过匹配其相应字体中的主导基线位置来对齐字形。
- 将子行内级框与其父框对齐。对于 vertical-align 值为 baseline,
通过匹配父框的主导基线到子框中的相同基线来对齐子框。
(例如,如果父框的主导基线是字母基线,则子框的字母基线与父框的字母基线对齐,
即使子框的主导基线是其他基线。)
对于 sub、super、<length> 和
<percentage> 的值,
基线对齐与 baseline 相同,但子框根据其 vertical-align 值给定的偏移量移动。
给定以下示例标记:
<p><span class="outer">Ap <span class="inner">ji</span></span></p>
以及以下样式规则:
span.inner { font-size: .75em; }
父框(
.outer
)和子框(.inner
)的基线表由于字体大小不同而无法对齐。 由于主导基线是字母基线,通过匹配字母基线使子框对齐其父框。如果我们为上面的示例中的
.inner
元素赋予 vertical-align: super, 则使用相同的规则将.inner
子框与其父框对齐; 唯一区别是除了基线对齐外,子框还会被移到上标位置。span.inner { vertical-align: super; font-size: .75em; }
5. 垂直文本布局介绍
每个书写系统都有一个或多个原生的方向。因此,现代文字可以分为三种方向类别:
- 仅水平
- 具有水平但没有垂直原生方向的文字。 包括:拉丁文、阿拉伯文、希伯来文、天城文
- 仅垂直
- 具有垂直但没有水平原生方向的文字。 包括:蒙古文、八思巴文
- 双向
- 同时具有垂直和水平原生方向的文字。 包括:汉字、韩文、日文假名
垂直文字是 具有原生垂直方向的文字: 即 仅垂直 或 双向。 水平文字 是具有原生水平方向的文字: 即 仅水平 或 双向。 (参见 附录 A 中按原生方向对文字的分类。)
在现代排版系统中,所有字形都有一个水平方向, 该方向用于水平排版。 为了排版垂直文本,用户代理需要将文本从水平方向转换为垂直方向。 此转换称为双向转换,有两种类型:
- 旋转
- 将字形从水平旋转为垂直
- 平移
- 将字形从水平平移为垂直
具有原生垂直方向的文字具有内在的 双向转换, 使其在垂直文本中正确定向:大多数中日韩(CJK)字符是平移的,即它们始终是直立的。 其他文字的字符,如蒙古文,是旋转的。
没有原生垂直方向的文字可以旋转(横放)或平移(直立): 所使用的转换是根据文本使用情况的风格偏好,而不是正确性的问题。 text-orientation 属性的 mixed 和 upright 值 用于指定 仅水平文本的旋转与平移。
5.1. 文字方向:text-orientation 属性
名称: | text-orientation |
---|---|
值: | mixed | upright | sideways |
初始值: | mixed |
适用于: | 除表格行组、行、列组和列外的所有元素 |
继承: | 是 |
百分比: | n/a |
计算值: | 指定值 |
规范顺序: | n/a |
动画类型: | 不可动画 |
该属性指定文本在一行中的方向。 当前值仅在垂直排版模式下生效: 在水平排版模式中该属性不起作用。
值有以下含义:
- mixed
-
在垂直排版模式下,来自仅水平书写的 排版字符单元 以侧向排版, 即从它们的标准方向顺时针旋转90°。 垂直书写的排版字符单元则按其固有方向排版。 详情见垂直方向。
该值通常用于以垂直书写文字为主的布局。
- upright
-
在垂直排版模式下,来自仅水平书写的 排版字符单元 按直立排版, 即保持其标准的水平方向。 垂直书写的排版字符单元按其固有方向排版,并保持正常形状。 详情见垂直方向。
- sideways
-
在垂直排版模式下, 所有文本都以侧向排版, 就像在水平布局中一样,但顺时针旋转90°。
更改此属性的值可能会影响内联级对齐。 有关详细信息,请参阅文本基线。
如有必要,用户代理可能接受sideways-right作为计算为 sideways的值,以实现向后兼容。
.vertical-upright-hebrew { writing-mode: vertical-rl; text-orientation: upright; unicode-bidi: bidi-override; direction: ltr; }
5.1.1. 垂直排版和字体特性
当文本以vertical-rl和vertical-lr 模式排版时,文本将按照以下定义“直立”或“横向”排版:
- 直立排版
-
排版字符单元分别直立排版在垂直行中,使用垂直字体度量。
UA 必须为缺乏垂直字体度量的字体合成垂直字体度量。
(本规范未定义合成此类度量的启发式方法。)
此外,必须使用为垂直排版设计的字体特性(如替代字形和其他转换)。
(例如,必须启用 OpenType 的 vert 特性。)
此外,来自水平连字书写系统(如阿拉伯语)的字符在直立排版时呈现孤立形式。
请注意,即使是“直立”排版,一些字形仍应显示为旋转。 例如,破折号和包围标点应相对于内联轴进行定向。 在 OpenType 中,这通常通过字形替换来处理,尽管并非所有字体都提供所有相关代码点的替代字形。 (东亚字体通常提供东亚代码点的替代字形,但西方字体通常缺乏任何垂直排版功能, 而东亚字体通常缺乏对西方代码点的垂直替换。) Unicode 已发布草稿数据,指定哪些字符应侧向显示为 SVO 属性, 该数据可在此数据文件中查阅; 然而,该属性已在[UTR50]的当前修订版中被废弃。
排版字符单元被分类为
Tr
或Tu
在[UTR50]中 预计会有替代字形或用于垂直文本直立排版的定位。 对于Tr
字符, 如果字体缺少此类垂直替代字形,UA 可能希望 [RFC6919](但不要求) 通过侧向排版等方式合成缺失的字形。 - 横向排版
- 排版字符单元按一组运行,
从其直立方向顺时针旋转 90°,使用水平度量和组成,
且不使用垂直排版特性。
但是,如果字体具有用于在垂直行中排版的横向文本的功能
(例如调整笔画角度或对齐),则应使用这些功能。
(此类功能的一个示例是提议的
vrtr
OpenType 字体功能。)
5.1.2. 混合垂直定向
[UTR50]定义了Vertical_Orientation
属性,
用于混合定向垂直文本的默认字形定向。
当text-orientation为mixed时,
UA 必须根据其Vertical_Orientation
属性确定每个排版字符单元的定向:如果其定向属性为U
、Tu
或Tr
,则直立排版
;
如果其定向属性为R
,则侧向排版(相对于水平顺时针旋转 90°)。
请注意,UTR50 未处理在垂直上下文中旋转 -90° 的书写系统,因此它们不会以混合定向正确排版。 对于此类书写系统,请使用sideways-lr。
OpenType 的vrt2特性旨在用于混合定向排版, 但 CSS 不使用它。 它将字形定向的责任委托给字体设计师。 CSS 通过[UTR50]来控制字形的定向,并根据需要直立或侧向排版字形。
5.1.3. 已废弃:SVG1.1 glyph-orientation-vertical 属性
名称: | glyph-orientation-vertical |
---|---|
值: | auto | 0deg | 90deg | 0 | 90 |
初始值: | n/a |
适用对象: | n/a |
是否继承: | n/a |
百分比: | n/a |
计算值: | n/a |
规范顺序: | n/a |
可动画: | n/a |
某些 SVG 用户代理将需要处理包含废弃的 SVG glyph-orientation-vertical 属性的文档, 该属性被定义为接受 auto 关键字, 以及表示 90° 倍数的<angle>和<integer>值。 虽然支持此属性是可选的, 但支持此属性的 UA 必须将glyph-orientation-vertical作为 text-orientation 的简写别名,如下所示:
简写 glyph-orientation-vertical 值 | 长写 text-orientation 值 |
---|---|
auto | mixed |
0deg | upright |
0 | upright |
90deg | sideways |
90 | sideways |
UA 必须忽略并视为无效 任何其他值的glyph-orientation-vertical 属性; 并将 glyph-orientation-horizontal 属性 视为无效。
注意: 180deg 和 270deg 值, 弧度和百分度值, 以及glyph-orientation-horizontal 属性 未映射,因为它们没有已知的使用案例, 也没有依赖的内容,因此不属于 CSS 的一部分, 并且已从 SVG 中删除。
6. 抽象框术语
CSS2.1 [CSS2]详细定义了 CSS 的框布局模型, 但仅限于horizontal-tb书写模式。其他书写模式的布局类似, 但 CSS2.1 中的方向和尺寸术语必须进行抽象并适当重新映射。
本节定义抽象的方向和尺寸术语及其映射,以定义其他书写模式的框布局, 并为未来的规范提供术语,以抽象地定义它们的布局概念。(下一节解释如何将这些术语应用于 CSS2.1 的布局计算以及如何处理正交流。)虽然这些抽象映射源自文本的行为, 但即使对于不包含任何行框的框,这些抽象映射也存在: 它们直接根据writing-mode和direction属性的值计算。
CSS 中有三组方向术语:
- 物理方向
- 相对于页面解释,与书写模式无关。 物理方向为左、右、上和下。
- 流相对
- 相对于内容流的方向解释。 流相对方向为起始和 结束, 或块起始、块结束、内联起始和内联结束,如果维度也存在歧义。
- 行相对
- 相对于行框的方向解释。 行相对方向为行左、行右、行上和行下。
物理尺寸为宽度和高度, 它们分别对应于x 轴(水平维度)和y 轴(垂直维度)的测量。 抽象尺寸在流相对和行相对术语中是相同的,因此 这些术语只有一组。
注意:[CSS3-FLEXBOX] 还定义了弹性相对术语, 用于描述弹性布局。
6.1. 抽象尺寸
- 块尺寸
- 与行内文本流垂直的尺寸,即 垂直尺寸在水平书写模式中, 而水平尺寸在垂直书写模式中。
- 内联尺寸
- 与行内文本流平行的尺寸,即 水平尺寸在水平书写模式中, 而垂直尺寸在垂直书写模式中。
- 块轴
- 块尺寸的轴, 即垂直轴在水平书写模式中, 水平轴在垂直书写模式中。
- 内联轴
- 内联尺寸的轴,即水平轴在水平书写模式中,垂直轴在垂直书写模式中。
- 块大小
- 逻辑高度
- 块尺寸的测量: 在水平书写模式中指物理高度(垂直尺寸), 在垂直书写模式中指物理宽度(水平尺寸)。
- 内联大小
- 逻辑宽度
- 内联尺寸的测量: 在水平书写模式中指物理宽度(水平尺寸), 在垂直书写模式中指物理高度(垂直尺寸)。
6.2. 流相对方向
流相对方向为块起始、块结束、内联起始和内联结束, 是相对于页面上的内容流定义的。 在LTR的horizontal-tb书写模式中,它们分别对应于 上、下、左和右的方向。 它们定义如下:
- 块起始
- 在块流方向中较早的一侧, 由writing-mode属性决定: 在horizontal-tb模式中为物理顶部, 在vertical-rl模式中为右侧, 在vertical-lr模式中为左侧。
- 块结束
- 与块起始相对的一侧。
- 内联起始
- 文本在内联基本方向上开始的那一侧。 对于使用direction值为ltr的盒子,这意味着行左侧。 对于使用direction值为 rtl的盒子,这意味着行右侧。
- 内联结束
- 与起始相对的一侧。
在上下文明确或涵盖两种含义时, 使用术语起始 和结束 来代替块起始/内联起始和块结束/内联结束。
注意,确定盒子的块起始和块结束侧仅取决于writing-mode属性, 而确定盒子的内联起始和 内联结束侧不仅取决于 writing-mode属性, 还取决于direction属性。
6.3. 行相对方向
行方向 决定了行框的哪一侧是逻辑上的“顶部”(升部侧)。 由writing-mode属性指定。 通常行相对的“顶部”对应于块起始侧, 但并非总是如此: 在蒙古文排版中(因此默认情况下在vertical-lr书写模式中), 行相对的“顶部”对应于块结束侧。 因此需要不同的术语。

如上图所示,主要为蒙古文的文档以从左到右堆叠的垂直行书写, 但其拉丁文本的顶部朝向右侧。 这使得文本在内联方向上与蒙古文(自上而下)一致,并与其他东亚布局(垂直行从右到左堆叠)中的方向一致, 但字形的顶部是朝向行堆叠的底部,而不是顶部, 在英语段落中,这将是上下颠倒的。 (参见蒙古文本布局示意图。)
除了行相对的“顶部”和“底部”用于映射诸如 'vertical-align: top' 之类的东西外, CSS 还需要引用行相对的“左侧”和“右侧”,以映射诸如text-align: left之类的属性。 因此有四个行相对方向, 它们相对于行方向定义如下:
- 上方 或 行上方
- 通常对应于升部侧或行框的“顶部”侧。(上划线通常绘制在这一侧。)
- 下方 或 行下方
- 与上方相对:行相对的“底部”或降部侧。 (下划线通常绘制在这一侧。)
- 行左侧
- 行框的行相对“左侧”, 通常是LTR文本开始的那一侧。
- 行右侧
- 行框的行相对“右侧”, 通常是RTL文本开始的那一侧。 (与行左侧相对。)
有关物理方向和行相对方向的确切映射,请参见下表。

行方向在horizontal-tb中的示意图

行方向在vertical-rl、vertical-lr和sideways-rl中的示意图

行方向在sideways-lr中的示意图
直立字形的垂直基线
由于基线是垂直的, 上述对于mixed或sideways的定义仍然适用; 即,行上方在右侧, 而行下方在左侧。
这与 OpenType 等字体系统中的定义一致, 这些系统在其垂直度量中将升部定义在右侧, 将降部定义在左侧。
6.4. 抽象到物理映射
下表总结了抽象到物理的映射 (基于使用的direction和writing-mode):
writing-mode | horizontal-tb | vertical-rl, sideways-rl | vertical-lr | sideways-lr | ||||
---|---|---|---|---|---|---|---|---|
direction | ltr | rtl | ltr | rtl | ltr | rtl | ltr | rtl |
块大小 | 高度 | 宽度 | ||||||
内联大小 | 宽度 | 高度 | ||||||
块起始 | 上方 | 右方 | 左方 | |||||
块结束 | 下方 | 左方 | 右方 | |||||
内联起始 | 左方 | 右方 | 上方 | 下方 | 上方 | 下方 | 下方 | 上方 |
内联结束 | 右方 | 左方 | 下方 | 上方 | 下方 | 上方 | 上方 | 下方 |
上方 | 上方 | 右方 | 左方 | |||||
下方 | 下方 | 左方 | 右方 | |||||
行左侧 | 左方 | 上方 | 下方 | |||||
行右侧 | 右方 | 下方 | 上方 |
注意:使用的direction取决于计算出的writing-mode和text-orientation: 在垂直书写模式中, text-orientation值为upright会强制使用的direction为ltr。
7. 抽象框布局
7.1. 垂直书写模式下的布局原则
垂直书写模式下的 CSS 框布局类似于水平书写模式,遵循以下原则:
适用于水平书写模式中水平维度的布局计算规则(如 CSS2.1,第 10.3 节) 在垂直书写模式中应用于垂直维度。 同样,适用于水平书写模式中垂直维度的布局计算规则(如 CSS2.1,第 10.6 节) 在垂直书写模式中应用于水平维度。 因此:
-
布局规则引用宽度时使用高度,反之亦然。
-
布局规则引用*-left和*-right框属性(边框、边距、内边距、定位偏移) 使用*-top和*-bottom代替,反之亦然, 通过使用流相对方向将 CSS2.1 中的水平书写模式规则映射到垂直书写模式规则中。 这些属性应用到的框的边并没有改变: 只是哪些值作为哪些布局计算的输入发生了变化。 例如,margin-left属性仍然影响左侧边距; 但是在vertical-rl书写模式中,它参与边距折叠, 取代了margin-bottom。
-
依赖direction属性在左和右之间做出选择的布局规则 (例如,溢出、过度约束解决方案、text-align的初始值、表格列排序) 被抽象为起始和结束侧并适当地应用。
例如,在垂直书写模式中, 表格行是垂直的,表格列是水平的。 在vertical-rlmixedrtl表格中, 第一列将位于底部(内联起始侧), 而第一行位于右侧(块起始侧)。 表格的margin-right和margin-left将分别与表格前(右侧)和表格后(左侧)的边距折叠, 如果表格的margin-top和margin-bottom值为auto, 那么它将在其块流中垂直居中。
在vertical-rl RTL 书写模式中的表格
对于主要参考行框左右两侧或其纵向平行线(因此没有上或下等价物)的功能, 如文本对齐、浮动和列表标记定位, 使用行左侧和行右侧作为左右两侧的参考。
同样,对于主要参考行框顶部或底部或其横向平行线(因此没有左或右等价物)的功能, 如下划线、上划线和基线对齐(不幸命名为vertical-align), 使用行上方和行下方作为顶部和底部的参考。
这些映射的详细信息如下所述。
7.2. 尺寸映射
某些属性的逻辑行为如下:
- border-spacing属性的第一个和第二个值分别表示列间距和行间距, 而不一定是水平和垂直间距。[CSS2]
- line-height属性始终指逻辑高度。[CSS2]
高度属性(height、 min-height 和 max-height) 指物理高度,宽度属性(width、 min-width 和 max-width)指物理宽度。然而, 用于计算框尺寸和位置的规则是逻辑的。
例如,CSS2.1 第 10.3 节中的计算规则 用于内联尺寸的测量: 它们适用于内联尺寸 (可以是物理宽度或物理高度) 以及内联起始和内联结束的边距、内边距和边框。 同样,CSS2.1 第 10.6 节中的计算规则 用于块尺寸: 它们适用于块尺寸以及块起始和块结束的边距、内边距和边框。[CSS2]
因此,边距和内边距属性上的百分比, 在 CSS2.1 中始终相对于包含块宽度计算, 在 CSS3 中相对于包含块的内联尺寸计算。
7.3. 正交流
当一个框的书写模式与其 包含块不同时,有两种情况可能发生:
- 两种书写模式彼此平行。(例如,vertical-rl 和 vertical-lr)。
- 两种书写模式彼此垂直。(例如,horizontal-tb 和 vertical-rl)。
当一个框的书写模式与其包含块垂直时, 称其处于或建立了一个正交流。
为处理这种情况,CSS 布局计算分为两个阶段:框的尺寸调整和框在流中的定位。
- 在尺寸调整阶段——计算框的宽度和高度时——框和包含块的尺寸映射到内联尺寸 和块尺寸,并根据 建立正交流的框的书写模式执行计算。
- 在定位阶段——计算定位偏移、边距、边框和内边距时——框和其包含块的尺寸映射到内联尺寸和块尺寸,并根据包含块的书写模式执行计算,从而建立正交流。
由于auto边距是根据包含块的书写模式解决的, 建立正交流的框可以在尺寸调整后, 使用自动边距与包含块内的其他块级框对齐或居中。
正交流的示例
例如,如果一个垂直块放置在一个水平块内, 那么在计算子块的物理高度(即内联尺寸)时, 父块的物理高度用作子块的包含块的内联尺寸, 即使物理高度是块尺寸,而不是父块的内联尺寸。
另一方面, 由于包含块处于水平书写模式, 子块上的垂直边距参与边距折叠, 即使它们处于子块的内联轴, 而水平自动边距将扩展以填充包含块, 即使它们处于子块的块轴。
这意味着在对诸如内联块、浮动或表格单元等框应用缩小以适应公式时, 如果其子块建立了正交流, 则必须更改计算依赖关系,以便 子块的尺寸调整阶段先运行, 并且其使用的块大小成为父块 的内联尺寸 缩小以适应公式的输入。
7.3.1. 正交流中的可用空间
在 CSS 中,包含块通常具有明确的内联尺寸, 但没有明确的块尺寸。 这种情况通常发生在 CSS2.1 中, 当包含块的高度为auto时, 例如:其宽度由10.3.3中的计算确定, 但其块尺寸取决于其内容。 在这种情况下,可用内联空间定义为 包含块的内联尺寸; 但可用块空间, 即包含块的块尺寸,是无限的。
将一个框放入正交流中可能会导致相反的结果:
该框的可用块空间是确定的,
但其可用内联空间是不确定的。
在这种情况下,包含块的内联尺寸的百分比无法定义,
并且无法解决内联轴计算。
在这些情况下,使用额外的约束作为回退,
代替需要确定的可用内联空间的计算——
- 包含块的内部最大尺寸(如果固定) 并且不低于其内部最小尺寸(如果固定)
- 最近的祖先滚动端口的内部尺寸(如果固定), 否则限制在其内部最大尺寸(如果固定), 并且不低于其内部最小尺寸(如果固定)
- 初始包含块的尺寸
有关 CSS 尺寸术语和概念的更多详细信息,请参见[CSS3-SIZING]。
7.3.2. 正交流中块容器的自动调整大小
如果一个框建立了正交流, 并且它是一个块容器或多列容器, 在该框的内联尺寸为auto的情况下:
- 计算使用的列宽:
- 如果列数和列宽均为auto,
使用缩小以适应的公式:
min(max-content, max(min-content, constraint))
,其中:
- 如果列数不是auto,且列宽是auto, 则使用相同的公式计算使用的列宽, 只是将constraint替换为constraint − (列数 − 1) × 列间距。
- 如果列数和列宽均为非auto, 则使用的列宽为计算出的列宽。 (不推荐这样做,因为可能会导致溢出; 建议设置列宽和最大块尺寸。)
- 如果列数和列宽均为auto,
使用缩小以适应的公式:
-
计算使用的列长: 如果计算出的块尺寸是auto,并且至少有一个列数或列宽的指定值是auto,
则使用该框的块尺寸(如果它是确定的),
否则使用该框的拉伸适应块尺寸(如果它是确定的),
否则使用该框的最大内容块尺寸。
否则遵循正常的多列容器大小计算规则。
我们是否应该在公式中考虑框的最小内容块尺寸, 例如,大图像不会溢出框, 而是导致框溢出包含块?
- 计算使用的列数:如果计算出的列数是auto, 则使用的列数取决于填充多列布局的内容。
然后计算出最终多列容器的使用内联尺寸:
- 如果内容在多列容器中既没有换行也没有分段, 则使用的内联尺寸为框内容的最大内容内联尺寸。 这一标准提供了短正交流内容的缩小以适应行为, 而不会留下大的空白区域。
- 否则,它是根据使用的列宽、列数和列间距计算出来的。
使用的块尺寸为: 如果使用了多个列,则为使用的列长; 如果只使用了一个列,则为内容的最大内容块尺寸。 如果 UA 不支持 CSS 多列布局[CSS3COL], 则 UA 可以假设可用块空间是无限的, 以此计算框的块尺寸,从而将内容布局为单列。 (请注意,这可能导致内容被剪裁或溢出,使其不可访问。)
自动触发多列布局的功能处于风险状态,可能在 CR 阶段被取消。
7.3.3. 正交流其他根元素的自动调整大小
为了限制行的长度, 当块容器的可用内联空间是无限时(通常发生在它们建立了正交流时), 块容器具有特殊的自动调整大小行为(定义在上方)。
其他布局模型则简单地按照其最大内容尺寸的最大内容尺寸来布局到无限的可用内联空间。 然而,它们会将无限的可用内联空间传递给它们所包含的块容器, 可能会触发这些块容器的特殊自动调整大小行为, 尽管它们本身并未建立正交流。
例如, 一张表格或一个弹性容器建立了一个正交流 并按照其给定的可用空间进行布局。 如果其可用内联空间是无限的, 这实际上会将该框布局为其最大内容尺寸。 然而,任何其包含的表格单元或弹性项目, 如果是块容器,则会假定无限的可用内联空间并相应地表现。
7.3.4. 分割正交流
本节是信息性的。
关于分割,CSS2.1 中的规则仍然适用于垂直书写模式和正交流:断点机会不会出现在行框内部,只会出现在它们之间。 支持[CSS3COL]的用户代理可以在列间(可能是零宽度的)间隙中断开。
请注意,如果内容超出了由根元素建立的分页流, UA 没有义务打印这些内容。因此,作者在混合使用书写模式和长文本流时,应考虑使用 CSS 列布局, 以确保所有内容都在文档的分页方向上流动。
换句话说,如果你的文档在屏幕上需要两个滚动条,它可能不会完全打印出来。修复你的布局,例如使用列布局, 以确保所有内容都在一个方向上滚动(因此分页),以确保它能全部打印出来。T 形文档通常打印效果不佳。
7.4. 流向相对映射
流向相对方向是根据盒子的包含块的书写模式计算的,并用于抽象与盒子属性(如边距、边框、内边距)相关的布局规则, 以及与盒子在其包含块内的定位相关的任何属性 (浮动, 清除浮动, 上, 下, 左, 右, 标题侧)。 对于内联级别的盒子,使用父级盒子的书写模式。 (左右/上下命名的属性和值仍然是物理映射;对 标题侧做了特别的处理, 其上/上外和下/下外值 分别与表格的块开始和 块结束侧相关联。)
例如,当一个框的内联尺寸 约束过度时,丢弃的边距是根据包含块的书写模式确定的结束边距。
边距折叠规则完全适用于 块开始边距替换顶部边距,以及块结束边距替换底部边距。 同样,块开始的填充和边框 替代了顶部的填充和边框,块结束的填充和边框替代了底部的填充和边框。 注意,这意味着只有块开始和块结束的边距会折叠。
流相对方向是根据框的书写模式计算的,并用于抽象与框内容相关的布局:
- text-align属性的初始值 对齐到行框的开始边缘。
- text-indent属性从行框的开始边缘缩进。
- 对于表格,列的排序从表格的内联开始侧开始,行的排序从表格的块开始侧开始。
7.5. 行相对映射
行相对方向是上、下、行左和行右。 在LTR的水平-从上到下的书写模式中, 它们分别对应顶部、底部、左侧和右侧方向。
行右和行左方向是根据框的书写模式计算的, 用于解释以下属性的左和右值:
行右和行左方向是根据框的包含块的书写模式计算的, 用于解释以下属性的左和右值:
上和下方向是根据框的书写模式计算的, 用于定义如下对行框“顶部”(上)和“底部”(下)侧的解释:
- vertical-align属性, 行框的“顶部”是其上边缘; 行框的“底部”是其下边缘。 正值长度和百分比值 将基线向行上边缘移动。[CSS2]
- text-decoration属性, 下划线在文本的下侧绘制; 上划线在文本的上侧绘制。[CSS2] 请注意,CSS文本装饰模块对此进行了更详细的定义,并提供了额外的控件来控制下划线和上划线的位置。[CSS3-TEXT-DECOR]
7.6. 纯物理映射
以下值在其定义中是纯物理的, 不会响应书写模式的变化:
- rect()表示法在clip 属性中[CSS2]
- 背景属性[CSS2][CSS3BG]
- 边框图像属性[CSS3BG]
- box-shadow和text-shadow属性的偏移量
8. 主要书写模式
文档的主要书写模式 由根元素的使用的writing-mode、direction和 text-orientation值确定。 该书写模式用于确定滚动方向和默认的页面进程方向。
对于处理HTML文档的特殊情况,
如果根元素有一个
body
子元素[HTML],
那么根元素的使用值中的writing-mode和direction属性
将从第一个子元素的计算的writing-mode和direction值中获取,而不是从根元素的自身值获取。
UA可以 以这种方式传播text-orientation的值。
请注意,这不会影响根元素本身的writing-mode、direction或text-orientation的计算值。
注意:传播是基于使用值而不是计算值,以避免干扰样式计算的其他方面, 如继承、逻辑属性映射逻辑、 或长度值计算。
8.1. 向初始包含块的传播
主要书写模式 传播到初始包含块和视口, 从而影响根元素的布局 和视口的滚动方向。
8.2. 页面流:页面进程方向
在分页媒体中,CSS将所有页面分类为左页或右页。 页面进程方向(参见[CSS3PAGE]), 决定了跨页中左页或右页哪个先出现, 以及第一页是默认的左页还是右页, 取决于主要书写模式,具体如下:
主要书写模式 | 页面进程 |
---|---|
horizontal-tb 和 ltr | 从左到右 |
horizontal-tb 和 rtl | 从右到左 |
vertical-rl 或 sideways-rl | 从右到左 |
vertical-lr 或 sideways-lr | 从左到右 |
注意:除非另有覆盖,文档的第一页从跨页的后半部分开始,例如,在从左到右的页面进程中,第一页位于右页。
9. 字形组合
9.1. 竖排中的横向组合:text-combine-upright属性
名称: | text-combine-upright |
---|---|
值: | none | all | [ digits <integer>? ] |
初始值: | none |
适用于: | 非替换内联元素 |
继承: | 是 |
百分比: | 不适用 |
计算值: | 指定的关键字,若为 digits 则包括整数值 |
规范顺序: | 不适用 |
动画类型: | 不可动画 |
该属性指定将多个排版字符单元组合成一个字符单元的效果。 如果组合后的文本宽度超过1em,UA必须将内容调整到1em内,如下所示。 组合结果在布局和装饰中视为一个单一的竖直字形。 该属性仅在竖排书写模式下有效,值的含义如下:
- none
- 无特殊处理。
- all
- 尝试水平排版 盒子内的所有连续排版字符单元, 使其占据竖直线盒中的一个排版字符单元的空间。
- digits <integer>?
- 尝试水平排版 每个连续的ASCII数字序列(U+0030–U+0039), 如果数字个数不超过指定的整数, 则使其占据竖直线盒中的一个排版字符单元的空间。 如果省略整数,默认计算为2。 超出2-4范围的整数是无效的。
在东亚文档中,text-combine-upright效果常用于显示拉丁字符的字符串,如日期组件或 首字母缩写,无论文本的书写模式如何,它们总是以水平书写模式呈现:
横排竖写的例子,日语中的tate-chu-yoko效果
该效果由以下规则实现
date { text-combine-upright: digits 2; }
以及以下标记:
<date>平成20年4月16日に</date>
在日语中,这种效果称为tate-chu-yoko。
以下示例显示了对整个文档应用text-combine-upright: digits 2可能会产生意想不到的后果:
<p>あれは10,000円ですよ!</p>
错误应用tate-chu-yoko的例子
9.1.1. 文字运行规则
为了避免渲染和布局的复杂性,text-combine-upright 只能组合纯文本: 不能被盒子边界打断的连续排版字符单元。
然而,由于该属性继承, UA必须确保影响组合的盒子内容 不属于一个开始或结束于该盒子之外的可组合序列的一部分; 如果是这样,那么文本将正常布局, 就像text-combine-upright值为none一样。 为避免只组合部分序列: 如果潜在组合运行的边界 仅由于一个或多个内联盒子边界, UA必须检查在运行之前和之后出现的字符, 如果这些字符在没有干扰盒子的情况下会形成一个可组合的序列(如果它不太长), 那么该候选运行不应组合。
上述段落为风险内容,欢迎实现者提出意见。
例如,给定规则
tcy { text-combine-upright: digits 4; }
如果提供以下标记:
<tcy>12<span>34</span></tcy>
不会有文本被组合:12 和 34 共享相同的祖先元素并具有相同的text-combine-upright值, 因此它们被认为是被盒子边界打断的四个可组合数字的序列。 但在这些情况下:
12<tcy><span>34</span></tcy>12<tcy><span></span>34</tcy> 12<tcy>34<span></span></tcy>
34 将会被组合,因为 12 与 34 没有共享一个拥有相同text-combine-upright值的祖先, 因此 34 被认为是两位可组合数字的整个序列。
如果我们使用规则
tcy { text-combine-upright: all; }
结果将是相同的: 第一个例子不会组合,因为 1234 形成了一个被盒子边界打断的四个可组合字符的序列, 而第二个例子中 34 会被组合,因为它形成了两个可组合字符的整个序列。
请注意,text-combine-upright 的值(all或digits) 仅影响哪些类型的排版字符单元可以被组合 以及组合序列的最大长度。 它不会改变其他行为。
9.1.2. 布局规则
当组合文本时,text-combine-upright: all的效果为, 组合文本的字形是双向隔离的,并且水平排版 (忽略字母间距和任何强制换行, 但使用指定的字体设置), 类似于具有inline-block盒子的内容, 具有水平书写模式和 line-height为1em。 包含在组合文本开始/结束的任何文档空白 将被视为这种inline-block的开始/结束进行处理[CSS-TEXT-3]。 组合的有效尺寸假设为1em的正方形; 正方形之外的任何内容不计入布局目的。 UA应将字形在1em正方形内水平和垂直居中。
生成的组合的基线必须被选择,使得正方形在父内联盒子的文本上方和文本下方基线之间居中, 之前未进行任何基线对齐位移vertical-align。 在双向重排时,组合被视为具有text-orientation: upright的 排版字符单元。 对于组合之前和之后的换行,它被视为具有其实际内容的常规内联元素。 对于其他文本布局目的, 例如重点标记、文本装饰、间距等,组合结果被视为表示对象替换字符U+FFFC的单个字形。
9.1.3. 压缩规则
UA 必须确保组合的前进宽度适合 1em,必要时通过压缩组合文本。
(这并不意味着字形一定会适合 1em,因为某些字形的设计是绘制在其几何边界之外的。)
OpenType 实现必须使用特定宽度的变体
(OpenType 功能hwid
/twid
/qwid
;
其他字形宽度功能如fwid
或pwid
不包括在内)
压缩文本,
当这些变体可用于组成中的所有排版字符单元时。
否则,UA 可以使用任何方法压缩文本,
包括替换由字体提供的半宽、三分之一宽和/或四分之一宽字形,
使用旨在水平压缩文本的其他字体功能,
几何缩放文本,
或这些方法的任意组合。
例如,一个简单的基于 OpenType 的实现可能会按如下方式压缩文本:
- 为由n个排版字符单元组合的文本启用 1/n-宽字形
(即对 2 个 排版字符单元使用 OpenType
hwid
,对 3 个 排版字符单元使用twid
,等等), 如果排版字符单元数量 > 1。 请注意,排版字符单元的数量 ≠ Unicode 码点数量! - 如果结果宽于 1em,则将结果水平缩放为 1em。
另一种利用 OpenType 布局功能的实现可能首先使用正常字形组合文本以查看是否合适, 然后在需要时替换半宽或三分之一宽的形式, 可能会根据可用的字形替换调整其方法或与缩放操作相结合。
在某些字体中,表意字形的设计为压缩,使其宽为 1em 但高度小于 1em。 为了适应此类字体,UA 可以垂直缩放组合以匹配按照指定字体设置渲染的水 U+6C34 的前进高度。 在这种情况下,生成的组合假设水 U+6C34 的前进高度,而不是 1em。
9.1.3.1. 全宽字符
为了在将文本压缩到 1em 时保持排版颜色, 当组合文本包含多个排版字符单元时, 应首先通过反向应用为text-transform: full-width定义的算法, 将任何全宽的排版字符单元转换为其非全宽等效字符, 然后再应用其他压缩技术。
例如,作者可能对设置为垂直文本的日期同时应用text-transform和text-combine-upright。
date { text-combine-upright: digits 2; text-transform: full-width; }
假设该样式规则应用于类似这样的日期。
<date>2010年2月23日</date>
"2010" 太长而无法组合(4 位数字),但 "2" 和 "23" 将会受影响。 由于 "23" 包含多个排版字符单元, 它不会受到text-transform: full-width的影响。 但是由于 "2" 只有一个排版字符单元, 它将被转换为全角的"2"。 由于 "2010" 未被组合,它的数字也将被转换为全角的"2010"; 并且由于是全角,它们将竖直排版,结果如下:
2 0 1 0 年 2 月 23 日
影响字形选择的属性, 例如font-variant和font-feature-settings, 定义在[CSS3-FONTS]中, 可能会影响组合文本运行中字符的变体选择。 当同时使用text-combine-upright时,建议作者谨慎使用这些属性。
10. 隐私和安全注意事项
该规范没有引入新的隐私泄漏, 或“正确实现”之外的安全考虑。
更改
自 2018 年 5 月 CSS 书写模式模块第 4 级候选推荐规范以来的更改
- 澄清了从 body 元素传播主要书写模式到初始包含块和视口确实会影响根元素的使用值, 但不会影响其计算值。 另外,允许可选传播text-orientation。 这一变化也应用到了第 3 级。 (问题 3066)
-
澄清了—特别是在组合文本序列的开始/结束处—text-combine-upright中的空白处理方式与内联块相同。
(问题 4139)
这一变化也应用到了第 3 级。
当组合文本时,如为text-combine-upright: all, 组合文本的字形被双向隔离并水平排版 (忽略字母间距和任何强制换行, 但使用指定的字体设置), 类似于一个内联块盒子的内容, 使用水平书写模式和1em的行高。 包含在组合文本开始/结束处的任何文档空白将按内联块的方式 处理 [CSS-TEXT-3]。
第 4 级中的新增功能
该模块只是2015 年 CSS Writing Modes 第 3 级候选推荐规范的副本。 与当前 CSS Writing Modes 第 3 级的不同之处在于以下由于后来实现更新而从第 3 级推迟的功能:
- 重新引入了sideways-lr和sideways-rl值到writing-mode属性中
- 重新引入了text-combine-upright属性的 digits值。
- 重新引入了正交流的自动多列行为。
- 澄清了双向重排引起的碎片化的条件。 (问题 1509)
致谢
L. David Baron, Brian Birtles, James Clark, John Daggett, Nami Fujii, Daisaku Hataoka,Martin Heijdra,Laurentiu Iancu, Richard Ishida, Jonathan Kew, Yasuo Kida,Tatsuo Kobayashi,Toshi Kobayashi, Ken Lunde, Shunsuke Matsuki, Nat McCully,Eric Muller, Paul Nelson,Kenzou Onozawa, Chris Pratley, Xidorn Quan, Florian Rivoal, Dwayne Robinson, Simon Sapin, Marcin Sawicki, Dirk Schulze, Hajime Shiozawa, Alan Stearns, Michel Suignard, Takao Suzuki, Gérard Talbot, Masataka Yakura, Taro Yamamoto, Steve Zilles
附录 A: Unicode 中的垂直脚本
本节是信息性内容。
该附录列出了 Unicode 6.0 中的仅垂直和双向脚本及其从横向到纵向的变换。 未明确列出的任何脚本都被视为仅横向。 Unicode 字符的脚本分类由[UAX24]提供。
代码 | 名称 | 变换 (顺时针) | 垂直固有方向 |
---|---|---|---|
Bopo | 注音符号 | 0° | ttb |
Egyp | 埃及象形文字 | 0° | ttb |
Hira | 平假名 | 0° | ttb |
Kana | 片假名 | 0° | ttb |
Hani | 汉字 | 0° | ttb |
Hang | 谚文 | 0° | ttb |
Merc | 梅罗埃草书 | 0° | ttb |
Mero | 梅罗埃象形文字 | 0° | ttb |
Mong | 蒙古文 | 90° | ttb |
Ogam | 欧甘文 | -90° | btt |
Orkh | 古突厥文 | -90° | ttb |
Phag | 八思巴文 | 90° | ttb |
Yiii | 彝文 | 0° | ttb |
例外情况:根据本规范的目的,所有全宽(F)和宽(W)字符都被视为属于垂直脚本, 半宽字符(H)则被视为属于横向脚本。 [UAX11]
请注意,对于仅垂直字符(如蒙古文和八思巴文字母), Unicode 代码表中的字形以其垂直方向显示。 在横向文本中,它们以顺时针旋转 90°的方式排版。
由于 Unicode 技术报告 50 和 CSS Writing Modes 当前功能集的限制, 垂直混合排版无法自动处理欧甘文或古突厥文。 对于这些脚本,可以使用sideways-lr来排版这些段落。