The ruby I’m talking about is not the Ruby programming language. As a native Mandarin speaker, this element is pretty relevant to me. If you have seen how East Asian glyphs are annotated with pronunciation guides, then this shouldn’t be too foreign, but just in case you have no idea what I’m talking about, here’s an image from the manga, Slamdunk.

Panel from Slamdunk
Slamdunk manga
Local kindergarten textbook
Kindergarten textbook

See those little glosses along the main text? Those are known as Ruby characters (sometimes also called rubi). These short runs of text alongside the base text are usually used in East Asian documents as pronunciation guides.

East Asian writing systems

The Japanese language writing system is relatively complex, in that there are 2 kinds of syllabary, hiragana and katakana. There is also kanji, which are adopted from Chinese Han characters. As a single kanji potentially could have a variety of readings, ruby characters help indicate how they should be read. There is also the romanised version known as romaji.

とう きょう トー キョー kyō

For Chinese, there are 2 styles of syllabary for ruby characters, the one used in mainland China (Pinyin) and the one used in Taiwan (Zhuyin).

běi jīng ㄅㄟˇ ㄐ丨ㄥ

The Korean language also adopts some Chinese Han characters, and these are known as hanja. The Korean alphabet is hangul, which is the official script of both South and North Korea. Hangul is usually used as the ruby annotation for hanja characters. There is also a romanised version known as romaja.

han guk

East Asian languages on the web

The W3C recommendation for ruby characters came about in 2001 1998 to address formatting for such writing systems on the web. The specification defines markup required to define the association between the base text and the ruby text. This also allows for styling of content marked up in this manner with CSS.

Edit: The first Ruby working draft was published 21 Dec 1998, edited by Marcin Sawicki, with contributions from Martin Dürst, Masayasu Ishikawa and Chris Wilson

The initial working draft of the CSS Ruby module also came about in 2001 and became a candidate recommendation in 2003. The standard has evolved over the years and now we have the CSS Ruby Layout Module Level 1.

You can refer to the HTML specification for ruby for all the details. I found that the Japanese version of the HTML specifications provide better examples though. Even if you don’t understand Japanese, there are images that can make things much clearer as to how each element should be used.

Browser support for <ruby>

As of time of writing, caniuse.com shows there is at least partial support for all major browsers, with Firefox fully supporting this property. No love from Opera Mini though. If you want details on how browsers support and render <ruby>, check out the W3C browser tests.

Browser support for ruby element

Using <ruby>

There are a number of ruby elements as defined in the HTML specification. The table below summarises what each of these elements do.

<ruby>
Creates the association between the base text and the ruby text. Serves as the parent container for all associated ruby elements.
<rbc>
Refers to the ruby base container element. Serves as the container for rb elements in the complex ruby markup use-case. Only one rbc element should appear in a ruby element.
<rb>
Refers to the ruby base element. Serves as the markup for base text. Multiple rb elements are allowed in an rbc element. Each rb element has a corresponding rt element.
<rtc>
Refers to the ruby text container element. Serves as the container for rt elements in the complex ruby markup use-case. A maximum of 2 rtc elements can appear in a ruby element.
<rt>
Refers to the ruby text element. Serves as the markup for ruby text. Can contain inline elements but cannot have ruby elements as children. Has rbspan attribute for use in complex ruby markup, which allows an rt element to span multiple rb elements.
<rp>
Refers to the ruby parenthesis element. Acts as a fallback option for user-agents which do not support ruby to differentiate ruby text from base text.

Basic ruby markup is supported by all major browsers except Opera Mini.

大马女子篮球队 dà mǎ nǚ zǐ lán qiú duì
<ruby>
  <rb>大马女子篮球队</rb>
  <rt>dà mǎ nǚ zǐ lán qiú duì</rt>
</ruby>

The complex ruby markup (use of the <rtc> and <rbc> elements) is only fully supported by Firefox, so if you’re using any other browser, the example should have parentheses around the ruby annotations, and the formatting may look quite bad. In Firefox, the <rp> tag tells the browser to ignore those parentheses.

() () () () (lán) (qiú) (duì) (Malaysia Women's Basketball Team)
<ruby>
  <ruby xml:lang="zh">
    <rbc>
      <rb>大</rb><rp>(</rp><rt>dà</rt><rp>)</rp>
      <rb>马</rb><rp>(</rp><rt>mǎ</rt><rp>)</rp>
      <rb>女</rb><rp>(</rp><rt>nǚ</rt><rp>)</rp>
      <rb>子</rb><rp>(</rp><rt>zǐ</rt><rp>)</rp>
      <rb>篮</rb><rp>(</rp><rt>lán</rt><rp>)</rp>
      <rb>球</rb><rp>(</rp><rt>qiú</rt><rp>)</rp>
      <rb>队</rb><rp>(</rp><rt>duì</rt><rp>)</rp>
    </rbc>
  </ruby>
  <rtc xml:lang="en" style="ruby-position: under;">
  <rp>(</rp><rt>Malaysia Women's Basketball Team</rt><rp>)</rp>
  </rtc>
</ruby>

For the benefit of people who do not have Firefox installed, here’s how the markup is supposed to be rendered.

Complex ruby markup

If you noticed the additional ruby-position style applied to the bottom ruby text, that’s because the default position of ruby text is above the base text. In this case, there are 2 lines of ruby text and they will overlap each other. Setting ruby-position: under; moves that line under the base text instead.

Styling <ruby> elements

There are 3 formatting properties we can use with ruby elements, ruby-position, ruby-merge and ruby-align.

ruby-position

The property only applies to ruby element containers, <rtc> and <rbc>, and controls the position of ruby text with respect to its base. As of time of writing, this only works on Firefox.

over
Renders the ruby text above the base for horizontal text and to the right of base for vertical text. It's the default value.
under
Renders the ruby text below the base for horizontal text and to the left of base for vertical text
inter-character
Renders the ruby text on the right of each base character for horizontal text, but this forces the ruby text to be displayed vertically. (Currently not implemented anywhere)
ruby-position: over
Over (horizontal) Over (vertical)
ruby-position: under
Under (horizontal) Under (vertical)
ruby-position: inter-character
Inter-character

ruby-merge

This property controls how ruby boxes should be rendered if there are multiple ruby containers adjacent to each other. This property is essentially not implemented in any browser simply because the only value that works is separate, which is the default value.

<ruby>無<rt>む</ruby><ruby>常<rt>じょう</ruby>
<ruby style="ruby-merge:separate"><rb>無<rb>常<rt>む<rt>じょう</ruby>

The above two code examples mean exactly the same thing. Each annotation box is in the same column as its corresponding base box, and this style is called “mono ruby”.

There is also the collapse value, which concatenates all ruby annotation boxes within the same ruby segment on the same line. This combined annotation box spans across their corresponding base boxes.

<ruby>無常<rt>むじょう</ruby>
<ruby style="ruby-merge:collapse"><rb>無<rb>常<rt>む<rt>じょう</ruby>

The above two code examples mean exactly the same thing. Each annotation box is in the same column as its corresponding base box, and this style is called “group ruby”.

The auto value cedes the rendering style to the user agent depending on the length of the annotation box with respect to the base box.

ruby-align

This property dictates the distribution of ruby boxes when their contents do not fill their respective boxes exactly. Currently, Firefox is the only browser that supports this property.

start
Aligns ruby content with the start of its box.
center
Centres ruby content within its box.
space-between
Distributes ruby content evenly within its box from edge to edge.
space-around
Distributes ruby content evenly within its box, but does not necessarily fill up space from edge to edge.

Wrapping up

Support for the <ruby> element has improved quite a lot since 2010, and although the more complex markup and styling options are limited to Firefox only, at least all browsers can display basic ruby markup now. Below is the list of relevant resources for the HTML <ruby> element if you’re interested to find out more.