8000 csswg-drafts/css-ruby-1/Overview.bs at ae90d79de46c9775810eee7053a2a2cb7fcc9d7e · SebastianZ/csswg-drafts · GitHub
Skip to content

Latest commit

 

History

History
2266 lines (1922 loc) · 100 KB

Overview.bs

File metadata and controls

2266 lines (1922 loc) · 100 KB
<pre class='metadata'>
Title: CSS Ruby Annotation Layout Module Level 1
Shortname: css-ruby
Level: 1
Status: ED
Work Status: Exploring
Group: csswg
ED: https://drafts.csswg.org/css-ruby-1/
TR: https://www.w3.org/TR/css-ruby-1/
Test Suite: https://www.w3.org/International/tests/repo/results/css-ruby
Previous Version: https://www.w3.org/TR/2014/WD-css-ruby-1-20140805/
Previous Version: https://www.w3.org/TR/2013/WD-css3-ruby-20130919/
Editor: Elika J. Etemad / fantasai, Invited Expert, http://fantasai.inkedblade.net/contact, w3cid 35400
Editor: Koji Ishii, Google, kojiishi@gmail.com, w3cid 45369
Editor: Xidorn Quan, Mozilla https://www.mozilla.org/, https://www.upsuper.org/, w3cid 73936
Editor: Florian Rivoal, Invited Expert, https://florian.rivoal.net/, w3cid 43241
Abstract: “Ruby”, a form of interlinear annotation, are short runs of text alongside the base text.
Abstract: They are typically used in East Asian documents to indicate pronunciation or to provide a short annotation.
Abstract: This module describes the rendering model and formatting controls related to displaying ruby annotations in CSS.
</pre>
<pre class=link-defaults>
spec:css-text-3; type:dfn; text:character
spec:css-box-4; type:dfn; text:content area
</pre>
<!--
Issues:
box layout/sizing
clean up inter-character vs. parallel layout requirements
Redo all examples with consistent font. (M+ 2p?)
-->
<h2 id="intro">
Introduction</h2>
<h3 id="ruby-def">
What is ruby?</h3>
<em>This subsection is not normative.</em>
<dfn export>Ruby</dfn> is the commonly-used name for a run of text
that appears alongside another run of text (referred to as the “base”)
and serves as an annotation or a pronunciation guide associated with that run of text.
<figure>
<img src="images/ruby-context.png"
alt="Hiragana ruby annotations above each kanji in Japanese text">
<figcaption>A run of Japanese text with phonetic ruby annotations indicating the pronunciation of each ideograph.</figcaption>
</figure>
The following figures show two examples of Ruby,
a simple case and one with more complicated structure.
<div class="example">
In this example, a single annotation is used to annotate a base text
consisting of multiple characters.
<div class="figure">
<img src="images/licence.png"
alt="Example of ruby applied on top of a Japanese expression">
<p class="caption">Example of ruby used in Japanese (simple case)
</div>
In Japanese typography, this case is sometimes called
taigo ruby (Japanese: <span lang="ja">対語ルビ</span>, i.e. per-word ruby) or group-ruby,
because the annotation as a whole is associated
with multi-character word (as a whole).
</div>
<div class="example">
In this second example,
two levels of annotations are attached to the base text:
the hiragana characters on top refer to the pronunciation of each of the base kanji characters,
while the words “Keio” and “University” on the bottom are give the English translation.
<div class="figure">
<img src="images/ruby-univ.gif"
alt="Example showing complex ruby with annotation text over and under the base characters">
<p class="caption">Complex ruby with annotation text over and under the base characters
</div>
Notice that to reflect the correct association
of hiragana characters and their corresponding Kanji base characters,
the spacing within the base-level text is adjusted.
(This happens around the fourth Kanji character in the figure above,
which has a three-character phonetic gloss.)
To avoid variable spacing of the base text in the example above,
the hiragana annotations can be styled as a [=merged annotation=],
which will look more like the group-ruby example earlier.
However because the base-annotation [=pairings=] are recorded in the ruby structure,
if the text breaks across lines, the annotation characters will stay
correctly paired with their respective base characters.
</div>
In HTML, ruby structure and markup to represent it is described
in the Ruby Markup Extension specification.
This module describes the CSS rendering model
and formatting controls relevant to ruby layout of such markup.
A more in-depth introduction to [=Ruby=] and its formatting
can be found in the “What is Ruby“ article [[QA-RUBY]].
Extensive information about the main ways [=ruby=] has traditionally been formatted in Japanese
can be found in JIS X-4051 [[JIS4051]] (in Japanese)
and in <a href="https://www.w3.org/TR/jlreq/#ruby_and_emphasis_dots">“Ruby and Emphasis Dots”</a> in <cite>Requirements for Japanese Text Layout</cite> [[JLREQ]] (in English and Japanese);
<cite>Rules for Simple Placement of Japanese Ruby</cite> [[SIMPLE-RUBY]]
also describes (in English) one possible approach for Japanese ruby formatting.
<a href="https://www.w3.org/TR/clreq/#interlinear_annotations">“Interlinear annotations”</a> in <cite>Requirements for Chinese Text Layout</cite> [[CLREQ]]
describes the related practices for Chinese typography (in Chinese and English).
<h3 id="placement">
Module interactions</h3>
This module extends the inline box model of CSS Level 2 [[!CSS2]]
to support ruby.
None of the properties in this module apply to the ''::first-line'' or
''::first-letter'' pseudo-elements;
however 'ruby-position' can inherit through ''::first-line'' to affect
ruby annotations on the first line.
ISSUE: Issues are being tracked both
<a href="https://github.com/w3c/csswg-drafts/issues">in GitHub</a>
as well as in this
<a href="http://drafts.csswg.org/css-ruby-1/issues-wd-2014">Disposition of Comments</a>
tracking issues raised on <a href="http://lists.w3.org/Archives/Public/www-style/">www-style</a>.
<h3 id="values">
Value Definitions</h3>
This specification follows the <a href="https://www.w3.org/TR/CSS2/about.html#property-defs">CSS property definition conventions</a> from [[!CSS2]]
using the <a href="https://www.w3.org/TR/css-values-3/#value-defs">value definition syntax</a> from [[!CSS-VALUES-3]].
Value types not defined in this specification are defined in CSS Values &amp; Units [[!CSS-VALUES-3]].
Combination with other CSS modules may expand the definitions of these value types.
In addition to the property-specific values listed in their definitions,
all properties defined in this specification
also accept the [=CSS-wide keywords=] keywords as their property value.
For readability they have not been repeated explicitly.
<h3 id="diagram-conventions">
Diagram conventions</h3>
<em>This subsection is not normative.</em>
Many typographical conventions in East Asian typography depend
on whether the character rendered is wide (CJK) or narrow (non-CJK).
There are a number of illustrations in this document
for which the following legend is used:
<dl>
<dt><img alt="Symbolic wide-cell glyph representation" width="39" height="39" src="images/fullwidth.gif">
<dd>
Wide-cell glyph (e.g. Han) that is the <var>n</var>th character in the text run.
They are typically sized to 50% when used as annotations.
<dt><img alt="Symbolic narrow-cell glyph representation" width="19" height="39" src="images/halfwidth.gif">
<dd>Narrow-cell glyph (e.g. Roman) which is the <var>n</var>th glyph in the text run.
</dl>
The orientation which the above symbols assume in the diagrams
corresponds to the orientation that the glyphs they represent
are intended to assume when rendered by the user agent.
Spacing between these characters in the diagrams is incidental,
unless intentionally changed to make a point.
<h2 id="ruby-model">
Ruby Box Model</h2>
The CSS ruby model is based on
the <a href="https://www.w3.org/TR/html5/text-level-semantics.html#the-ruby-element">W3C HTML5 Ruby Markup</a> model
and the <a href="https://www.w3.org/TR/ruby/">XHTML Ruby Annotation Recommendation</a> [[RUBY]].
In this model, a ruby structure consists of
one or more [=ruby base=] elements representing the base (annotated) text,
associated with one or more levels of [=ruby annotation=] elements representing the annotations.
The structure of ruby is similar to that of a table:
there are “rows” (the [=base text level=], each [=annotation level=])
and “[=columns=]” (each [=ruby base=] and its corresponding [=ruby annotations=]).
<figure>
<img src="images/ruby-boxes-simple.png"
alt="Ruby structure arranged as a table,
the first “column” containing 上 in a base box with じょう centered below in an annotation box
and the second “column” containing 手 in a separate base box with ず centered below in another annotation box.">
<figcaption>The Japanese compound word “上手” annotated with its pronunciation “じょうず”. Each syllable is associated individually with its base character.</figcaption>
</figure>
Sets of consecutive bases and their consecutive annotations are grouped together into [=ruby segments=].
Within a [=ruby segment=], a [=ruby annotation=] may span multiple [=ruby bases=].
<figure>
<img src="images/ruby-boxes-complex.png"
alt="Ruby structure arranged as a table,
the first “column” containing 旧 in a base box with jiù centered above in an annotation box,
the second “column” containing 金 in a base box with jīn centered above in an annotation box,
the third “column” containing 山 in a base box with .shān centerered above it in an annotation box,
and the name San Francisco centered below the entire phrase in an annotation box that spans all three “columns”.">
<figcaption>The Chinese city name “旧金山” annotated with its pronunciation in Pinyin “jiùjīnshān” and its English name “San Francisco”. Each Pinyin syllable is associated individually with its base character, however the English name is associated with the name as a whole.</figcaption>
</figure>
Note: In HTML, a single <code>&lt;ruby&gt;</code> element may contain multiple [=ruby segments=].
(In the XHTML Ruby model, a single <code>&lt;ruby&gt;</code> element can only contain one [=ruby segment=].)
<h3 id="ruby-display">
Ruby-specific 'display' Values</h3>
For document languages (such as XML applications) that do not have pre-defined ruby elements,
authors must map document language elements to ruby elements;
this is done with the 'display' property.
<pre class=propdef partial>
Name: display
New values: ruby | ruby-base | ruby-text | ruby-base-container | ruby-text-container
</pre>
The following new 'display' values assign ruby layout roles to an arbitrary element:
<dl dfn-type=value export dfn-for=display>
<dt><dfn>ruby</dfn>
<dd>
Specifies that an element generates a <dfn dfn for lt="ruby container | ruby container box">ruby container box</dfn>.
(Corresponds to HTML/XHTML <code>&lt;ruby&gt;</code> elements.)
<dt><dfn>ruby-base</dfn>
<dd>
Specifies that an element generates a <dfn dfn for lt="ruby base box | ruby base | base | base box">ruby base box</dfn>.
(Corresponds to HTML/XHTML <code>&lt;rb&gt;</code> elements.)
<dt><dfn>ruby-text</dfn>
<dd>
Specifies that an element generates a <dfn dfn for lt="ruby annotation box | ruby annotation | annotation | annotation box">ruby annotation box</dfn>.
(Corresponds to HTML/XHTML <code>&lt;rt&gt;</code> elements.)
<dt><dfn>ruby-base-container</dfn>
<dd>
Specifies that an element generates a <dfn dfn for lt="ruby base container box | ruby base container" local-lt="base container">ruby base container box</dfn>.
(Corresponds to XHTML <code>&lt;rbc&gt;</code> elements; generated as an anonymous box in HTML.)
<dt><dfn>ruby-text-container</dfn>
<dd>
Specifies that an element generates a <dfn dfn for lt="ruby annotation container box | ruby annotation container" local-lt="annotation container">ruby annotation container box</dfn>.
(Corresponds to HTML/XHTML <code>&lt;rtc&gt;</code> elements.)
</dl>
<p class="advisement">Authors using a language (such as HTML)
that supports dedicated ruby markup
should use that markup rather than
styling arbitrary elements (like <code>&lt;span&gt;</code>)
with ruby 'display' values.
Using the correct markup ensures that screen readers
and non-CSS renderers can interpret the ruby structures.
<h4 id="formatting-context">
The Ruby Formatting Context</h4>
[=Ruby containers=] are non-atomic [=inline-level=] boxes.
Like regular [=inline boxes=] (see [[css-inline-3#model]]),
they break across lines,
and their [=containing block=] is the nearest [=block container=] ancestor.
And just as the contents of an [=inline box=]
participate in the same [=inline formatting context=] that contains the [=inline box=] itself,
a [=ruby container=] and its base-level contents
participate in the same [=inline formatting context=] that contains the [=ruby container=] itself.
However [=ruby containers=] also establish a <dfn export>ruby formatting context</dfn>
that builds further structure around their segment of the [=inline formatting context=]
in order to host their annotations.
<span class=note>Note: this [=formatting context=] is <em>not</em> an [=independent formatting context=].</span>
[=Ruby bases=], [=ruby annotations=], [=ruby base containers=], and [=ruby annotation containers=]
are <dfn export lt="internal ruby boxes|internal ruby display types">internal ruby boxes</dfn>:
like [=internal table elements=],
they have specific roles in ruby layout,
and participate in their [=ruby container=]’s [=ruby formatting context=].
In addition to their role in the [=ruby formatting context=],
[=ruby bases=] simultaneously participate
in the same base-level [=inline formatting context=] as the [=ruby container=],
while [=ruby annotations=] participate
in separate annotation-level [=inline formatting contexts=]
established by the [=ruby container=].
As with the contents of [=inline boxes=],
the [=containing block=] for the contents of a [=ruby container=] (and all its [=internal ruby boxes=])
is the [=containing block=] of the [=ruby container=].
So floats, for example, are trapped by the [=ruby container=]’s [=containing block=],
not any of the ruby box types.
<h4 id="block-ruby">
Non-Inline Ruby</h4>
If an element has an [=inner display type=] of ''ruby''
and an [=outer display type=] other than ''display/inline'',
then it generates two boxes:
a principal box of the required [=outer display type=] type,
and an inline-level [=ruby container=].
All properties specified on the element apply to the principal box
(and if inheritable, inherit to the [=ruby container box=]).
This allows styling the element as a block,
while correctly maintaining the internal ruby structure.
Note: Absolute positioning or floating an element causes its 'display' value
to compute to a block-level equivalent. (See [[!CSS-DISPLAY-3]] or [[!CSS2]] section 9.7.)
For the [=internal ruby display types=],
this causes their 'display' value to compute to ''display/block''.
<h3 id="box-fixup">
Anonymous Ruby Box Generation</h3>
The CSS model does not require that the document language
include elements that correspond to each of these components.
Missing parts of the structure are implied through the anonymous box generation rules
<a href="https://www.w3.org/TR/CSS2/tables.html#anonymous-boxes">similar to those used to normalize tables</a>. [[!CSS2]]
<ol>
<li id="anon-gen-inlinize"><strong>[=Inlinify=] block-level boxes:</strong>
Any in-flow boxes directly contained by a
[=ruby container=],
[=ruby base container=],
[=ruby annotation container=],
[=ruby base box=],
or [=ruby annotation box=]
are “[=inlinified=]” per [[!CSS-DISPLAY-3]]),
and their 'display' value computed accordingly,
so that they contain only inline-level content.
For example,
the 'display' property of an in-flow element with ''display: block''
parented by an element with ''display: ruby-text''
computes to ''inline-block''.
<li id="anon-gen-anon-ruby"><strong>Generate anonymous ruby containers:</strong>
Any <a href="https://www.w3.org/TR/CSS2/tables.html#anonymous-boxes">consecutive</a> sequence of
improperly-contained
[=ruby base containers=],
[=ruby annotation containers=],
[=ruby bases=],
and/or
[=ruby annotations=]
(and any intervening [=white space=])
is wrapped in an anonymous [=ruby container=].
For the purpose of this step:
<ul>
<li>an improperly-contained [=ruby base=] is one not parented by a [=ruby base container=] or [=ruby container=]
<li>an improperly-contained [=ruby annotation=] is one not parented by a [=ruby annotation container=] or [=ruby container=]
<li>
an improperly-contained [=ruby base container=] or [=ruby annotation container=]
is one not parented by a [=ruby container=]
</ul>
<li id="anon-gen-bare-inlines"><strong>Wrap misparented inline-level content:</strong>
Any consecutive sequence of text and inline-level boxes
directly parented by a [=ruby container=] or [=ruby base container=]
is wrapped in an anonymous [=ruby base=].
Similarly, any consecutive sequence of text and inline-level boxes
directly parented by a [=ruby annotation container=]
is wrapped in an anonymous [=ruby annotation=].
(For this purpose, misparented [=internal table elements=]
are treated as [=inline-level content=]
since, being parented by ruby boxes,
they will be ultimately wrapped by an [=inline-level=] [=table wrapper box=].)
However, if an anonymous box so constructed contains only [=white space=],
it is considered <dfn>intra-ruby white space</dfn>
and is either discarded
or preserved
as described below.
<li id="anony-gen-trim-space"><strong>Trim leading/trailing white space:</strong>
Any [=intra-ruby white space=]
that is not the sole [=in-flow=] child of its parent
and is the first or last [=in-flow=] child of
a [=ruby container=], [=ruby annotation container=], or [=ruby base container=]
is removed, as if it had ''display: none''
<li id="anon-gen-discard-space"><strong>Remove inter-level white space:</strong>
Any [=intra-ruby white space=]
whose immediately adjacent [=in-flow=] siblings match one of the patterns below
is <dfn noexport>inter-level white space</dfn>
and is removed, as if it had ''display: none''.
<table class="data">
<thead>
<tr><th>Previous box
<th>Next box
<tbody>
<tr><td>any
<td>[=ruby annotation container=]
<tr><td>not [=ruby annotation=]
<td>[=ruby annotation=]
<!--
<tr><td>[=ruby base=] or [=ruby base container=]
<td>[=ruby annotation=] or [=ruby annotation container=]
<tr><td>[=ruby annotation container=]
<td>[=ruby annotation container=]
<tr><td>[=ruby annotation=]
<td>[=ruby annotation container=]
<tr><td>[=ruby annotation container=]
<td>[=ruby annotation=]
-->
</table>
<li id="anon-gen-interpret-space"><strong>Interpret intra-level white space:</strong>
Any [=intra-ruby white space=] box
whose immediately adjacent [=in-flow=] siblings match one of the patterns below
is assigned the box type and subtype defined in the table below:
<table class="data">
<colgroup span=2></colgroup>
<colgroup span=2></colgroup>
<thead>
<tr><th>Previous box
<th>Next box
<th>Box type
<th>Subtype
<tbody>
<tr><td>[=ruby base=]
<td>[=ruby base=]
<td>[=ruby base=]
<td><dfn>inter-base white space</dfn>
<tr><td>[=ruby annotation=]
<td>[=ruby annotation=]
<td>[=ruby annotation=]
<td><dfn>inter-annotation white space</dfn>
<tr><td>[=ruby annotation=] or [=ruby annotation container=]
<td>[=ruby base=] or [=ruby base container=]
<td rowspan=3>[=ruby base=]
<td rowspan=3><dfn>inter-segment white space</dfn>
<tr><td>[=ruby base=] or [=ruby base container=]
<td>[=ruby base container=]
<tr><td>[=ruby base container=]
<td>[=ruby base=] or [=ruby base container=]
</table>
The <dfn>intra-level white space</dfn> boxes defined above
are treated specially for [=pairing=] and layout.
See below.
<li id="anon-gen-unbreak"><strong>Suppress line breaks:</strong>
Convert all forced line breaks inside [=ruby annotations=] (regardless of 'white-space' value)
as defined for collapsible segment breaks in <a href="https://www.w3.org/TR/css-text-3/#line-break-transform">CSS Text Level 3 &sect; 4.1.2</a>.
Issue: The goal of this is to simplify the layout model by suppressing any line breaks within ruby annotations.
Alternatively we could try to define some kind of acceptable behavior for them.
<li id="anon-gen-anon-containers"><strong>Generate anonymous level containers:</strong>
Any consecutive sequence of [=ruby bases=] and [=inter-base white space=]
(and not [=inter-segment white space=])
not parented by a [=ruby base container=]
is wrapped in an anonymous [=ruby base container=].
Similarly, any consecutive sequence of [=ruby annotations=] and [=inter-annotation white space=]
not parented by a [=ruby annotation container=]
is wrapped in an anonymous [=ruby annotation container=].
</ol>
Once all ruby layout structures are properly parented,
the UA can start to associate bases with their annotations.
Note: The UA is not required to create any of these anonymous boxes
(or the anonymous empty [=intra-level white space=] boxes in [[#ruby-pairing]])
in its internal structures,
as long as [=pairing=] and layout behaves as if they existed.
<div class="example">
The following markup diagram representing the various boxes
shows where [=intra-ruby white space=] is preserved or discarded:
<xmp highlight=html style="white-space: normal; overflow-wrap: break-word">
<ruby>×<rbc>×<rb></rb>⬕<rb></rb>×</rbc>☒<rtc>×<rt></rt>⬔<rt></rt>×</rtc>◼<rbc>×<rb></rb>…</rtc>×</ruby>
</xmp>
where
* × represents [[#anony-gen-trim-space|discarded leading/trailing white space]]
* ☒ represents [[#anon-gen-discard-space|discarded inter-level white space]]
* ⬕ represents [=inter-base white space=]
* ⬔ represents [=inter-annotation white space=]
* ◼ represents [=inter-segment white space=]
</div>
<h3 id="ruby-pairing">
Annotation Pairing</h3>
Annotation <dfn>pairing</dfn> is the process of associating
[=ruby annotations=] with [=ruby bases=].
Each [=ruby annotation=] is associated with one or more [=ruby bases=],
and is said to <dfn>span</dfn> those bases.
(A [=ruby annotation=] that [=spans=] multiple bases is called
a <dfn>spanning annotation</dfn>.)
A [=ruby base=] is can be associated with
only one [=ruby annotation=] per [=annotation level=].
However, if there are multiple [=annotation levels=],
it can be associated with multiple [=ruby annotations=].
Once [=pairing=] is complete, <dfn local-lt=column>ruby columns</dfn> are defined,
each represented by a single [=ruby base=]
and one [=ruby annotation=] (possibly an empty, anonymous one)
from each [=interlinear=] [=annotation level=] in its [=ruby segment=].
<h4 id="segment-pairing">
Segment Pairing and Annotation Levels</h4>
A ruby structure is divided into <dfn>ruby segments</dfn>,
each consisting of a single [=ruby base container=]
followed by one or more [=ruby annotation containers=].
Each [=ruby annotation container=] in a [=ruby segment=]
represents one <dfn lt="annotation level | level">level</dfn> of annotation for the base text:
the first one represents the first level of annotation,
the second one represents the second level of annotation,
and so on.
The [=ruby base container=] represents the <dfn lt="base level | base text level">base level</dfn>.
The [=ruby base container=] in each segment is thus paired
with each of the [=ruby annotation containers=] in that segment.
In order to handle degenerate cases, some empty anonymous containers are assumed:
<ul>
<li>
If the first child of a [=ruby container=] is a [=ruby annotation container=],
an anonymous, empty [=ruby base container=] is assumed to exist before it.
<li>
Similarly, if the [=ruby container=] contains consecutive [=ruby base containers=],
anonymous, empty [=ruby annotation containers=] are assumed to exist between them.
</ul>
[=Inter-segment white space=] is effectively a [=ruby segment=] of its own.
<h4 id="base-annotation-pairing">
Unit Pairing and Spanning Annotations</h4>
Within a [=ruby segment=],
each [=ruby base=] in the [=ruby base container=]
is paired with one [=ruby annotation=]
from each [=ruby annotation container=] in its [=ruby segment=].
If a [=ruby annotation container=] contains only
a single, anonymous [=ruby annotation=],
then that [=ruby annotation=] is paired with (i.e. [=spans=] across)
all of the [=ruby bases=] in its [=ruby segment=].
Otherwise, each [=ruby annotation=] is paired,
in document order, with the corresponding [=ruby base=] in that segment.
If there are not enough [=ruby annotations=] in a [=ruby annotation container=],
the remaining [=ruby bases=] are paired with anonymous empty annotations
inserted at the end of the [=ruby annotation container=].
If there are not enough [=ruby bases=],
any remaining [=ruby annotations=] pair with empty, anonymous bases
inserted at the end of the [=ruby base container=].
If an implementation supports ruby markup with explicit spanning
(e.g. XHTML Complex Ruby Annotations),
it must adjust the [=pairing=] rules to pair [=spanning annotations=]
to their bases appropriately.
[=Intra-level white space=] does not participate in standard annotation [=pairing=].
However, if the immediately-adjacent [=ruby bases=] or [=ruby annotations=]
are paired
<ul>
<li>
with two [=ruby bases=] or [=ruby annotations|annotations=]
that surround corresponding [=intra-level white space=] in another level,
then the so-corresponding [=intra-level white space=] boxes are also paired.
<li>
with a single spanning [=ruby annotation=],
then the [=intra-level white space=] is also paired to that [=ruby annotation=]
<li>
with two [=ruby bases=] or [=ruby annotations|annotations=]
with no intervening [=intra-level white space=],
then the [=intra-level white space=] box pairs with
an anonymous empty [=intra-level white space=] box assumed to exist between them.
</ul>
Issue: Insert diagram
<!--
No longer needed now that the layout model is better defined,
althout we might want this (or something like this) if we want to handle
complex cases for nesting with proper alignement accross the nested parts
<h4 id="nested-pairing">
Complex Spanning with Nested Ruby</h4>
When [=ruby containers=] are <dfn lt="nested ruby">nested</dfn>,
[=pairing=] begins with the deepest [=ruby container=],
then expands out.
From the [=pairing=] perspective of the outer [=ruby container=],
each [=ruby container=] nested within another [=ruby container=]
counts as representing a single [=ruby base=]/[=annotation=] per level.
The outer [=ruby container=]’s [=ruby annotations=] paired to the [=nested ruby=]
are therefore paired with (and [=span=]) all of the nested [=ruby container=]’s [=ruby bases=].
Each [=ruby annotation container=] in the nested [=ruby container=]
occupies the same [=annotation level=] in the outer [=ruby container=]
as it does in the inner one
and participates in its layout as if it were directly contained in the outer [=ruby container=].
This process is recursive.
Thus, using nested [=ruby containers=] allows the representation
of complex spanning relationships.
Issue: It's not clear whether this falls out of layout handling of ruby containers inside ruby bases
or needs to be handled specially.
Waiting until layout is better-defined to find out...
-->
<h3 id="autohide">
Autohiding Base-identical Annotations</h3>
If a [=ruby annotation=] has the exact same text content as its base,
it is <dfn lt="hidden ruby annotation | hidden annotation">hidden</dfn>.
Hiding a [=ruby annotation=] does not affect annotation [=pairing=].
However the [=hidden annotation=] is not visible,
and it has no impact on layout
other than to separate adjacent sequences of [=ruby annotation boxes=] within its level,
as if they belonged to separate segments
and the [=hidden annotation=]’s base were not a [=ruby base=] but an intervening inline.
<div class="example">
This is to allow correct inlined display of annotations
for Japanese words that are a mix of kanji and hiragana.
For example, the word <span lang=ja>振り仮名</span> should be inlined as
<p class="figure">振り仮名(ふりがな)
and therefore marked up as
<pre highlight=html>
&lt;ruby>
&lt;rb>振&lt;/rb>&lt;rb>り&lt;/rb>&lt;rb>仮&lt;/rb>&lt;rb>名&lt;/rb>
&lt;rp>(&lt;/rp>&lt;rt>ふ&lt;/rt>&lt;rt>り&lt;/rt>&lt;rt>が&lt;/rt>&lt;rt>な&lt;/rt>&lt;rp>)&lt;/rp>
&lt;/ruby></pre>
However, when displayed as ruby, the “り” should be hidden
<div class="figure">
<img src="images/furigana-separate.png"
alt="Hiragana annotations for 振り仮名 appear, each pronunciation above its kanji base character.">
<p class="caption">Hiragana ruby for 振り仮名. Notice there is no hiragana annotation above り, since it is already in hiragana.
</div>
</div>
When the computed value of 'ruby-merge' is ''merge'',
the autohiding is disabled.
When the computed value of 'ruby-merge' is ''ruby-merge/auto'',
the user agent may decide whether to autohide or not,
but it is recommended to autohide if the algorithm the user agent chose
produces the results similar to ''separate'' would produce.
The content comparison for this auto-hiding behavior
takes place prior to white space collapsing ('white-space') and text transformation ('text-transform')
and ignores elements (considers only the <code>textContent</code> of the boxes).
Note: Future levels of CSS Ruby may add controls for auto-hiding,
but in this level it is always forced.
<h3 id="white-space">
White Space Collapsing</h3>
As discussed in [[#box-fixup]],
white space within a ruby structure is <a href="#anon-gen-discard-space">discarded</a>:
<ul>
<li>at the beginning and end of a [=ruby container=], [=annotation container=], or [=base container=],
<li>between a [=base container=] and its following [=annotation container=],
<li>between [=annotation containers=].
</ul>
<div class="example">
For example, the following markup will display without any spaces:
<pre highlight=html>
&lt;ruby>
&lt;rb>東&lt;/rb>&lt;rb>京&lt;/rb>
&lt;rt>とう&lt;/rt>&lt;rt>きょう&lt;/rt>
&lt;rtc>&lt;rt>Tō&lt;/rt>&lt;rt>kyō&lt;/rt>&lt;/rtc>
&lt;/ruby></pre>
</div>
Between [=ruby segments=], between [=ruby bases=], and between [=ruby annotations=], however,
white space is not discarded,
and is maintained for rendering
as [=inter-base white space|inter-base=],
[=inter-annotation white space|inter-annotation=],
or [=inter-segment white space=].
(See <a href="#anon-gen-interpret-space">Interpret intra-level white space</a>, above.)
<div class="example">
The rules preserving white space allow ruby to be used with space-separated scripts such as Latin.
For example,
<pre highlight=html>
&lt;ruby>
&lt;rb>W&lt;/rb>&lt;rb>W&lt;/rb>&lt;rb>W&lt;/rb>
&lt;rt>World&lt;/rt> &lt;rt>Wide&lt;/rt> &lt;rt>Web&lt;/rt>
&lt;/ruby></pre>
They also ensure that annotated white space is preserved. For example,
<pre highlight=html>
&lt;ruby>
&lt;rb>Aerith&lt;/rb>&lt;rb> &lt;/rb>&lt;rb>Gainsboro&lt;/rb>
&lt;rt>エアリス&lt;/rt>&lt;rt>・&lt;/rt>&lt;rt>ゲインズブール&lt;/rt>
&lt;/ruby></pre>
</div>
Where undiscarded white space is [=collapsible white space|collapsible=],
it will collapse across adjacent boxes in each line box
following the standard <a href="https://www.w3.org/TR/css3-text/#white-space-rules">white space processing rules</a> [[!CSS-TEXT-3]].
Annotations in separate [=ruby segments=]
or separated by [=hidden annotations=]
are not considered adjacent;
however all base-level content
(including [=inter-character annotations=],
which are treated as [=atomic inlines=])
is.
For [=collapsible white space=] between [=ruby segments=] ([=inter-segment white space=]),
the contextual text for determining [[css-text-3#line-break-transform|segment break transformations]]
is thus given by the [=ruby bases=] on either side,
not necessarily the text on either side of the white space in source document order
(which could include [=interlinear annotations=]).
<div class="note">
Note: The white space processing rules
cause a white space sequence containing a [=segment break=] (such as a line feed)
to <a href="https://www.w3.org/TR/css3-text/#line-break-transform">collapse to nothing</a> between Han and Kana characters.
This means that Chinese and Japanese ruby can safely use white space for indentation of ruby markup.
For example, the following markup will display without any spaces:
<pre highlight=html>
&lt;ruby>
屋&lt;rt>おく&lt;/rt>内&lt;rt>ない&lt;/rt>
禁&lt;rt>きん&lt;/rt>煙&lt;rt>えん&lt;/rt>
&lt;/ruby></pre>
However, white space that does not contain a [=segment break=] does not collapse completely away,
so this markup will display with a space between the first and second ruby pairs:
<pre highlight=html>
&lt;ruby>
屋&lt;rt>おく&lt;/rt> 内&lt;rt>ない&lt;/rt>
禁&lt;rt>きん&lt;/rt> 煙&lt;rt>えん&lt;/rt>
&lt;/ruby></pre>
</div>
<h2 id="ruby-layout">
Ruby Layout</h2>
When a ruby structure is laid out,
its [=base level=] is initially laid out on the line
exactly as if its [=ruby bases=] were a regular sequence of [=inline boxes=]
and the [=ruby container=] a regular [=inline box=] wrapped around it.
If a [=ruby container=] has any [=inter-character annotations=],
they are laid out into the [=base level=] as detailed in [[#inter-character-layout]].
Subsequently,
the [=base container=] is sized and
[=interlinear annotations=] are laid out
as detailed in [[#interlinear-layout]].
As in other CSS layout models,
relative positioning, transforms, and other graphical effects
apply after this layout of the boxes.
<h3 id="interlinear-layout">
Interlinear Ruby Layout</h3>
[=Interlinear=] [=ruby annotations=] within a level
are initially laid out as if they were [=inline boxes=]
participating in the same [=inline formatting context=],
effectively establishing a [=line box=]
for that [=level=] of annotation in the [=ruby container=].
[=Annotations=] and [=bases=] are aligned to each other
by adjusting their spacing as described below.
<h4 id="interlinear-inline">
Inline-axis Interlinear Layout</h4>
In the inline axis, [=interlinear=] [=ruby annotations=] are aligned
with respect to their [=ruby base boxes=]
in accordance with their [=annotation container=]’s 'ruby-merge' value.
When 'ruby-merge' is ''ruby-merge/separate'',
each [=ruby column=] is sized
to the widest content ([=ruby base=] or [=ruby annotation=]) in that [=column=].
In the case of [=spanning annotations=]
(whether actually spanning or pretending to span per ''ruby-merge: merge''),
if the content of a [=spanning annotation=] would be wider
than the [=columns=] that it spans,
then the difference is distributed equally among the spanned [=columns=].
If a [=ruby segment=] contains multiple [=spanning annotations=],
this distribution of additional space
is performed starting with the [=spanning annotations=]
that span the least number of bases,
and then in increasing number of bases spanned.
Each [=ruby base=] and [=ruby annotation=]
is then sized to exactly span its column(s).
Note: If there are multiple annotations spanning the same number of bases
that overlap but do not coincide,
the distribution of space is undefined.
Note this is not poss E870 ible with HTML markup,
but can happen in markup languages with explicit spanning such as in [[RUBY]].
If any [=ruby annotation=] in an [=annotation container=] with ''ruby-merge: auto''
is wider than its [=ruby base|base=],
then [=ruby annotations=] in that [=annotation container=]
may extend outside of their [=column=](s).
When they do, their influence on
the measure of the [=columns=] they intersect
is up to the User Agent,
provided that the [=ruby segment=] is made wide enough to fit all its content.
[=Inter-character=] annotations are interleaved between columns:
they factor into measurement of annotations that span both adjacent columns,
but are not included in either column
and are never affected by the sizing or positioning
of [=interlinear annotations=].
Within each [=base=] and [=annotation=] box,
how the extra space is distributed
when its content is narrower than the measure of the box
is specified by its 'ruby-align' property.
<div class=example>
The following diagrams illustrate these rules,
covering typical situations
as well as a few more complex ones.
In each case,
[=base boxes=] and [=annotation boxes=] are assumed to have ''ruby-align: center'',
while <!--[=base containers=] and --> [=annotation containers=] are assumed to have ''ruby-align: space-between''.
Blue brackets (<span style=color:blue>[ ]</span>) represent [=base boxes=],
red brackets (<span style=color:red>[ ]</span>) represent [=annotation boxes=],
and gray bars (<span style=color:gray>|</span>) represent the limits of [=ruby columns=].
[=Ruby containers=], [=base containers=], and [=annotation containers=] are omitted.
<dl>
<dt id=ex-separate>Separate / non spanning:
<dd>
<pre class=highlight>
<span style=color:gray>|</span><span style=color:red>[</span> a1 <span style=color:red>]</span><span style=color:gray>|</span><span style=color:red>[</span> a2 <span style=color:red>]</span><span style=color:gray>|</span><span style=color:red>[</span>annotation-3<span style=color:red>]</span><span style=color:gray>|</span>
<span style=color:gray>|</span><span style=color:blue>[</span>base 1<span style=color:blue>]</span><span style=color:gray>|</span><span style=color:blue>[</span>base 2<span style=color:blue>]</span><span style=color:gray>|</span><span style=color:blue>[</span> base 3 <span style=color:blue>]</span><span style=color:gray>|</span>
</pre>
Boxes within each [=column=] are sized to match the widest box of that [=column=].
The value of 'ruby-align' on each [=base box=] and [=annotation box=] is used
to distribute the extra space in each box.
<dt id=ex-short-span>Spanning (short):
<dd>
<pre class=highlight>
<span style=color:gray>|</span><span style=color:red>[</span> a1 <span style=color:red>]</span><span style=color:gray>|</span><span style=color:red>[</span> short span <span style=color:red>]</span><span style=color:gray>|</span>
<span style=color:gray>|</span><span style=color:blue>[</span>base 1<span style=color:blue>]</span><span style=color:gray>|</span><span style=color:blue>[</span>base 2<span style=color:blue>]</span><span style=color:gray>|</span><span style=color:blue>[</span>base 3<span style=color:blue>]</span><span style=color:gray>|</span>
</pre>
When a [=spanning annotation=] is shorter than the spanned [=bases=],
there is no extra space to distribute to these [=bases=].
Extra space within the [=spanning annotation=]
is distributed according to 'ruby-align' on that [=annotation box=],
as for non spanning ones.
<dt id=ex-long-span>Spanning (long):
<dd>
<pre class=highlight>
<span style=color:gray>|</span><span style=color:red>[</span> a1 <span style=color:red>]</span><span style=color:gray>|</span><span style=color:red>[</span>spanning annotation<span style=color:red>]</span><span style=color:gray>|</span>
<span style=color:gray>|</span><span style=color:blue>[</span>base 1<span style=color:blue>]</span><span style=color:gray>|</span><span style=color:blue>[</span> base 2 <span style=color:blue>]</span><span style=color:gray>|</span><span style=color:blue>[</span> base 3 <span style=color:blue>]</span><span style=color:gray>|</span>
</pre>
When the [=spanning annotation=] is longer than the spanned [=base boxes=],
the extra space is distributed equally between them.
<dt id=ex-short-merge>Merged (short):
<dd>
<pre class=highlight>
<span style=color:gray>|</span><span style=color:red>[</span>merged annotation<span style=color:red>]</span><span style=color:gray>|</span>
<span style=color:gray>|</span><span style=color:blue>[</span>base 1<span style=color:blue>]</span><span style=color:gray>|</span><span style=color:blue>[</span>base 2<span style=color:blue>]</span><span style=color:gray>|</span><span style=color:blue>[</span>base 3<span style=color:blue>]</span><span style=color:gray>|</span>
</pre>
A [=merged annotation=] behaves similarly to a [=spanning=] one,
except that distribution of any extra space in it
is determined by the value of 'ruby-align' on the [=annotation container=],
not on any of its [=annotation boxes=].
<!--
<dt id=ex-long-merge>Merged (long):
<dd>
<pre>
|[This is a long merged annotation]| <- no extra space, nothing to align
|[ Base 1 ]|[ Base 2 ]|[ Base 3 ]| <- uses ruby-align on each base like for a spanner?
or maybe (see https://github.com/w3c/csswg-drafts/issues/6004)
|[Base 1 Base 2 Base 3]| <- treats the bases as merged as well?
</pre>
-->
<dt id=ex-multi-level-span>Several levels, with spanning annotation:
<dd>
<pre class=highlight>
<span style=color:gray>|</span><span style=color:red>[</span> a1 <span style=color:red>]</span><span style=color:gray>|</span><span style=color:red>[</span> annotation-2 <span style=color:red>]</span><span style=color:gray>|</span><span style=color:red>[</span> a3 <span style=color:red>]</span><span style=color:gray>|</span>
<span style=color:gray>|</span><span style=color:red>[</span>long annotation spanning all content<span style=color:red>]</span><span style=color:gray>|</span>
<span style=color:gray>|</span><span style=color:blue>[</span> base 1 <span style=color:blue>]</span><span style=color:gray>|</span><span style=color:blue>[</span> base 2 <span style=color:blue>]</span><span style=color:gray>|</span><span style=color:blue>[</span> base 3 <span style=color:blue>]</span><span style=color:gray>|</span>
</pre>
<pre class=highlight>
<span style=color:gray>|</span><span style=color:red>[</span> xx <span style=color:red>]</span><span style=color:gray>|</span><span style=color:red>[</span>annotation spanning bases<span style=color:red>]</span><span style=color:gray>|</span>
<span style=color:gray>|</span><span style=color:red>[</span> a1 <span style=color:red>]</span><span style=color:gray>|</span><span style=color:red>[</span> annotation-2 <span style=color:red>]</span><span style=color:gray>|</span><span style=color:red>[</span> a3 <span style=color:red>]</span><span style=color:gray>|</span>
<span style=color:gray>|</span><span style=color:blue>[</span>base 1<span style=color:blue>]</span><span style=color:gray>|</span><span style=color:blue>[</span> base 2 <span style=color:blue>]</span><span style=color:gray>|</span><span style=color:blue>[</span> base 3 <span style=color:blue>]</span><span style=color:gray>|</span>
</pre>
In these two examples with multiple [=levels=],
each [=column=] is sized to its longest content,
and [=spanning annotations=] that are still longer
than the sum of the [=columns=] that they span
grow them further,
adding to each equally.
<dt id=ex-multi-level-mutli-span>Several levels, with multiple spanning annotations:
<dd>
<pre class=highlight>
<span style=color:gray>|</span><span style=color:red>[</span><span style=background:orange;opacity:0.3> </span> xx <span style=background:orange;opacity:0.3> </span><span style=color:red>]</span><span style=color:gray>|</span><span style=color:red>[</span><span style=background:orange;opacity:0.3> </span><span style=color:green>annotation spanning bases</span><span style=background:orange;opacity:0.3> </span><span style=color:red>]</span><span style=color:gray>|</span>
<span style=color:gray>|</span><span style=color:red>[</span><span style=background:orange;opacity:0.3> </span> a1 <span style=background:orange;opacity:0.3> </span><span style=color:red>]</span><span style=color:gray>|</span><span style=color:red>[</span><span style=background:orange;opacity:0.3> </span><span style=background:green;opacity:0.3> </span>annotation-2<span style=background:green;opacity:0.3> </span><span style=background:orange;opacity:0.3> </span><span style=color:red>]</span><span style=color:gray>|</span><span style=color:red>[</span><span style=background:orange;opacity:0.3> </span><span style=background:green;opacity:0.3> </span> a3 <span style=background:green;opacity:0.3> </span><span style=background:orange;opacity:0.3> </span><span style=color:red>]</span><span style=color:gray>|</span>
<span style=color:gray>|</span><span style=color:red>[</span><span style=color:#ae4a00>lengthy annotation spanning base content</span><span style=color:red>]</span><span style=color:gray>|</span>
<span style=color:gray>|</span><span style=color:blue>[</span><span style=background:orange;opacity:0.3> </span>base 1<span style=background:orange;opacity:0.3> </span><span style=color:blue>]</span><span style=color:gray>|</span><span style=color:blue>[</span><span style=background:orange;opacity:0.3> </span><span style=background:green;opacity:0.3> </span> base 2 <span style=background:green;opacity:0.3> </span><span style=background:orange;opacity:0.3> </span><span style=color:blue>]</span><span style=color:gray>|</span><span style=color:blue>[</span><span style=background:orange;opacity:0.3> </span><span style=background:green;opacity:0.3> </span>base 3<span style=background:green;opacity:0.3> </span><span style=background:orange;opacity:0.3> </span><span style=color:blue>]</span><span style=color:gray>|</span>
</pre>
When there are multiple [=spanning annotations=],
those that span fewest [=bases=] are processed first.
In this case, the green one,
which spans two bases,
is processed before the orange one,
which spans three.
Changing this order would change the distribution of space.
To help identify which [=spanning annotation=] is responsible
for which extra spacing,
in this diagram
the color of the text in each [=spanning annotation=] is matched
with the background color of spacing it adds to other boxes.
</dl>
</div>
<h4 id="interlinear-block">
Block-axis Interlinear Layout</h4>
ISSUE: Define the extent to which 'vertical-align' affects these ruby boxes.
See <a href="https://github.com/w3c/csswg-drafts/issues/4987">Issue 4987</a>.
Each [=base container=] is then sized and positioned
to contain exactly all of its [=ruby bases=]’ margin boxes--
and all their associated [=inter-character=] [=ruby annotation=] margin boxes, if any--
as well as the [=base containers|base=] and [=annotation containers=]
of any descendant [=ruby containers=]
also participating in this [=inline formatting context=].
(If a [=base container=] has no [=in-flow=] content,
it is sized and positioned
as if it contained a single empty [=ruby base=].)
Each [=interlinear=] [=annotation container=] is sized and positioned
to contain exactly all of its [=ruby annotations=]’ margin boxes
as well as the [=base containers|base=] and [=annotation containers=]
of any descendant [=ruby containers=]
also participating in this [=annotation level=]’s [=inline formatting context=].
(If an [=annotation container=] has no [=in-flow=] content,
it is sized and positioned
as if it contained a single empty [=ruby annotation=].)
These [=annotation containers=] are then stacked outward
over or under (depending on 'ruby-position') their corresponding [=base container=],
without any intervening space,
thus determining the block-axis positioning of the [=ruby annotations=]
with respect to their [=ruby bases=].
Issue: Should block-axis margins collapse?
This makes layout more robust,
but is inconsistent with how inlines behave along the inline-axis.
<h3 id="inter-character-layout">
Inter-character Ruby Layout</h3>
[=Inter-character annotations=] have special layout.
[=Inter-character=] [=ruby annotation boxes=]
are spliced into and measured as part of the layout of the [=base level=].
Each [=ruby annotation=] is inserted to the right of the [=ruby base=] it is paired with;
a [=spanning=] [=inter-character annotation=] is placed after
the rightmost of all the bases that it spans.
[=Inter-character=] [=ruby annotations=] are laid out
exactly like [=inline blocks=],
except as described below.
Note: As per the definition of ''inter-character'',
[=inter-character annotations=] always have a ''vertical-rl'' 'writing-mode',
and only exist in [=horizontal writing mode|horizontal=] [=ruby containers=].
Each [=ruby annotation=] is placed immediately to the right of the relevant [=ruby base=],
before any [=inter-base white space=] (or [=inter-segment white space=]).
If multiple [=inter-character=] [=ruby annotation boxes=] are placed against the same [=ruby base=],
their [=margin boxes=] are stacked rightwards without intervening space,
in increasing [=level=] order.
If the [=automatic size|automatic height=] of the [=ruby annotation box=]’s [=content area=]
would be shorter than the height of the [=content box=]
of the [=ruby base=] after which it is placed,
its [=content box=] height is increased to match that height exactly.
The alignment of the [=ruby annotation box=]
depends on the 'ruby-align' property on the [=ruby annotation=]:
<ul>
<li>
If 'ruby-align' is ''ruby-align/start'',
the top edge of the [=ruby annotation=]'s [=content box=] is aligned
with the top edge of the [=ruby base=]'s [=content box=].
<li>
Otherwise,
the center of the [=ruby annotation=]'s [=content box=] is vertically aligned
with the center of the [=ruby base=]'s [=content box=].
</ul>
The [=ruby annotation container box=] of an [=inter-character=] annotation
is sized and placed so that its content box coincides exactly with that of the [=ruby base container box=].
Note: The size and position of [=inter-character=] [=ruby annotation container boxes=]
has no effect on layout.
The above definition is merely so that programmatically inquiring about them
produces deterministic results.