CSS Ruby Annotations: Reading Aids for East Asian Typography
AI generated
{ }
@
CSS · Internationalization · Typography
Ruby Annotations in CSS
Building clean reading aids for Japanese and Chinese text

The HTML element <ruby> together with <rt> and <rp> displays small annotation text, so-called ruby annotations, directly above or beside individual characters. In Japanese and Chinese content, these annotations explain the pronunciation and meaning of whole character blocks, and for international shops with an East Asian audience they are not a niche feature but a standard requirement.

14 min read ruby · rt · rp ruby-position · ruby-align

1. What ruby text is: furigana as the best-known example

In Japanese writing, complex kanji characters are often annotated with small syllabic characters, called furigana, placed directly above the kanji to indicate its pronunciation in the simpler hiragana or katakana syllabary. These annotations especially help children, language learners, or readers facing an uncommon proper name pronounce a character correctly without looking it up in a dictionary.

The concept is not limited to Japanese: in Chinese, pinyin annotations play a similar role by showing the Latin phonetic transcription above a character. In both cases, this is ruby text, smaller supplementary text information that is typographically closely tied to the main character while remaining visually distinct from it. Knowing both conventions makes it easier to see why ruby text is treated as its own HTML concept rather than a mere CSS trick.

2. The HTML foundation: ruby, rt and rp

The <ruby> element wraps both the base character and its annotation. Inside it, <rt> (ruby text) marks the actual annotation text, which the browser automatically positions above the base character. Browsers with native ruby support need no extra CSS for this, the basic positioning already happens through HTML alone.

The optional <rp> (ruby parenthesis) element contains parenthesis characters that only become visible in browsers without ruby support. For browsers that understand <ruby>, the specification automatically hides the content of <rp>, so the parentheses serve purely as a text-based fallback without disturbing the native rendering.


<p>
  <ruby>
    東京
    <rp>(</rp><rt>とうきょう</rt><rp>)</rp>
  </ruby>
  is the capital of Japan.
</p>

<!-- Browsers without ruby support display: 東京(とうきょう) -->
<!-- Browsers with ruby support show the annotation above the character -->

3. Why this matters for international online shops

An online shop serving customers in Japan or the Chinese-speaking market encounters ruby text not only in literary content, but regularly in product names with rare or ambiguously readable kanji, in brand names whose pronunciation is not obvious, or in place names within shipping information. Without the pronunciation aid, customers cannot reliably name a product, which creates friction for voice search or customer service inquiries.

From an SEO perspective it is also worth doing, because search engines in East Asian markets can treat ruby text as an additional semantic signal, similar to how a title attribute provides extra context. Anyone maintaining international shop variants should therefore not treat ruby annotations as an exotic edge case, but as a standard part of localization for the East Asian market. A correctly implemented pronunciation aid also measurably improves the perceived care behind the localization, since customers quickly read a plain machine translation without ruby conventions as unprofessional.

4. ruby-position: annotation above, below or beside the base character

The CSS property ruby-position controls where the annotation appears relative to the base text. The default value over places the ruby text above the base character, matching the classic Japanese furigana convention. The value under instead shifts the annotation below the base character, which is common in some Chinese textbook layouts.

In vertical writing mode, common in traditional Japanese content, the annotation can additionally be positioned beside the base character, with ruby-position automatically adapting to the document's writing-mode direction. For horizontal, Western-read layouts, over remains the correct choice in the vast majority of cases.


ruby {
  ruby-position: over; /* default, furigana above the kanji */
}

.textbook-style ruby {
  ruby-position: under; /* alternative textbook convention */
}

5. Styling rt elements: size, color and ruby-align

By default, the browser renders text inside <rt> noticeably smaller than the base character, usually about half of the surrounding font size, so the annotation stays visibly supportive without competing with the main character. That size can be adjusted with normal CSS on the rt selector, along with color, font family, or opacity, when the annotation should look more subtle or more prominent.

The ruby-align property additionally controls how the annotation is aligned horizontally relative to the base character, for example centered with center or spread evenly with space-around, when the ruby text is shorter than the base character. For multi-syllable furigana above a multi-part kanji compound, correct alignment ensures each syllable visually sits above its matching part of the character.


ruby {
  ruby-align: space-around;
}

rt {
  font-size: 0.55em;
  color: #6d28d9;
  font-weight: 500;
  user-select: none; /* annotation cannot be selected separately */
}

6. Multiple characters and complex ruby constructions

A single <ruby> element can wrap several base characters with one shared annotation, which is useful for words whose pronunciation cannot be cleanly broken down onto individual kanji. For more precise mapping, where each syllable should appear exactly above its corresponding character, a separate <ruby> element per character with its own <rt> is recommended instead.

For double annotations, for example showing pronunciation and meaning translation simultaneously above the same character, the specification defines additional structures with multiple <rt> groups. These more complex patterns are less common in practice, but definitely relevant for learning materials or bilingual product catalogs that need translation and pronunciation at once.

7. Fallback via rp: robust rendering without ruby support

Because <rp> content is automatically hidden in browsers with ruby support, but appears normally in the text flow in browsers without that support, a fallback emerges that requires no CSS or JavaScript at all. A screen reader or a very old browser then simply shows the annotation in parentheses right after the base character, which looks less elegant but preserves the information completely.

This built-in redundancy makes ruby text one of the most robust internationalization typography features in the web platform stack, because even in the worst case no information is lost, only the visual presentation is less polished. A test with CSS disabled reliably shows whether the <rp> parentheses were set up correctly.

8. Accessibility and screen reader behavior

From an accessibility standpoint, it matters that ruby annotations use semantically correct HTML instead of a purely visual CSS solution, because screen readers can handle the <ruby> element and its children differently. A well-implemented screen reader reads the base character and its annotation in a sensible order, instead of reading both unstructured one after another, something that would be hard to achieve reliably with a purely visual reconstruction using position: absolute.

For international shops under legal accessibility obligations, for example under the European Accessibility Act, native ruby semantics is therefore not just a typographic question, but also a compliance argument against self-built annotation solutions relying purely on CSS positioning. A native implementation also minimizes the effort for later audits, since testing tools already recognize and correctly evaluate the semantic ruby element.

9. Practical example: product titles with a pronunciation aid

A Japanese-language product title with a rare kanji character in the brand name directly benefits from a ruby annotation that shows the correct pronunciation, without visually altering the actual product title or taking up extra layout space, since the annotation sits compactly above the character. For the rest of the international content library, the element stays unused, it is applied specifically where readability would otherwise suffer.

For the technical implementation in a shop frontend, a small utility class is worth defining that centrally handles base styling like annotation font size and alignment, so editors adding product titles only need to insert the HTML markup with <ruby>, <rt> and <rp>, without worrying about individual CSS per product.


<h1 class="product-title">
  <ruby>
    煎茶
    <rp>(</rp><rt>せんちゃ</rt><rp>)</rp>
  </ruby>
  Premium Green Tea, 100g Tin
</h1>
Feature Purpose Fallback without support Relevance for shops
<ruby><rt> Show pronunciation/meaning rt content stays visible in flow Product names, brand names
<rp> Provide parenthesis fallback Displayed as parenthesis text Screen readers, old browsers
ruby-position Control annotation position Default over applies automatically Layout fine-tuning
ruby-align Control horizontal alignment Browser default alignment Multi-syllable furigana

Mironsoft

Modern CSS, layout architecture and rendering performance

CSS that stays maintainable instead of breaking with every change?

We review existing stylesheets for specificity chaos and layout thrashing, then build a CSS architecture with cascade layers, custom properties and modern layout primitives that still makes sense after the tenth feature.

CSS Audit

Systematically uncovering specificity issues, cascade conflicts and unused selectors.

Architecture Refactoring

Introducing cascade layers, custom properties and design tokens cleanly.

Performance Tuning

Fixing layout thrashing, expensive selectors and rendering bottlenecks.

10. Summary

Ruby Annotations: The Essentials at a Glance

Core concept

Ruby text shows small annotations like furigana or pinyin directly above or below individual characters for pronunciation or meaning.

HTML structure

ruby wraps the base character and annotation, rt holds the annotation text, rp provides a parenthesis fallback without ruby support.

Shop relevance

Product names with rare kanji, ambiguous brand names and place names directly benefit from correctly set ruby annotations.

Accessibility

Native ruby semantics is read out sensibly by screen readers and is more robust than a purely visual CSS reconstruction.

11. FAQ: Ruby Annotations: The Essentials at a Glance

1What is ruby text on the web?
Ruby text refers to small annotations like furigana in Japanese or pinyin in Chinese, displayed directly above or below a character to show its pronunciation or meaning.
2Which HTML elements belong to ruby annotations?
The wrapping element ruby, the rt element for the actual annotation text, and optionally rp for a parenthesis fallback in browsers without ruby support.
3What exactly is the rp element for?
rp contains parenthesis characters that only become visible in browsers without ruby support. Browsers with support automatically hide the rp content.
4When does ruby text matter for an online shop?
Whenever product names, brand names, or place names contain rare or ambiguously readable kanji, and customers in Japan or the Chinese-speaking market need the correct pronunciation.
5What does ruby-position control?
The property defines whether the annotation appears above (over, the default) or below (under) the base character, depending on the relevant typographic convention.
6Can I adjust the font size of the annotation?
Yes, the rt element can be styled with normal CSS, for example a smaller font-size, its own color, or an adjusted font-weight.
7What does ruby-align do?
The property controls the horizontal alignment of the annotation relative to the base character, for example centered or evenly spread, when the ruby text is shorter than the base character.
8How does ruby text behave without browser support?
Without native support, the rp parenthesis content appears normally in the text flow, so the pronunciation information is preserved as parenthesis text right after the character.
9Is ruby text better for accessibility than a pure CSS solution?
Yes, because screen readers can read the native ruby element and its children in a sensible order, something that is hard to achieve reliably with a purely visual reconstruction using CSS positioning.
10Does a German-language shop without an Asian audience need ruby annotations?
No, for purely German or English content, ruby text is not relevant. It is only needed for content in languages with a corresponding annotation convention, such as Japanese or Chinese.