Prompt and scope
Design a content component for Japanese kana, Traditional Chinese Zhuyin, and Pinyin. How would you structure ruby markup, support layered annotations, handle search and copy, fall back when CSS Ruby is unavailable, and assess screen-reader risks?
The W3C published the HTML Ruby Markup Extensions Candidate Recommendation Snapshot on 4 June 2026. It revises HTML ruby structure, restores rb and rtc as conforming elements, and defines semantic units for bases, annotations, containers, and multiple annotation levels. It is not a translation component and does not settle every screen-reader speech strategy; separate semantic markup, layout, and assistive-technology behavior.
What the interviewer evaluates
The interviewer wants structured base-to-annotation pairing, a reasoned choice between interleaved and tabular markup, and CSS Ruby Layout instead of putting pronunciation into images. Cover language attributes, search and copy, rp fallback, SSR/hydration consistency, XSS safety, and the limits of screen-reader testing.
Clarifying questions before answering
- Does the content source provide base/annotation pairs, or must the component segment and generate them?
- Can one base have multiple language or annotation levels, such as Zhuyin and Pinyin together?
- If Ruby layout is unavailable, should the product show inline parentheses, hide annotations, or preserve the raw structure?
- What should search, clipboard copy, and text-to-speech each retain?
- Can users submit content, and which HTML elements, attributes, URLs, and CSP rules are allowed?
A 30-second answer framework
“I would model base ranges, annotation ranges, languages, and presentation policy, then emit semantic ruby, rb, rt, rtc, and rp. Interleaved markup handles simple pairs; explicit containers or tabular markup handle multi-character and layered annotations without relying on implicit pairing. CSS controls Ruby position and fallback styling; rp supplies visible inline content when Ruby layout is unavailable. Search and copy follow product semantics and are tested in real browsers. Screen-reader output is tested rather than promised by the specification. User content is sanitized before rendering.”
Step-by-step deep dive
1. Define the annotation data model
Each segment contains a base range, one or more annotation ranges, language tags, and presentation policy. Japanese may use kana; Traditional Chinese may use Zhuyin or Latin Pinyin. One base can have multiple rtc levels, but the default level must be explicit. Keep the model separate from rendering so segmentation rules do not spread across components.
2. Choose semantic markup
ruby is the overall container, rb a base unit, rt annotation text, rtc an annotation container, and rp fallback presentation. Simple cases may use implicit base units, but complex multi-character pairing should use explicit rb so DOM, copy behavior, and layout remain predictable.
3. Handle multi-character and layered pairing
Interleaved markup works for simple one-to-one annotations. Tabular markup lists several rb units followed by their corresponding rt units, which better represents compound words and layered readings. Group consecutive rt elements with rtc; set lang on each language layer. Do not put actual pronunciation in CSS pseudo-elements because search, copy, and assistive technology cannot reliably see it.
<ruby lang="zh-TW">
<rb>美</rb><rtc><rt>ㄇㄟˇ</rt></rtc>
<rtc lang="zh-Latn"><rt>měi</rt></rtc>
</ruby>4. Use CSS for progressive layout enhancement
HTML supplies structure; CSS Ruby Annotation Layout controls ruby-position, font size, line height, and alignment. Defaults must prevent annotations from covering bases and must allow text zoom. When Ruby layout is unavailable, rp can show parentheses or another inline cue; do not hide all annotation text with display: none.
5. Design search, copy, and extraction
The specification discusses search and copy interaction, but implementations still need real-browser tests. Define whether copy contains the base, base plus annotation, or a structured export. Search should find both base and annotation without losing words because annotations interrupt the DOM. Server indexes can store structured fields; the client should not infer pairs with a regex over rendered HTML.
6. Assess assistive technology and internationalization
Ruby can help children, non-native speakers, and people with reading difficulties, but screen readers may use different heuristics. Set accurate lang values, preserve meaningful text order, and test screen readers, keyboard navigation, zoom, and high contrast. Do not claim the specification solves text-to-speech; document known differences and fallbacks.
7. Verify security, performance, and compatibility
Sanitize user-supplied bases and annotations with an element and attribute allowlist; reject scripts, event attributes, and dangerous URLs. SSR and hydration must share the same pairing algorithm to prevent annotation flicker or text reordering. Use structured nodes and incremental rendering for long documents, cache the data model rather than unsafe HTML, and test with WPT and a browser matrix.
High-quality sample answer
I would model base ranges, annotation levels, languages, and presentation policy before emitting semantic ruby markup. Simple pairs can use interleaved structure; multi-character and layered annotations use explicit rb and rtc, with lang on each language layer. CSS Ruby Layout controls position, size, and line height, while rp provides inline fallback when Ruby layout is unavailable. Copy defaults to the base text, search indexes both base and annotation, and exact behavior is tested in real browsers. Because assistive-technology speech is not fully unified by this specification, I would test screen readers, keyboard, zoom, and high contrast and document differences. Input is sanitized, SSR and client use one data model and pairing algorithm, and WPT plus a browser matrix verify structure, layout, search, copy, and security.
Common mistakes
- Displaying pronunciation only with CSS pseudo-elements → search and assistive technology lose text → use semantic Ruby markup.
- Hard-coding every character as an interleaved node → compound and layered readings become brittle → use structured pairing and
rtc. - Treating
rpas mandatory visible punctuation → supported browsers show duplicate content → show it only in fallback presentation. - Ignoring
lang→ speech and font selection are wrong → tag base and annotation layers accurately. - Promising identical screen-reader order → the specification does not define complete TTS behavior → test devices and document differences.
- Rendering user HTML directly → script injection is possible → sanitize elements, attributes, and URLs.
Follow-up questions and responses
When should you use rb instead of an implicit base?
Implicit bases are fine for simple single-layer annotations. Use explicit rb for compound words, tabular markup, or applications that need a stable DOM for pairing, copy, and debugging.
What if one base has kana and romanization?
Use multiple rtc layers or an explicit annotation container and set lang on each. The product must choose a default layer and switching policy; CSS should not decide semantics.
What is the fallback when Ruby layout is unavailable?
Keep the text structure and use rp for parentheses or inline separators so base and annotation remain readable. Do not hide the content or replace it with an unselectable image.
How do you define copy behavior?
Choose base, base-plus-annotation, or structured export according to product goals, then test Chromium, Firefox, Safari, and mobile. DOM order is not automatically the user’s desired string.
How do you show that annotations remain accessible?
Check language tags, focus order, zoom, keyboard operation, and screen-reader output across no-annotation, single-layer, multi-layer, and fallback modes. Publish known assistive-technology differences.