CSS Ruby 注释布局模块 1 级

W3C 工作草案,

关于本文档的更多信息
此版本:
https://www.w3.org/TR/2022/WD-css-ruby-1-20221231/
最新发布版本:
https://www.w3.org/TR/css-ruby-1/
编辑草稿:
https://drafts.csswg.org/css-ruby-1/
历史版本:
历史记录:
https://www.w3.org/standards/history/css-ruby-1
测试套件:
https://www.w3.org/International/tests/repo/results/css-ruby
反馈:
CSSWG 问题仓库
文档内反馈
编辑者:
Elika J. Etemad / fantasai (特邀专家)
(Google)
Xidorn Quan (Mozilla)
Florian Rivoal (特邀专家)
为本规范建议修改:
GitHub 编辑器

摘要

“Ruby”是一种行间注释的形式,即在主文本旁显示简短的文本。 它们通常用于东亚文档中,用于标注发音或提供简短说明。 本模块描述了与在CSS中显示ruby注释有关的渲染模型和格式控制。

CSS 是一种用于描述结构化文档(如HTML和XML)在屏幕、纸张等上的渲染语言。

本文档状态

本节描述了本文档在发布时的状态。 当前W3C出版物列表 以及本技术报告的最新版本 可在 W3C技术报告索引 https://www.w3.org/TR/ 找到。

本文档由 CSS工作组 作为推荐标准流程下的 工作草案 发布。 作为工作草案发布 并不代表 W3C 及其成员的认可。

本文档为草稿文档 可能会随时被更新、替换或废弃。 除了作为在研工作外,不应引用本文档。

如有反馈,请优先通过在GitHub提交issue, 并在标题中包含规范代码“css-ruby”,格式如下: “[css-ruby] …评论摘要…”。 所有问题和评论都会被归档。 或者,也可以发送至(归档)公共邮件列表 www-style@w3.org

本文件受 2021年11月2日W3C流程文件 管辖。

本文件由遵循W3C专利政策的工作组产生。 W3C 保持一份与本工作组成果相关的专利披露公开列表; 该页面还包含专利披露的说明。 任何实际知晓某项专利、且认为其包含必要声明的个人,必须按照W3C专利政策第6节的要求披露相关信息。

1. 引言

1.1. 什么是 ruby?

本小节不具规范性。

Ruby 是指一段与另一段文本(称为“基底”)并排出现的文本, 用作该文本的注释或发音标注的通用名称。

日文文本中每个汉字上方带有平假名注音的ruby示例
一段日文文本,每个汉字上方有注音ruby,标明每个字的发音。

下列插图展示了两种 Ruby 的例子, 一个简单情况和一个结构更复杂的情况。

在此示例中,单个注释用于标注由多个字符组成的基底文本。
在日文短语上方应用ruby的示例

日文中使用ruby的示例(简单情况)

在日文排版中,这种情况有时被称为 taigo ruby(日文:対語ルビ,即按词注音)或组ruby, 因为注释整体与多字符单词(作为整体)关联。

在第二个示例中, 有两层注释附加在基底文本上: 上方的平假名用于标注每个基底汉字的发音, 下方的“Keio”和“University”则给出了英文翻译。
复杂ruby示例,基底字符上下均有注释文本

复杂ruby,基底字符的上方和下方均有注释文本

注意,为了正确对应 平假名与其相应的汉字基底字符, 基底文本中的间距会做相应调整。 (如上图中第四个汉字,其注音为三个字符。) 为避免上述示例中基底文本间距变化, 可以将平假名注释设为合并注释, 这样效果会更接近前面的组ruby示例。 但由于基底-注释配对关系已记录在ruby结构中, 若文本换行,注释字符仍会与其基底字符正确配对。

在 HTML 中,ruby 结构及其标记描述见 Ruby Markup Extension 规范。 本模块描述与这种标记的 ruby 布局相关的 CSS 渲染模型及格式控制。

有关 Ruby 及其 格式化的更深入介绍 可以在“What is Ruby”文章 [QA-RUBY] 中找到。 有关ruby 在日语中传统上采用的主要 格式化方式的大量信息 可以在 JIS X-4051 [JIS4051](日语) 以及 日文文本布局需求 [JLREQ](英语和日语)中的 “Ruby 与着重号”中找到; 日文 Ruby 简单放置规则 [SIMPLE-RUBY] 还 (以英语)描述了一种可能的日文 ruby 格式化方法。“行间注释”中文排版需求 [CLREQ] 中描述了 中文排版中的相关实践(中文和英语)。

1.2. 模块交互

本模块扩展了 CSS Level 2 [CSS2] 的行内盒模型,以支持 ruby。

本模块中的属性均不适用于 ::first-line::first-letter 伪元素; 但 ruby-position 可通过 ::first-line 继承,影响首行上的 ruby 注释。

1.3. 值定义

本规范遵循 CSS属性定义约定(见 [CSS2]),并采用 值定义语法(见 [CSS-VALUES-3])。 未在本规范中定义的值类型,可参见 CSS Values & Units [CSS-VALUES-3]。 与其他CSS模块结合时,这些值类型的定义可能会被扩展。

除各自定义中列出的属性特定值外, 本规范定义的所有属性 还接受 CSS通用关键字 作为属性值。 为了可读性,这里未一一重复列出。

1.4. 图例约定

本小节不具规范性。

东亚排版的许多习惯 都取决于所渲染字符是宽字符(CJK)还是窄字符(非CJK)。 本文档中有多处插图采用如下图例:

宽单元格字形示意
宽单元格字形(如汉字),为文本流中的第 n 个字符。 作为注释时通常缩放为50%大小。
窄单元格字形示意
窄单元格字形(如拉丁字母),为文本流中的第 n 个字形。

上述符号在图中的方向 与其实际渲染时的字形方向一致。 图中这些字符之间的间距一般无实际意义, 除非特意调整以便说明。

2. Ruby盒模型

CSS的ruby模型基于 W3C HTML5 Ruby 标记 模型 以及 XHTML Ruby 注释推荐规范 [RUBY]。 在该模型中,ruby结构由 一个或多个 ruby基底 元素(表示被注释的基底文本)组成, 并与一个或多个层级的 ruby注释 元素(表示注释内容)关联。 其结构类似于表格: 有“行”(即 基底文本层、每个 注释层) 也有“”(每个 ruby基底 及其对应的 ruby注释)。

Ruby结构如表格排布,
		          第一“列”包含一个基底盒的‘上’,下方注释盒居中显示‘じょう’,
		          第二“列”包含另一个基底盒的‘手’,下方注释盒居中显示‘ず’。
日语复合词“上手”带有注音“じょうず”。每个音节都与其基底字符单独关联。

一组连续的基底及其连续的注释会被归为一个 ruby段。 在一个 ruby段内,ruby注释可以跨多个 ruby基底

Ruby结构如表格排布,
		          第一“列”包含基底盒‘旧’,上方注释盒居中‘jiù’,
		          第二“列”包含基底盒‘金’,上方注释盒居中‘jīn’,
		          第三“列”包含基底盒‘山’,上方注释盒居中‘shān’,
		          下方注释盒‘San Francisco’横跨三列。
中国城市名“旧金山”带有拼音“jiùjīnshān”及英文名“San Francisco”。每个拼音音节与其基底字符分别关联,而英文名则与整体关联。

注: 在 HTML 中,单个 <ruby> 元素可包含多个 ruby段。 (而在 XHTML Ruby 模型中,一个 <ruby> 元素只能包含一个 ruby段。)

2.1. Ruby专用 display

对于没有预定义ruby元素的文档语言(如某些XML应用), 作者需将文档语言元素映射为ruby元素; 这可通过 display 属性实现。

名称: display
新增值: ruby | ruby-base | ruby-text | ruby-base-container | ruby-text-container

以下新的 display 值可为任意元素分配ruby布局角色:

ruby
指定元素生成一个 ruby容器盒。 (对应HTML/XHTML中的 <ruby> 元素。)
ruby-base
指定元素生成一个 ruby基底盒。 (对应HTML/XHTML中的 <rb> 元素。)
ruby-text
指定元素生成一个 ruby注释盒。 (对应HTML/XHTML中的 <rt> 元素。)
ruby-base-container
指定元素生成一个 ruby基底容器盒。 (对应XHTML中的 <rbc> 元素;在HTML中生成匿名盒。)
ruby-text-container
指定元素生成一个 ruby注释容器盒。 (对应HTML/XHTML中的 <rtc> 元素。)

如使用支持专用ruby标记的语言(如HTML), 应优先使用该标记, 而非仅对任意元素(如 <span>)应用ruby display 值。 正确使用标记可保证屏幕阅读器 及非CSS渲染器能正确识别ruby结构。

注: 替换元素 设置为 displayruby-baseruby-textruby-base-containerruby-text-container 时,均视为 行内级盒, 详见 CSS Display 3 § 2.4 布局内部display类型:table-*与ruby-*关键字替换元素display 值为 rubyinline ruby 时,根据其 外部display类型 行为, 详见 CSS Display 3 § 2.1 流式布局的外部display角色:block、inline和run-in关键字。 (参见 § 2.1.2 非行内ruby。)

2.1.1. Ruby格式化上下文

Ruby容器是非原子的 行内级盒。 与普通的行内盒类似(参见CSS Inline Layout 3 第2节 行内布局模型), 它们可以跨行断开, 且其包含块是最近的块级容器祖先。 就像行内盒的内容参与包含该行内盒自身的同一个 行内格式化上下文一样, ruby容器及其基底层内容 也参与包含该ruby容器自身的同一个行内格式化上下文

然而,ruby容器还会建立一个ruby格式化上下文,在其所处的 行内格式化上下文的片段基础上构建更多结构,以承载其注释。 注意:此格式化上下文不是独立格式化上下文 Ruby基底ruby注释ruby基底容器ruby注释容器内部ruby盒: 类似于内部表格元素, 它们在ruby布局中有特定的作用, 并参与其ruby容器ruby格式化上下文。 除了在ruby格式化上下文中的角色之外, ruby基底还同时参与与ruby容器同级的基底层 行内格式化上下文, 而ruby注释则参与由ruby容器建立的独立注释层 行内格式化上下文

行内盒的内容一样, ruby 容器(以及其所有内部 ruby 盒)内容的包含块 是该ruby 容器包含块。 因此,例如,浮动会被ruby 容器包含块限制, 而不是被任何一种 ruby 盒类型限制。

2.1.2. 非行内ruby

如果一个元素的内部display类型ruby,而外部display类型不是 inline, 则会生成两个盒: 一个指定的外部display类型的主盒, 以及一个行内级的ruby容器。 元素上指定的所有属性应用于主盒 (可继承的属性则会继承到ruby容器盒)。 这样可以将元素样式化为块级, 同时仍能正确维护内部的ruby结构。

注意: 绝对定位或浮动元素会导致其display 值 计算为块级等价值。(参见[CSS-DISPLAY-3][CSS2] 第9.7节。) 对于内部ruby显示类型, 这会使它们的display值计算为block

2.2. 匿名ruby盒生成

CSS模型不要求文档语言 必须包含与每个组件对应的元素。 缺失的结构部分通过匿名盒生成规则隐式推断,类似于表格的归一化处理。(见[CSS2]

  1. 行内化块级盒: 任何由ruby容器ruby基底容器ruby注释容器ruby基底盒ruby注释盒 直接包含的流内盒, 必须按照[CSS-DISPLAY-3]行内化规则行内化, 并相应计算其display值, 以便它们仅包含行内级内容。 例如, 被一个displaydisplay: block的父元素包裹、且本身在流内的元素, 如果其父元素的display: ruby-text, 则其display属性会计算为inline-block
  2. 生成匿名ruby容器: 任何连续的未正确包含的 ruby基底容器ruby注释容器ruby基底盒和/或 ruby注释盒(及其间的空白) 会被包裹在一个匿名ruby容器中。 本步骤中:
  3. 包裹父级错误的行内级内容: 任何由ruby容器ruby基底容器直接包含的文本和行内级盒的连续序列, 会被包裹在一个匿名ruby基底中。 类似地,任何由ruby注释容器直接包含的文本和行内级盒的连续序列, 会被包裹在一个匿名ruby注释中。 (为此目的,被视为内部表格元素的错误父级元素, 也被视为行内级内容,因为它们最终会被ruby盒包裹成 行内级表包装盒。)

    但如果这样构建的匿名盒只包含空白, 则该盒被视为ruby内部空白,其是否丢弃 或保留见下文说明。

  4. 移除首尾空白: 任何ruby内部空白,如果不是父元素唯一的流内子元素,并且是 ruby容器ruby注释容器ruby基底容器的第一个或最后一个 流内子元素,则移除它,如同其有display: none
  5. 移除层间空白: 任何ruby内部空白,其紧邻的流内兄弟元素匹配下列模式之一, 就是层间空白,并被移除,如同其有display: none
    前一个盒 后一个盒
    任意 ruby注释容器
    不是ruby注释 ruby注释
  6. 解释层内空白: 任何ruby内部空白盒, 其紧邻的流内兄弟元素 匹配下表之一时, 赋予该盒相应类型及子类型:
    前一个盒 后一个盒 盒类型 子类型
    ruby基底 ruby基底 ruby基底 基底间空白
    ruby注释 ruby注释 ruby注释 注释间空白
    ruby注释ruby注释容器 ruby基底ruby基底容器 ruby基底 段间空白
    ruby基底ruby基底容器 ruby基底容器
    ruby基底容器 ruby基底ruby基底容器
    上述定义的层内空白盒 在配对和布局时有特殊处理。 见下文。
  7. 抑制换行: 转换所有ruby注释内部的强制换行(无论white-space值如何), 按照CSS Text Level 3 § 4.1.2中的可折叠段落断点处理。

    这样做的目的是通过抑制ruby注释中的换行简化布局模型。 也可以尝试对其定义某种可接受的行为。

  8. 生成匿名层级容器: 任何没有被ruby基底容器包裹的 ruby基底基底间空白的连续序列 (且不是段间空白), 会被包裹在匿名ruby基底容器中。 类似地,任何没有被ruby注释容器包裹的 ruby注释注释间空白的连续序列, 会被包裹在匿名ruby注释容器中。

一旦所有ruby布局结构都正确包裹, UA即可开始将基底与注释关联。

注意: UA无需在内部结构中实际创建这些匿名盒 (或层内空白匿名空盒,见§ 2.3 注释配对), 只要配对和布局行为如同这些盒存在即可。

下图展示了表示各种盒子的标记图, 展示了ruby内部空白被保留或丢弃的位置:
<ruby>×<rbc>×<rb></rb><rb></rb>×</rbc><rtc>×<rt></rt><rt></rt>×</rtc><rbc>×<rb></rb></rtc>×</ruby>

其中

2.3. 注释配对

注释配对是将ruby注释ruby基底关联的过程。 每个ruby注释关联一个或多个ruby基底, 称为跨基底。 (ruby注释如果多个基底, 则称为跨基底注释。)

一个ruby基底在每个注释层只能关联一个ruby注释。 但如果有多个注释层, 则可关联多个ruby注释

一旦配对完成,定义ruby列, 每列由一个ruby基底和每个 行内注释注释层中的一个ruby注释(可能是匿名空注释)组成,均来自其ruby段

2.3.1. 段配对与注释层级

一个 ruby 结构被划分为ruby 分段, 每个分段由单个ruby 基底容器后跟一个或多个ruby 注释容器组成。 ruby 分段中的每个ruby 注释容器表示基底文本的一个 注释层级: 第一个表示第一级注释, 第二个表示第二级注释, 依此类推。 ruby 基底容器表示基底层级。 因此,每个分段中的ruby 基底容器都与 该分段中的每个ruby 注释容器配对。

为处理退化情况,假定有若干匿名空容器:

段间空白实质上是一个独立的ruby段

2.3.2. 单元配对与跨基底注释

在一个ruby 分段内, ruby 基底 容器中的每个ruby 基底都与其ruby 分段中每个ruby 注释 容器中的一个ruby 注释配对。

如果一个ruby 注释容器仅包含 一个匿名ruby 注释, 则该ruby 注释与其 ruby 分段中的所有ruby 基底配对(即跨越所有这些基底)。

否则,每个ruby 注释都按文档顺序 与该分段中对应的ruby 基底配对。 如果一个ruby 注释容器中没有足够的ruby 注释, 则剩余的ruby 基底与 插入到ruby 注释 容器末尾的匿名空注释配对。 如果没有足够的ruby 基底, 则所有剩余的ruby 注释与 插入到ruby 基底容器末尾的匿名空基底配对。

如果一个实现支持具有显式跨越的 ruby 标记 (例如 XHTML 复杂 Ruby 注释), 则它必须调整配对规则,以将 跨越 注释与其基底正确配对。

层内 空白不参与标准注释配对。 但是,如果紧邻的ruby 基底ruby 注释与以下内容配对

下图展示了普通基底注释盒的配对,以及 ruby内部空白(以ws表示)的配对:
|[  s p a n n i n g   a n n o t a t i o n ]|
|[ a1 ]|[ws]|[ a2 ]|[  ]|[ a3 ]|[ws]|[ a4 ]|
|[ b1 ]|[ws]|[ b2 ]|[ws]|[ b3 ]|[  ]|[ b4 ]|

蓝色方括号([ ])表示基底盒, 红色方括号([ ])表示注释盒, 灰色竖线(|)表示ruby列的边界, [ws]表示ruby内部空白, 而[]表示自动生成与另一层的层内空白配对的匿名空基底或注释。 ruby容器基底容器注释容器省略不画。

2.4. 隐藏注释:visibility: collapse 和自动隐藏ruby

ruby注释visibilitycollapse,则该注释为隐藏注释。 此外, 若某ruby注释与其基底文本内容完全相同, UA会自动将其隐藏自动隐藏)。

隐藏一个ruby 注释 不会影响注释配对。 但是,隐藏的注释不可见, 并且它不会对布局产生影响, 除了会分隔其层级内相邻的ruby 注释 盒序列, 就好像它们属于不同的分段, 并且隐藏的注释的基底不是ruby 基底,而是一个介于其间的 行内盒。

自动隐藏机制可以正确内联显示包含汉字和平假名混合的日文词汇的注释。 例如,单词振り仮名应内联显示为:

振り仮名(ふりがな)

因此其标记如下:

<ruby>
  <rb></rb><rb></rb><rb></rb><rb></rb>
  <rp>(</rp><rt></rt><rt></rt><rt></rt><rt></rt><rp>)</rp>
</ruby>

但以ruby显示时,“り”应被隐藏:

振り仮名的平假名注音显示,每个汉字上方有对应发音,但‘り’上方无注音。

振り仮名的平假名ruby。注意‘り’已经是平假名,因此其上方没有注释。

此例中的日文单词由三个汉字组成, 其中一个为一年级常用字, 另两个较难。 (字符用颜色区分基底配对关系。)
<ruby><rb><rb><rb><rt>こん</rt class=easy>ちゅう</rt></ruby>
昆虫记三个汉字均带有注音,中间注音较宽,基底字符间有空隙避免注音重叠。
完整注音的三字词

虽然有些读者需要全部字的发音, 但对其他人来说,隐藏简单字符的注音更合适。 应用visibility: collapse即可隐藏:

昆虫记仅首尾汉字带有注音,居中注音已隐藏。
中间注音设置为visibility: collapse

隐藏行为 在 visibility: collapsevisibility: hidden 之间有所不同—后者会使注释不可见, 但不会消除其对布局的影响:

昆虫记,首尾注音正常,中间注音虽不可见但仍占空间,导致基底字符间距扩大。
中间注音设置为visibility: hidden

这也不同于display: none,因为visibility: collapse会保留配对关系, 而display: none会完全移除盒, 导致后续注释配对错乱:

昆虫记,注音错位:第二字符注音被移除后,第三字符注音显示在第二上方。
中间注音设置为display: none

计算值ruby-merge注释容器merge时,将禁用隐藏。 若为auto, UA可决定是否禁用其注释的隐藏, 推荐在UA布局算法生成类似separate效果时启用隐藏

自动隐藏时的内容比较在空白折叠(white-space)和文本转换(text-transform)之前, 并忽略元素(仅比较盒的textContent)。

注:后续CSS Ruby级别可能会增加自动隐藏的控制, 但在本级别中始终强制自动隐藏。

2.5. 空白折叠

§ 2.2 匿名ruby盒生成所述, ruby结构内的空白会被丢弃

例如,下列标记不会显示任何空白:
<ruby>
  <rb></rb><rb></rb>
  <rt>とう</rt><rt>きょう</rt>
  <rtc><rt></rt><rt>kyō</rt></rtc>
</ruby>

但在ruby段之间、ruby基底之间、ruby注释之间, 空白不会被丢弃, 会作为基底间空白注释间空白段间空白保留渲染。 (见上文层内空白解释。)

空白保留规则允许ruby用于如拉丁文等以空格分隔的书写系统。 例如:
<ruby>
  <rb>W</rb><rb>W</rb><rb>W</rb>
  <rt>World</rt> <rt>Wide</rt> <rt>Web</rt>
</ruby>

同时也保证带注释的空白被保留。例如:

<ruby>
  <rb>Aerith</rb><rb> </rb><rb>Gainsborough</rb>
  <rt>エアリス</rt><rt></rt><rt>ゲインズブール</rt>
</ruby>

若未丢弃的空白为可折叠空白, 则在每个行盒内会按照标准空白处理规则 [CSS-TEXT-3]跨相邻盒折叠。 不同ruby段的注释 或被隐藏注释分隔的注释不视为相邻; 但所有基底层内容 (包括被视为原子行内字间注释) 均视为相邻。 对于可折叠空白ruby段之间(段间空白), 用于确定分段断点转换的上下文文本 为两侧的ruby基底, 而非文档顺序上空白两侧的文本(可能包含行内注释)。

注:空白处理规则 使得包含分段断点 (如换行符)的空白序列 会在汉字与假名之间折叠为无内容。 这意味着中日文ruby可以安全用空白缩进ruby标记。 例如下例不会显示任何空白:
<ruby><rt>おく</rt><rt>ない</rt><rt>きん</rt><rt>えん</rt>
</ruby>

但若空白中不含分段断点, 则不会完全折叠,因此下例首对与次对ruby之间会显示空格:

<ruby><rt>おく</rt><rt>ない</rt><rt>きん</rt><rt>えん</rt>
</ruby>

3. Ruby布局

当ruby结构进行布局时, 其基底层首先在线上布局, 就像其ruby基底是一串普通行内盒ruby容器是包裹其中的普通行内盒一样。

如果ruby容器包含 字间注释, 则如§ 3.2 字间ruby布局所述,将其布局进基底层。 然后,对基底容器定尺寸, 并按行内注释§ 3.1 行间ruby布局的方法布局注释。

与其他CSS布局模型一样, 相对定位、变换等图形效果会在盒布局后应用。

3.1. 行间ruby布局

行间 ruby注释 在同一层内, 初始布局与行内盒相同, 参与同一个行内格式化上下文, 为该注释层ruby容器中建立一个行盒注释基底的对齐方式如下文调整间距所述。

3.1.1. 行内轴上的行间布局

在行内轴上,行间ruby 注释根据其注释容器ruby-merge 值,相对于其ruby 基底 盒进行对齐。

ruby-mergeseparate 时, 每个ruby 列的尺寸 会调整为该中最宽内容(ruby 基底ruby 注释)的尺寸。 对于跨越注释(无论是实际跨越,还是按照 ruby-merge: merge 假装跨越), 如果跨越注释的内容宽于 它所跨越的, 则其差值会在所跨越的之间平均分配。 如果一个ruby 分段包含 多个跨越注释, 则这种额外空间的分配 从跨越基底数量最少的跨越注释开始执行, 然后按照所跨越基底数量递增的顺序执行。 随后调整每个ruby 基底ruby 注释的尺寸,使其恰好跨越其所在的一个或多个列。

注: 如果不同层级中有多个注释跨越 相同数量的基底, 且彼此重叠但不完全重合, 则空间的分配方式未定义。 请注意,HTML 标记不可能产生这种情况, 但在具有显式跨越功能的标记语言中可能发生,例如 [RUBY]

如果 ruby-merge: auto注释容器中的任何ruby 注释宽于其基底, 则该注释容器中的ruby 注释可以延伸到其之外。 当它们这样做时,它们对 所相交尺寸的影响 由用户代理决定, 前提是使ruby 分段足够宽,以容纳其所有内容。

字符间注释交错放置 在列之间: 它们会计入跨越相邻两个列的注释的尺寸测量, 但不包含在任一列中, 并且永远不会受到行间 注释的尺寸调整或定位的影响。

在每个基底盒和注释盒内, 当其内容窄于盒的宽度时, 如何分配额外空间 由其 ruby-align 属性指定。

以下图示说明了这些规则, 涵盖典型情况 以及一些更复杂的情况。 在每种情况下,假定基底盒注释盒 都具有 ruby-align: center, 而注释容器则假定具有 ruby-align: space-between

蓝色方括号([ ])表示基底盒, 红色方括号([ ])表示注释盒, 灰色竖线(|)表示ruby 列的边界。Ruby 容器基底容器注释容器均被省略。

分离 / 非跨越:
|[ 注释1 ]|[ 注释2 ]|[   注释3   ]|
|[基底 1]|[基底 2]|[   基底 3   ]|

每个内的盒都会调整尺寸,以匹配该中最宽的盒。 每个基底盒注释盒上的 ruby-align 值用于 分配每个盒中的额外空间。

跨越(较短):
|[ 注释1 ]|[   较短跨越   ]|
|[基底 1]|[基底 2]|[基底 3]|

跨越注释比其跨越的基底短时, 没有额外空间可分配给这些基底跨越注释内的额外空间 根据该注释盒上的 ruby-align 进行分配, 与非跨越注释相同。

跨越(较长):
|[ 注释1 ]|[   跨越注释   ]|
|[基底 1]|[ 基底 2 ]|[ 基底 3 ]|

跨越注释比其跨越的基底盒长时, 额外空间会在它们之间平均分配。

合并(较短):
|[合并          注释]|
|[基底 1]|[基底 2]|[基底 3]|

合并 注释的行为与跨越注释类似, 不同之处在于,其中任何额外空间的分配 由注释容器上的 ruby-align 值决定, 而不是由其任何注释盒上的值决定。

多个层级,带 跨越注释:
|[  注释1  ]|[   注释2   ]|[  注释3  ]|
|[     跨越所有内容的长注释      ]|
|[ 基底 1 ]|[    基底 2    ]|[ 基底 3 ]|
|[  xx  ]|[    跨越基底的注释    ]|
|[ 注释1 ]|[   注释2   ]|[  注释3  ]|
|[基底 1]|[    基底 2    ]|[ 基底 3 ]|

在这两个具有多个层级的示例中, 每个都会 根据其中最长的内容调整尺寸, 而仍长于其所跨越总宽度的跨越注释 会进一步增大这些列, 并向每一列等量增加空间。

多个 层级,带多个跨越注释:
|[   xx   ]|[  跨越基底的注释  ]|
|[  注释1  ]|[   注释2   ]|[   注释3   ]|
|[      跨越基底内容的长注释       ]|
|[ 基底 1 ]|[     基底 2     ]|[  基底 3  ]|

当存在多个跨越注释时, 跨越基底数量最少的会优先处理。 在这种情况下,绿色的注释 跨越两个基底, 因此会在跨越三个基底的橙色注释 之前处理。 更改此顺序会改变空间的分配。

为了帮助识别哪个跨越注释负责 哪些额外间距, 在此图中, 每个跨越 注释中的文本颜色 与它添加到其他盒中的间距背景颜色相匹配。

3.1.2. 块轴上的行间布局

需要定义 vertical-align 对这些 ruby 盒的影响范围。 参见 Issue 4987

然后调整每个基底 容器的尺寸和位置, 使其恰好包含其所有ruby 基底的外边距盒—以及与其关联的所有字符间ruby 注释外边距盒(如果 有)—以及同样参与此行内格式化上下文的任何后代 ruby 容器基底注释 容器。 (如果一个基底容器没有流内内容, 则调整其尺寸和位置, 就好像它包含一个空的ruby 基底一样。)

调整每个行间注释 容器的尺寸和位置, 使其恰好包含其所有ruby 注释的外边距盒, 以及同样参与此注释层级行内格式化上下文的任何后代 ruby 容器基底注释容器。 (如果一个注释容器没有流内内容, 则调整其尺寸和位置, 就好像它包含一个空的ruby 注释一样。) 然后将这些注释容器向外堆叠 在其对应的基底容器上方或下方(取决于 ruby-position), 中间不留任何间隔, 从而确定ruby 注释相对于其ruby 基底在块轴上的位置。

块轴上的 margin 是否应折叠? 这样可增强布局健壮性, 但与行内轴的 inline 行为不一致。

3.2. 字间 ruby 布局

字符间注释具有特殊的 布局。字符间ruby 注释 盒会被插入基底层级的布局中,并作为其一部分进行测量。 每个ruby 注释都会插入到与其配对的ruby 基底的右侧; 跨越字符间注释放置在 其所跨越的所有基底中最右侧基底的后面。字符间ruby 注释的布局方式 与行内块完全相同, 下文所述情况除外。

注: 根据 inter-character 的定义,字符间注释始终具有 vertical-rl writing-mode, 并且仅存在于水平ruby 容器中。

每个ruby 注释都会紧接在相关ruby 基底的右侧放置, 位于任何基底间空白(或分段间 空白)之前。 如果多个字符间ruby 注释盒放置在同一个ruby 基底旁, 则它们的外边距盒按照递增的层级 顺序向右堆叠,中间不留空隙。

如果ruby 注释盒内容区域自动高度小于其后放置的ruby 基底内容盒高度, 则其内容盒高度会增加到与该高度完全一致。

ruby 注释盒的对齐方式取决于ruby 注释上的 ruby-align 属性:

字符间注释的ruby 注释容器盒 的尺寸和位置会被设置为使其内容盒与ruby 基底容器盒的内容盒完全重合。

注: 字符间ruby 注释 容器盒的尺寸和位置对布局没有影响。 上述定义仅用于确保以编程方式查询它们时 会产生确定性的结果。

对齐和列尺寸确定而言(如 § 3 Ruby 布局中所述),字符间ruby 注释不被视为 与其所附着的基底属于同一个; 相反,它们实际上会形成自己的一个

3.3. ruby盒样式

ruby 基底ruby 容器视为行内盒, 所有适用于行内盒的属性(除非另有说明)同样适用于它们。 但行内相对偏移值vertical-aligntopbottom) 必须忽略(视为0)。

所有适用于行内盒的属性(除非另有说明), 同样适用于ruby 注释, 但line-height不适用。 同时,行内相对偏移值vertical-aligntopbottom) 也需忽略(视为0)。

marginpaddingborder属性 以及所有不适用于行内盒的属性, 均不适用于基底容器注释容器。 此外,line-height 不适用于 注释容器

UA 不要求支持 任何 background 属性或 outline 属性, 也不要求在 ruby 基底容器盒ruby 注释容器盒上支持任何显示盒边界的属性。 UA 可仅将这些盒作为继承和布局内容控制的抽象实现。

3.4. 跨行断开

若一行无法容纳整个ruby 容器, 则只要所有层级同时允许断开处,ruby 可在该处断开。 (关于断行的详细内容,参见 CSS Text 3 § 5 断行和词边界。) ruby 通常在基底-注释对之间断开, 但若断行规则允许,也可在ruby 基底内部(及其关联的 ruby 注释盒)断开。

每当 ruby 跨行断开时,ruby 注释必须和它们各自的ruby 基底保持在一起。 不能ruby 基底与其注释之间断开, 即使是 字间注释 也如此。

图示“注音”ruby的断行机会

字间 ruby 的断行机会

断行后, 每个片段会独立布局ruby 对齐在每个片段内分别进行。

3.4.1. 基底间断开

通常情况下,ruby 基底盒ruby 注释盒都会避免内部换行且不包含强制断点。 (见附录A。) 这时ruby 容器只能在相邻ruby 基底间断开, 且只有当没有ruby 注释跨越这些基底时才可断开。

复杂ruby的断行机会示意图

ruby 的断行机会

是否能在两个相邻的ruby 基底间断开由基底文本的常规断行规则控制, 就像ruby 基底是相邻的行内盒一样。 (确定 基底层 软断点时会忽略注释。)

例如,若相邻两个 ruby 基底是“蝴”和“蝶”, 行可在它们之间断开, 因为汉字间通常允许断行。 但若word-breakkeep-all,则此断行被禁止。
<ruby><rt></rt><rt>dié</rt>

基底间空白对判断ruby 基底间的断行机会很重要。 如同行内空白, 断行时会被折叠, 规则见CSS Text 3 § 4.1 空白处理规则。 注释间空白在断行时也会被裁剪。

例如,以下标记:
<ruby><rb>one</rb> <rb>two</rb> <rt>1</rt> <rt>2</rt></ruby>

由于存在空格,行可在“one”和“two”之间断开。 若断行于此,空格(及“1”和“2”之间的空格)会消失,符合 CSS 标准空白处理规则。

3.4.2. 基底内断开

对于较长的基底文本,有时可以允许在基底-注释对内断行。 例如,用日文翻译为注解的英文句子, 允许文本换行能让段落获得合理的断行效果。

需要插入实际扫描样例,避免让人以为这只是规范作者的胡思乱想。

仅当 ruby 基底及其所有并行注释white-space 属性 都允许换行, 并且每个基底/注释盒的内容内部(即不在开头或 结尾) 都存在软换行机会时,才允许在ruby 基底内换行。 由于ruby 基底注释内部的内容片段之间不存在结构上的对应关系, 用户代理可以在任意一组机会处换行; 但建议用户代理尝试按比例平衡 每个片段内的内容量。

字间注释内部不允许断行。

3.5. 双向重排

当单个段落中混合了方向相反的文字字符时, Unicode 双向算法会对按逻辑顺序存储的文本进行重排序,以便进行视觉呈现。

为了保持ruby 注释与其各自ruby 基底之间的对应关系, 必须施加一些限制:

为此,

与其他行内级内容一样, 内部 ruby 盒的双向重排序发生在换行之后, 以便内容按照其逻辑顺序分布到各行中。

注: 对这些规则稍作调整可能会很有用, 这样当某个注释容器上的 ruby-mergemerge 时, 不会对各个注释强制实施双向隔离, 从而使它们能够一起处理。 但是,这会增加实现的复杂性, 在没有处理这种情况的需求时,这似乎并不合理。 任何需要处理这种情况的人 都可以联系 CSS 工作组。

有关 CSS 中双向文本的更深入讨论,请参见 [CSS3-WRITING-MODES]

3.6. 行间距

line-height 属性控制 CSS 中的行间距。 当一行中的行内内容高度小于 line-height 时, 会在内容上下各添加一半行距(half-leading), 具体见 CSS Inline Layout 3 § 5 逻辑高度与行间距

为了确保行距一致, 含 ruby 的文档通常会确保 line-height 足够大, 能容纳行间 ruby。 因此,通常 ruby 注释容器ruby 注释盒不会影响该行行内内容的高度测量; 对齐(见 vertical-align)和行高计算 仅以 ruby 基底容器为准, 就像它是普通行内元素一样。

但如果 line-height 设置在 ruby 容器上且小于 最上方 ruby 注释容器顶部到最下方 ruby 注释容器底部的距离, 就会在 ruby 基底容器 上适当一侧添加额外的行距, 这样如果一个块包含三行内容且每行 ruby 都一样, 则各 ruby 容器不会重叠。

注: 这并不能确保ruby 注释保持在 行盒内。 它仅确保如果所有行都具有相等的间距,并且具有等量且位置等效的 ruby 注释, 就会有足够的空间来避免重叠。

作者应确保 line-heightpadding 足够容纳 ruby, 并在块级开头、结尾以及某行包含高度大于段落默认字号的行内内容(如图片、inline-block、或用 vertical-align 上移的元素)时特别注意。

每行内容位于其 line-height 中部;上下额外空间为 half-leading。如果 ruby 小于两倍 half-leading,则能容纳于行间,但它会占据上一行 half-leading 空间。

Ruby 注释常常溢出行盒; 作者应确保 ruby 注释行上下内容有足够空间留给 ruby。

注: 更细粒度的 ruby 对齐和行布局控制将在 CSS Line Layout Module Level 3 实现。 目前尚处于探索阶段, 新特性说明尚不可靠。

4. Ruby 格式属性

下列属性用于控制 ruby 的定位文本分布对齐

4.1. Ruby 定位:ruby-position 属性

名称: ruby-position
值: [ alternate || [ over | under ] ] | inter-character
初始值: alternate
适用元素: ruby 注释容器
可继承:
百分比: n/a
计算值: 指定关键字
规范顺序: 依语法
动画类型: 离散

该属性控制 ruby 注释相对于基底的位置。 各值含义如下:

alternate
不同层级的 注释在 overunder 之间交替。

如果注释容器是其 ruby 分段中的第一个注释层级, 或者之前的所有层级都是字符间注释, 那么单独指定或与 over 组合指定的 alternate 的行为与 over 相同, 而与 under 组合指定的 alternate 的行为与 under 相同。

否则, 如果前一个行间注释层级为 over,则 alternate 的行为与 under 相同, 反之亦然。 (在这种情况下,无论alternate 是单独指定, 还是与 overunder 组合指定,都没有区别。)

over
ruby 注释出现在基底的行上方
水平模式下 ruby 字形布局示意图,ruby 注释出现在基底上方

水平布局中位于日文基底文本上方的 Ruby

垂直模式下 ruby 字形布局示意图,ruby 注释垂直出现在基底右侧

垂直布局中位于日文基底文本右侧的 Ruby

under
ruby 注释出现在基底的行下方。 这是东亚表意文字书写系统中一种相对少见的设置, 最容易在教育类文本中见到。
水平模式下 ruby 字形布局示意图,ruby 注释出现在基底下方

水平布局中位于日文基底文本下方的 Ruby

垂直模式下 ruby 字形布局示意图,ruby 注释垂直出现在基底左侧

垂直布局中位于日文基底文本左侧的 Ruby

inter-character
如果包含它的ruby 容器书写模式垂直, 则此值具有与 over 相同的效果。

否则,ruby 注释会成为字符间注释。 在水平文本中,注释出现在基底右侧。 这会强制此ruby 注释容器ruby 注释子元素的 writing-mode 计算值为 vertical-rl

注: ruby 注释容器本身的 writing-mode 计算值不受影响。 这是为了避免同一元素上的 writing-modedisplayruby-position 属性的计算值之间出现循环依赖。

此值是为繁体中文的特殊情况而提供的, 尤其是在台湾使用的形式: 在这种情况下,ruby(由注音符号字形组成) 会沿着基底字形的右侧垂直显示, 即使基底字符采用水平布局也是如此:

台湾样式 ruby 示例

水平布局中的繁体中文“注音符号”ruby (为清晰起见,ruby 注释以蓝色显示)

注:由于继承是在元素树上进行的,而不考虑为 ruby 布局创建的匿名盒, 因此在使用字符间注释时,作者 需要注意避免涉及以下内容的标记模式: 基于元素的ruby 注释容器、 匿名ruby 注释 以及更深层的后代元素, 因为这些后代会从ruby 注释容器继承其书写模式, 而不是从其 writing-mode 已被更改为 vertical-rlruby 注释继承。
ruby { ruby-position: inter-character; }
<ruby>base<rtc><em>problematic</em> annotation</ruby>

在上述标记中,会创建一个匿名ruby 注释盒作为 <rtc> 元素的子元素, 以包裹整个“problematic annotation”。 由于它是一个 注释容器的子元素,而该容器的 ruby-positioninter-character, 因此其 writing-mode 将为 vertical-rl,这符合预期。 但是,<em> 元素直接从 <rtc> 元素继承其 writing-mode, 而该元素并未被强制设置为 vertical-rl

在此示例中,显式的ruby 注释容器元素并 非必需, 因此改用ruby 注释元素即可避免该 问题:

<ruby>base<rt><em>problematic</em> annotation</ruby>

如果确实需要显式的ruby 注释容器元素, 那么同时使用ruby 注释元素也可以 解决该问题:

<ruby>base<rtc><rt><em>problematic</em> annotation</ruby>

不是字间注释注释容器被称为行间注释

若多个ruby 注释容器具有相同的 ruby-position, 它们会自基底文本向外堆叠。

4.2. 共享注释空间:ruby-merge 属性

名称: ruby-merge
值: separate | merge | auto
初始值: separate
适用元素: 行间 ruby 注释容器
可继承:
百分比: n/a
计算值: 指定关键字
规范顺序: 依语法
动画类型: 按计算值类型

该属性控制当一个 ruby 容器盒内有多个 ruby 注释盒时, 应如何渲染: 是每对独立分隔, 还是将注释合并为一组渲染, 或根据空间自动决定分隔方式。

注: 字间注释始终分隔,该属性无效。

可能的取值:

separate
每个 ruby 注释盒均在其对应的 中渲染, 即不会与相邻基底重叠。 这种风格在 [JLREQ] 中称为“单 ruby”。
如“上手”配对注释,若注释比基底长,则额外空间分配在该基底周围,短注释则直接与基底对齐。
ruby-merge: separate 居中对齐示意
例如,下列两行渲染一致:
<p><ruby><rt></ruby><ruby><rt>じょう</ruby>
<p><ruby style="ruby-merge:separate"><rb><rb></rb>rt></rt>rt>じょう</rt>ruby>
merge
同一行内同一ruby 段内所有 ruby 注释盒 会作为行内盒拼接进其 注释容器, 并以单一匿名 ruby 注释盒跨越所有 ruby 基底盒布局。 单行时这种风格类似于 [JLREQ] 的“组 ruby”。 跨行时,ruby 注释仍与各自 ruby 基底保持配对。
合并注释会整体居中于合并基底,即使注释已超出各自基底范围。
ruby-merge: merge 居中对齐示意
若两字符同在一行,以下两行渲染一致:
<p><ruby>無常<rt>むじょう</ruby>
<p><ruby style="ruby-merge:merge"><rb></rb></rb>rt></rt>rt>じょう</rt>ruby>

但当基底跨行时,后者表现同 ruby-position: separate

auto
UA 可采用任意算法决定每个 ruby 注释盒如何与其基底盒配对渲染, 但应尽量保证所有注释能对齐各自基底时效果等同于 separate, 若部分注释宽于基底,则空间会被合适分配,避免基底间出现空隙。
有足够空间时注释对齐各自基底,否则跨基底共享空间。
ruby-merge: auto 居中对齐示意
注:此行为用于复合词, 见 “Jukugo Ruby” in “What is ruby?”[QA-RUBY]

各种实现方式见 Placement of Jukugo-ruby ([SIMPLE-RUBY])、JLREQ4.12.3(c) 熟语 ruby 的处理[JISX4051])等。

最简单实现是: 若所有 ruby 注释盒能容纳于各自基底宽度内则渲染为 separate, 否则渲染为 merge

注: 文本不会跨 ruby 注释基底(即使合并的)自动连写或形成连字, 因为有 bidi 隔离。 见 § 3.5 双向重排CSS Text 3 § 7.3 跨元素边界的字形处理

4.3. Ruby 文本分布:ruby-align 属性

名称: ruby-align
值: start | center | space-between | space-around
初始值: space-around
适用元素: ruby 基底、ruby 注释、ruby 基底容器、ruby 注释容器
可继承:
百分比: n/a
计算值: 指定关键字
规范顺序: 依语法
动画类型: 按计算值类型

该属性指定当 ruby 盒内容未完全填满各自盒子时,文本在盒内如何分布。 注意 ruby-align 分布的空白与两端对齐分布的空白无关且互不影响。

对于字间注释, 该属性也可影响盒本身的对齐(见§ 3.2 字间 Ruby 布局)。 其它情况下只影响盒内内容对齐,不影响盒本身尺寸或位置。

各值含义如下:

start
ruby 内容与盒起始边对齐。
ruby 文本短于基底时左对齐排布图示 ruby 文本长于基底时左对齐排布图示

start ruby 文本分布

“肩付きルビ”(Katatsuki ruby) 与 此 start 值类似但不完全相同。 特别是在超出基底时, 其行为可能随上下文与 start 对齐不同, 见 JLREQ。 此风格仅用于竖排,且 JLTF 认为其重要性不高, 是否值得为 katatsuki ruby 优化存疑。 若 start 另有用途可保留,否则可考虑移除。

center
ruby 内容在盒内居中。
ruby 文本短于基底时居中排布图示 ruby 文本长于基底时居中排布图示

center ruby 文本分布

space-between
ruby 内容按常规文本两端对齐方式扩展分布 (由 text-justify 定义), 但若无对齐机会则居中显示。
ruby 文本短于基底时两端分布图示 ruby 文本长于基底时两端分布图示

space-between ruby 文本分布

space-around
类似 space-between,但多一个对齐机会,空白在 ruby 内容前后各分一半。
ruby 文本短于基底时自动分布图示 ruby 文本长于基底时自动分布图示

space-around ruby 文本分布

默认 UA 样式表text-justify: ruby 应用于 ruby 注释, 定义每对相邻 CJK 字符之间有对齐机会,而拉丁或注音符号 字符之间则无。 因此 space-aroundspace-between 在拉丁或注音符号 ruby 上也会居中分布:
半角 ruby 文本短于基底时自动分布图示 半角 ruby 文本长于基底时自动分布图示

非CJK ruby 文本在 space-aroundspace-between 下居中分布

可用 text-justify 控制空白分布。[CSS-TEXT-3]

ruby 基底ruby 注释中的内容, 除了由于 ruby-merge: merge 而跨越的内容之外, 会根据该盒上的 ruby-align 值在其盒内对齐。 合并 注释中的内容会根据注释容器上的 ruby-align 值,在ruby 注释容器内对齐, 并忽略各个ruby 注释上的 ruby-align 值。

如果合并注释导致ruby 段变宽,会怎样? 是否如当前规范让每个基底也等比变宽(如跨越注释),这导致多基底容器不能居中对齐合并注释。 或许应允许 ruby-merge 也应用于基底容器,但这又要求基底跨多个注释(如基底合并但部分注释层未合并), 或要求基底合并时所有注释层也必须合并。

ruby-mergeauto 时,实际对齐方式由 UA 决定, 但所有注释能完全覆盖各自基底时,效果必须与 ruby-merge: separate 相同。

4.4. Ruby 文本装饰

文本装饰不会从基底文本继承到注释。

当文本装饰应用于 ruby 祖先时, 会横跨 ruby 基底容器的整个内容区绘制, 包括为容纳长注释而在基底内容两侧添加的额外空间。 当文本装饰直接应用于 ruby 基底时, 这些额外空间不被装饰, 类似于盒自身 padding 区不被装饰。[CSS3-TEXT-DECOR]

文本装饰也可直接应用于 ruby 基底容器和注释容器: 此时会传递到容器内所有基底或注释,并在它们之间连续绘制。

ruby 注释的位置可以调整, 以避免与基底文本的上划线(overline)和下划线(underline)冲突。 在字体大小和基线一致的基本情况下, 下划线或上划线会绘制在 基底层与该侧注释之间。

本节需补充说明 邻接基底/注释内容间装饰的绘制方式, 取决于这些盒是否与其等宽。

5. 边缘效果

5.1. 悬挂 Ruby:ruby-overhang 属性

名称: ruby-overhang
值: auto | none
初始值: auto
适用元素: ruby 注释容器
可继承:
百分比: n/a
计算值: 指定关键字
规范顺序: 依语法
动画类型: 按计算值类型

ruby-overhang 属性控制 ruby 注释是否可超出 ruby 容器与相邻文本重叠。 各值含义如下:

auto
当一个ruby 注释容器比 其对应的ruby 基底容器更长时, 该ruby 注释容器可以 与相邻的盒部分重叠。

是否悬伸、悬伸多少以及在什么条件下悬伸 由用户代理确定。

none
绝不允许ruby 注释容器 延伸到该ruby 注释容器之外。

若不允许ruby 注释悬挂, ruby 容器表现如普通行内盒, 即只有自身内容渲染在边界内,相邻元素不会跨越盒边界:

ruby 盒与相邻文本的交互示意图

不允许悬挂相邻文本的简单 ruby

ruby 注释容器允许悬挂, 相邻内容可与 ruby 容器盒重叠, 允许其 ruby 注释部分覆盖上下文的行内内容。 悬挂仅在不会导致相邻内容与 ruby 容器的 注释盒或其下的 基底内容冲突时允许。

ruby 盒与相邻文本的交互示意图

允许悬挂相邻文本的简单 ruby

注: 与某个ruby 基底相关的ruby 注释是否可以悬伸到另一个ruby 基底之上,由 ruby-merge 控制。

通常,基底或注释内容的对齐不受悬挂行为影响: 对齐与空间分配(见 ruby-align) 的方式与是否允许悬挂无关,且在计算可用悬挂空间前已确定。 但 UA 可在分配空间和/或对齐时考虑允许悬挂的情况。

怀疑悬挂行为某些场景会影响对齐,需后续探讨。

UA 可采用 [JIS4051] 推荐的注释字体 0.5ic(半个全角)为最大悬挂长度。 日文 ruby 悬挂相邻字符的详细规则见 [JLREQ]

5.2. 行边对齐

当一个比其ruby 基底更长的ruby 注释盒位于一行的起始边缘或结束边缘时, 用户代理可以强制使ruby 注释中接触该行边缘的一侧 与基底的相应边缘对齐。 [JLREQ] 描述了这种对齐方式。

本级规范未提供控制此行为的机制。

行边对齐 ruby 文本短于基底时的排布图示 行边对齐 ruby 文本长于基底时的排布图示

行边对齐

附录 A:示例样式表

本节为补充说明。

A.1 默认 UA 样式表

以下为 HTML 和 XHTML ruby 标记渲染为 ruby 布局的默认 UA 样式表:

ruby { display: ruby; }
rp   { display: none; }
rbc  { display: ruby-base-container; }
rtc  { display: ruby-text-container; }
rb   { display: ruby-base; white-space: nowrap; }
rt   { display: ruby-text; }
ruby, rb, rt, rbc, rtc { unicode-bidi: isolate; }

rtc, rt {
  font-variant-east-asian: ruby;  /* 见 [[CSS-FONTS-3]] */
  text-justify: ruby;             /* 见 [[CSS-TEXT-4]] */
  text-emphasis: none;            /* 见 [[CSS-TEXT-DECOR-3]] */
  white-space: nowrap;
  line-height: 1; }

rtc, :not(rtc) > rt {
  font-size: 50%; }
rtc:lang(zh-TW), :not(rtc) > rt:lang(zh-TW),
rtc:lang(zh-Hanb), :not(rtc) > rt:lang(zh-Hanb), {
  font-size: 30%; }               /* 注音符号 */

注: 作者不应自行使用以上规则,支持 ruby 布局的 UA 应默认提供这些样式。

实现“最小字体大小”功能的 UA 应考虑对 ruby 注释适当缩小该最小值。

A.2 行内 ruby 注释

以下为 HTML 和 XHTML ruby 标记渲染为行内注释的样式表示例:

ruby, rb, rt, rbc, rtc, rp {
  display: inline; white-space: inherit;
  font: inherit; text-emphasis: inherit; }

A.3 生成括号

遗憾的是,由于选择器无法匹配文本节点, CSS 无法针对所有 HTML ruby 标记模式自动正确地 给未加括号的 ruby 注释加上括号。 (因为 HTML ruby 允许直接用文本推断 ruby 基底,而没有对应元素。)

但在严格使用 <rb><rtc> 的情况下,以下规则可为每段注释加括号:

/* 给 <rtc> 加括号 */
rtc::before { content: "("; }
rtc::after  { content: ")"; }

/* 给首个不在 <rtc> 内的 <rt> 前加括号 */
rb  + rt::before,
rtc + rt::before { content: "("; }

/* 给不在 <rtc> 内的 <rt> 后加括号 */
rb ~ rt:last-child::after,
rt + rb::before  { content: ")"; }
rt + rtc::before { content: ")("; }

若已知只用交替标记法 (<ruby>A<rt>a</rt>B<rt>b</rt>C<rt>c</rt><ruby>) 不会出现相邻 ruby 注释, 以下规则可为每个注释加括号:

/* 给每个 <rt> 加括号 */
rt::before { content: "("; }
rt::after  { content: ")"; }

6. 术语表

注音符号注音符号 (中文:ㄅㄆㄇㄈ注音符號,或 注音符号

为中文语音(尤其是普通话标准音)设计的字符和声调符号。 这些通常(但并非专用于)用于 ruby 注音。

注音符号字符(蓝色)沿着每个汉字右侧竖排出现在横排文本中。

注音符号作为中文字间注释的例子

注音符号声调符号是空格型字符, (在内存中)出现在每个注音音节的末尾。 它们通常显示在注音符号字母的右侧或上方的独立轨道中, 声调符号的位置依赖于音节中字符的数量。 但轻声符号则位于注音符号前面(与注音字母对齐),而不是在旁边。

注: 浏览器和字体子系统负责在显示文本时确保字形的正确相对对齐和定位,包括注音符号声调符号,无论这些文本出现于 ruby 注释还是普通行内内容。 这样的字形布局不是 CSS ruby 布局的功能。

注音符号字母属于 Bopomofo Unicode 脚本(当前位于 U+3100–312F 和 U+31A0–31BF 区段); 注音符号声调符号为 U+02C9 (ˉ), U+02CA (ˊ), U+02C7 (ˇ), U+02CB (ˋ), U+02EA (˪), U+02EB (˫), U+02D9 (˙)。 这些统称为 注音符号字符,用于 CSS 处理。

韩文汉字(朝鲜语:漢字
韩文书写体系的一个子集,使用自中文书写体系借用或改编的表意字符。 另见 日文汉字
平假名(日本语:平仮名
日语音节文字或该文字的字符。外形圆润、草书。 是日语书写体系的子集,与汉字和片假名共同使用。 近年来主要用于在无法或不适合用汉字时书写日语词汇,以及词尾和助词。 另见 片假名
表意文字
一种用来表示思想、词或词素的字符,与字母或音节文字的字符不同。 最著名的表意文字体系在东亚(中国、日本、韩国等)使用(有一定差异)。
假名(日本语:仮名
平假名和片假名的统称。
汉字(日语:漢字
日语中对表意文字的称呼;日语中使用的汉字。 是日语书写体系的子集,与平假名和片假名共同使用。 另见 韩文汉字
片假名(日语:片仮名
日语音节文字或该文字的字符。外形棱角分明。 是日语书写体系的子集,与汉字和平假名共同使用。 近年来主要用于书写外来词。 另见 平假名

致谢

没有以下人士的帮助,本规范无法完成:

David Baron, Robin Berjon, Susanna Bowen, Stephen Deach, Martin Dürst, Hideki Hiura(樋浦 秀樹), Masayasu Ishikawa(石川雅康), Taichi Kawabata, Chris Pratley, Xidorn Quan, Takao Suzuki(鈴木 孝雄), Frank Yung-Fong Tang, Chris Thrasher, Masafumi Yabe(家辺勝文), Boris Zbarsky, Steve Zilles。

特别感谢前任编辑: Microsoft 的 Michel Suignard 和 Marcin Sawicki, 以及 W3C 的 Richard Ishida。

变更记录

本节记录了自前一版发布以来的变更。

自 2021 年 12 月 2 日 WD 之后的变更

自 2020 年 4 月 29 日 WD 之后的变更

注: 仍有许多未解决问题,见 意见处理GitHub 跟踪的新问题

自 2014 年 8 月 5 日 WD 之后的变更

自 2013 年 9 月 19 日 WD 之后的变更

自 2011 年 6 月 30 日 WD 之后的变更

移除 ruby-span 以及对 rbspan 的提及。
HTML ruby 不使用显式跨越,而采用隐式跨越。 这无法处理某些特殊的双侧跨越情况, 但目前似乎没有这方面的需求。 (对于支持完整复杂 XHTML Ruby 的实现, 它们可以通过标记以相同的魔法方式推断跨越, 就像我们处理表格中的单元格跨越一样。 似乎没有必要在第 1 级中包含对此进行控制的功能。)
ruby-overhangruby-align: line-end 推迟到第 2 级。
这是一个有些复杂的高级功能。 提议是将此行为定义为由用户代理决定,并提供一些可接受选项的示例。
关闭请求 display: rp 的议题:使用 display: none
国际化工作组添加了一个议题, 请求为 rp 元素提供一个 display 值。 当 ruby 显示为 ruby 时,它们应当被隐藏。 但这已经可以很容易地通过 display: none 实现。
更改 ruby-position 的值,使其与 text-emphasis-position 匹配。
除了我们需要保留的 inter-character 之外, 让 ruby 位置与 text-emphasis-position 对齐更为合理, 后者可以正确处理水平/垂直偏好的各种组合。
移除 ruby-align 中未使用的值。
不需要 leftrightend
ruby-align 中的 autodistribute-letterdistribute-space 替换为 space-betweenspace-around
auto 值依赖于检查内容来确定行为; 只需使用 space-around 并配合标准的对齐规则,即可避免这种情况 (这些规则允许在 CJK 字符之间添加间距,但不允许在拉丁字符之间添加间距)。 将 distribute-letterdistribute-space 替换为 space-betweenspace-around,以便与 [CSS-FLEXBOX-1][CSS-ALIGN-3] 中的分布 关键字保持一致,并避免 与 text-justify: distribute 的定义产生任何关联。
添加 ruby-merge 属性以控制熟语渲染。
这是一种样式效果,而不是结构效果; 之前的模型假定它属于结构效果, 并建议通过更改标记来处理它。:(
ruby-position 中移除 inline
这可以通过在所有与 ruby 相关的元素上使用 display: inline 来实现, 参见 附录 A
添加了默认样式规则
应国际化工作组的要求。
编写了匿名盒生成规则
并定义了基底和注释的配对。 现在应当可以处理所有那些疯狂提出的 HTML ruby 标记排列组合。
定义了 ruby 的布局
详细定义了空间分布、空白处理、 换行、行堆叠等。 关于双向文本仍留有一个待解决的议题。

一致性

文档约定

一致性要求由描述性断言和 RFC 2119 术语共同表达。规范性部分中的关键词 “MUST”(必须)、“MUST NOT”(不得)、“REQUIRED”(要求)、“SHALL”(应)、“SHALL NOT”(不应)、“SHOULD”(建议)、“SHOULD NOT”(不建议)、“RECOMMENDED”(推荐)、“MAY”(可以)、“OPTIONAL”(可选)应按 RFC 2119 解释。 为便于阅读,本规范未对这些词全部大写。

本规范所有文本均为规范性内容,除非明确标注为非规范性、示例、或注释。[RFC2119]

本规范中的示例以“For example”开头, 或用 class="example" 单独排版,如下所示:

这是一个说明性示例。

说明性注释以“Note”开头,并用 class="note" 单独排版,如下:

注:这是一个说明性注释。

警示性内容为规范性部分,样式突出,用 <strong class="advisement"> 标记,如: UA 必须提供可访问性替代方案。

一致性类别

本规范定义了三类一致性:

样式表
一份CSS 样式表
渲染器
一个UA,解释样式表语义并渲染 使用它们的文档。
创作工具
一个UA,用于编写样式表。

只要样式表中所有使用本模块定义语法的语句都根据通用 CSS 语法和本模块各特性的语法有效,则样式表即合规。

渲染器若能按照相关规范解释样式表,并能解析本规范定义的所有特性并相应渲染文档,即为合规。 但 UA 因设备限制无法正确渲染文档不视为不合规。(例如,UA 不要求在单色显示器上渲染颜色。)

创作工具若其生成的样式表在语法上符合通用 CSS 语法和本模块各特性的语法,且符合本模块描述的样式表一致性要求,则为合规。

部分实现

为了让作者利用向前兼容的解析规则设置回退值,CSS 渲染器必须将任何其不支持的 at-rule、属性、属性值、关键字和其它语法结构视为无效(并按需忽略)。尤其是,用户代理不得有选择地忽略声明中的部分不支持值而只使用支持的值:如有任何值无效(如不支持),则整个声明都应被忽略。

不稳定和专有特性的实现

为避免与未来稳定 CSS 特性冲突,CSSWG 建议遵循最佳实践实现不稳定功能专有扩展

非实验性实现

一旦规范进入候选推荐(CR)阶段, 就可以进行非实验性实现,开发者应当在能够证明按规范正确实现 CR 级特性时发布无前缀实现。

为确保 CSS 在各实现间的互操作性,CSS 工作组要求非实验性 CSS 渲染器在发布任何 CSS 特性的无前缀实现前,向 W3C 提交实现报告(必要时还包括用于该报告的测试用例)。 提交给 W3C 的测试用例由 CSS 工作组审核和修订。

有关提交测试用例和实现报告的更多信息,请参见 CSS 工作组网站 https://www.w3.org/Style/CSS/Test/。 问题可发送至 public-css-testsuite@w3.org 邮件列表。

索引

本规范定义的术语

引用定义的术语

参考文献

规范性引用

[CSS-BOX-4]
Elika Etemad. CSS Box Model Module Level 4。2022年11月3日。WD。URL:https://www.w3.org/TR/css-box-4/
[CSS-CASCADE-5]
Elika Etemad; Miriam Suzanne; Tab Atkins Jr.。CSS Cascading and Inheritance Level 5。2022年1月13日。CR。URL:https://www.w3.org/TR/css-cascade-5/
[CSS-DISPLAY-3]
Tab Atkins Jr.; Elika Etemad。CSS Display Module Level 3。2022年11月18日。CR。URL:https://www.w3.org/TR/css-display-3/
[CSS-FONTS-5]
Myles Maxfield; Chris Lilley。CSS Fonts Module Level 5。2021年12月21日。WD。URL:https://www.w3.org/TR/css-fonts-5/
[CSS-GRID-2]
Tab Atkins Jr.; Elika Etemad; Rossen Atanassov。CSS Grid Layout Module Level 2。2020年12月18日。CR。URL:https://www.w3.org/TR/css-grid-2/
[CSS-INLINE-3]
Dave Cramer; Elika Etemad。CSS Inline Layout Module Level 3。2022年11月14日。WD。URL:https://www.w3.org/TR/css-inline-3/
[CSS-PSEUDO-4]
Daniel Glazman; Elika Etemad; Alan Stearns。CSS Pseudo-Elements Module Level 4。2022年12月30日。WD。URL:https://www.w3.org/TR/css-pseudo-4/
[CSS-SIZING-3]
Tab Atkins Jr.; Elika Etemad。CSS Box Sizing Module Level 3。2021年12月17日。WD。URL:https://www.w3.org/TR/css-sizing-3/
[CSS-SYNTAX-3]
Tab Atkins Jr.; Simon Sapin。CSS Syntax Module Level 3。2021年12月24日。CR。URL:https://www.w3.org/TR/css-syntax-3/
[CSS-TABLES-3]
François Remy; Greg Whitworth; David Baron。CSS Table Module Level 3。2019年7月27日。WD。URL:https://www.w3.org/TR/css-tables-3/
[CSS-TEXT-3]
Elika Etemad; Koji Ishii; Florian Rivoal。CSS Text Module Level 3。2022年5月5日。CR。URL:https://www.w3.org/TR/css-text-3/
[CSS-VALUES-3]
Tab Atkins Jr.; Elika Etemad。CSS Values and Units Module Level 3。2022年12月1日。CR。URL:https://www.w3.org/TR/css-values-3/
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad。CSS Values and Units Module Level 4。2022年10月19日。WD。URL:https://www.w3.org/TR/css-values-4/
[CSS-WRITING-MODES-4]
Elika Etemad; Koji Ishii。CSS Writing Modes Level 4。2019年7月30日。CR。URL:https://www.w3.org/TR/css-writing-modes-4/
[CSS2]
Bert Bos; 等。Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification。2011年6月7日。REC。URL:https://www.w3.org/TR/CSS21/
[CSS3-TEXT-DECOR]
Elika Etemad; Koji Ishii。CSS Text Decoration Module Level 3。2022年5月5日。CR。URL:https://www.w3.org/TR/css-text-decor-3/
[CSS3-WRITING-MODES]
Elika Etemad; Koji Ishii。CSS Writing Modes Level 3。2019年12月10日。REC。URL:https://www.w3.org/TR/css-writing-modes-3/
[HTML]
Anne van Kesteren; 等。HTML 标准。Living Standard。URL:https://html.spec.whatwg.org/multipage/
[RFC2119]
S. Bradner。Key words for use in RFCs to Indicate Requirement Levels。1997年3月。最佳现行实践。URL:https://datatracker.ietf.org/doc/html/rfc2119

补充性引用

[CLREQ]
Bobby Tung; 等。Requirements for Chinese Text Layout - 中文排版需求。2022年10月9日。NOTE。URL:https://www.w3.org/TR/clreq/
[CSS-ALIGN-3]
Elika Etemad; Tab Atkins Jr.。CSS Box Alignment Module Level 3。2021年12月24日。WD。URL:https://www.w3.org/TR/css-align-3/
[CSS-FLEXBOX-1]
Tab Atkins Jr.; 等。CSS Flexible Box Layout Module Level 1。2018年11月19日。CR。URL:https://www.w3.org/TR/css-flexbox-1/
[JIS4051]
Formatting rules for Japanese documents (『日本語文書の組版方法』)。 日本标准协会。2004年。JIS X 4051:2004。日文
[JISX4051]
Line composition rules for Japanese documents。 日本标准协会。1995年。JIS X 4051-1995。日文
[JLREQ]
Hiroyuki Chiba; 等。Requirements for Japanese Text Layout 日本語組版処理の要件(日本語版)。2020年8月11日。NOTE。URL:https://www.w3.org/TR/jlreq/
[QA-RUBY]
Richard Ishida。What is ruby?。 URL:https://www.w3.org/International/questions/qa-ruby
[RUBY]
Marcin Sawicki; 等。Ruby Annotation。2001年5月31日。REC。URL:https://www.w3.org/TR/ruby/
[SIMPLE-RUBY]
Florian Rivoal; Atsushi Shimono; Richard Ishida。Rules for Simple Placement of Japanese Ruby。2020年6月9日。WD。URL:https://www.w3.org/TR/simple-ruby/

属性索引

名称 初始值 适用元素 继承 %百分比 动画类型 规范顺序 计算值
ruby-align start | center | space-between | space-around space-around ruby 基底、ruby 注释、ruby 基底容器、ruby 注释容器 n/a 按计算值类型 依语法 指定关键字
ruby-merge separate | merge | auto separate 行间 ruby 注释容器 n/a 按计算值类型 依语法 指定关键字
ruby-overhang auto | none auto ruby 注释容器 n/a 按计算值类型 依语法 指定关键字
ruby-position [ alternate || [ over | under ] ] | inter-character alternate ruby 注释容器 n/a 离散 依语法 指定关键字

问题索引

本规范的目标是通过抑制 ruby 注释内部的所有换行,简化布局模型。 或者我们也可以尝试定义一些可接受的行为。
需要定义 vertical-align 对这些 ruby 盒的影响范围。 见 Issue 4987
块轴上的 margin 是否应折叠? 这样可增强布局鲁棒性, 但与行内轴的 inline 行为不一致。
需插入实际扫描样例,避免让人以为这只是规范作者的胡思乱想。
“肩付きルビ” (Katatsuki ruby) 与 start 值类似, 但并不完全相同。 特别是当注释悬挂超出基底时,其行为可能与 start 对齐不同, 具体取决于上下文, 见 JLREQ。 此外,它只用于竖排, JLTF 认为其重要性不高, 因此未必值得为 katatsuki ruby 智能化处理投入努力。 若 start 有其他用途可以保留, 否则也许应移除?
如果合并注释导致 ruby 段变宽,会怎样? 是否如当前规范所述让每个基底也等比变宽(如跨越注释)? 这导致多基底容器内的合并注释无法居中。 或许应允许 ruby-merge 也应用于基底容器, 但这就需要允许基底跨多个注释 (如果基底合并但部分注释层未合并), 或要求基底合并时所有注释层也必须合并。
本节需补充说明 邻接基底/注释内容间装饰的绘制方式, 取决于这些盒是否与其等宽。
怀疑悬挂行为某些场景会影响对齐,需后续探讨。