The essentials

Quick reference

One focused task per row. Jump to the related section for complete, working examples.

UseSyntaxExamples
Add a ruby annotation<ruby>漢字<rt>かんじ</rt></ruby>View examples
Add legacy fallback punctuation<ruby>漢字<rp>(</rp><rt>かんじ</rt><rp>)</rp></ruby>View examples
Declare annotation language<ruby lang="ja">東京<rt>とうきょう</rt></ruby>View examples
Place ruby underneathruby { ruby-position: under; }View examples
Distribute ruby textruby { ruby-align: space-around; }View examples
Disable ruby overhangruby { ruby-overhang: none; }View examples
Enable automatic hyphenation:lang(en) { hyphens: auto; }View examples
Honor manual opportunities.product-name { hyphens: manual; }View examples
Choose the hyphen glyph:lang(en) { hyphenate-character: auto; }View examples
Constrain hyphenated fragments.prose { hyphenate-limit-chars: 6 3 2; }View examples
Wrap an unbreakable token.token { overflow-wrap: anywhere; }View examples
Use normal wrapping.prose { overflow-wrap: normal; }View examples
Break non-CJK text anywhere.machine-output { word-break: break-all; }View examples
Use strict CJK rules:lang(ja) { line-break: strict; }View examples
Loosen short-line rules.narrow:lang(ja) { line-break: loose; }View examples
Keep CJK phrases together.short-label:lang(ko) { word-break: keep-all; }View examples
Restore language defaults.article { word-break: normal; }View examples
Suggest a hyphenated breakinterna&shy;tionalizationView examples
Suggest a non-hyphen breakapi.example.com/<wbr>v2/<wbr>reportsView examples
Balance a short headingh2 { text-wrap: balance; }View examples

Line breaking is language-sensitive typography, not a generic request to split strings wherever space runs out. Start with correct Unicode text and an accurate lang attribute, use semantic ruby and rt elements for pronunciation or glosses, allow the browser's line-breaking engine to follow the writing system, and reserve emergency wrapping for genuinely unbreakable content. Automatic hyphenation and newer ruby controls depend on browser dictionaries, fonts, and evolving implementation support, so design a readable fallback and test with real content in every supported language.

Step by step

Detailed examples

01

Encode annotations as text relationships, not decoration

Use ruby for a base phrase and rt for its pronunciation or gloss. The lang attribute should identify the actual language of the base or annotation so fonts, speech, shaping, and line breaking can respond correctly. The optional rp elements provide visible punctuation only in user agents without ruby rendering. Do not duplicate the same reading in nearby visually hidden text: assistive technologies handle ruby differently, and duplication can cause repeated announcements. Test the semantic result with your supported browser and screen-reader combinations.

Mark a Japanese reading with a text fallback
<p lang="ja">
  次の駅は
  <ruby>東京<rp>(</rp><rt>とうきょう</rt><rp>)</rp></ruby>
  です。
</p>
Annotate individual bases when pairing matters
<p lang="ja">
  <ruby>漢<rt>かん</rt>字<rt>じ</rt></ruby>を学びます。
</p>
Back to quick reference ↑
02

Adjust ruby placement without breaking the fallback

The browser constructs ruby base and annotation boxes from the semantic markup. ruby-position chooses the line-over, line-under, or inter-character placement; ruby-align distributes annotation content within the available inline dimension. ruby-overhang and ruby-merge provide finer control in CSS Ruby Level 1, but support is less consistent. Keep the unstyled markup readable and treat advanced values as progressive enhancement rather than hiding annotations or recreating them with generated content.

Enhance annotation layout behind feature queries
ruby {
  font-variant-east-asian: ruby;
}

rt {
  font-size: .55em;
}

@supports (ruby-position: under) {
  ruby.gloss { ruby-position: under; }
}

@supports (ruby-overhang: none) {
  ruby.term { ruby-overhang: none; }
}
Back to quick reference ↑
03

Drive hyphenation with correct language metadata

hyphens: auto permits the user agent to use a hyphenation dictionary, but only when it knows the content language and has suitable resources. Results vary by browser, operating system, and vocabulary. Use it for prose with a constrained measure, not identifiers, person names, code, or controls. hyphenate-limit-chars and related Level 4 controls can improve fragment quality where implemented; unsupported declarations are ignored, leaving ordinary automatic hyphenation in place.

Enable language-specific prose hyphenation
<article>
  <p lang="en" class="prose">Internationalization requires representative content.</p>
  <p lang="de" class="prose">Silbentrennung folgt sprachabhängigen Wörterbüchern.</p>
</article>
Add quality limits as an optional enhancement
.prose {
  max-inline-size: 38ch;
  hyphens: auto;
  hyphenate-character: auto;
}

@supports (hyphenate-limit-chars: 6 3 2) {
  .prose { hyphenate-limit-chars: 6 3 2; }
}

code, input, button { hyphens: none; }
Back to quick reference ↑
04

Use emergency wrapping only for hostile strings

overflow-wrap: anywhere creates emergency soft wrap opportunities when a token cannot otherwise fit, and those opportunities participate in min-content sizing. It is usually the safest option for URLs, hashes, and user-generated tokens inside cards or grid tracks. word-break: break-all is much more aggressive for non-CJK text and can split ordinary words even when another line would fit, harming recognition and reading. Keep normal language-aware wrapping for prose and scope aggressive behavior to machine-oriented output.

Protect a card from long user-provided tokens
.card {
  min-inline-size: 0;
}

.card__url,
.card__identifier {
  overflow-wrap: anywhere;
}

.card__description {
  overflow-wrap: normal;
  word-break: normal;
}

.raw-hexdump { word-break: break-all; }
Back to quick reference ↑
05

Choose line-breaking rules for the writing system

line-break adjusts the strictness of East Asian punctuation and character restrictions, while word-break changes which character sequences are treated as unbreakable words. normal is the appropriate default for general multilingual prose. strict can enforce conventional Japanese restrictions; loose can help very narrow columns. keep-all suppresses common breaks inside CJK sequences, so reserve it for short labels or headings with authored opportunities rather than applying it to long Korean, Chinese, or Japanese passages.

Tailor compact labels without changing article prose
:lang(ja) {
  line-break: strict;
  word-break: normal;
}

.narrow:lang(ja) {
  line-break: loose;
}

.short-label:lang(ko) {
  word-break: keep-all;
  overflow-wrap: anywhere;
}
Back to quick reference ↑
06

Author intentional opportunities when dictionaries cannot help

A soft hyphen represents a preferred intra-word break and displays a hyphen only when used. The wbr element marks an opportunity without adding a hyphen, which is useful at semantic boundaries in URLs or long compounds. Insert either into the source text deliberately; blanket insertion can disrupt copying, searching, speech, and maintenance. Do not use zero-width characters as an invisible layout patch when semantic markup or overflow-wrap expresses the requirement more clearly.

Offer meaningful breaks in a term and path
<p lang="en" class="manual">
  interna&shy;tionalization
</p>

<p class="endpoint">
  api.example.com/<wbr>v2/<wbr>organizations/<wbr>quarterly-reports
</p>
Honor manual hyphens and retain an overflow escape hatch
.manual {
  hyphens: manual;
}

.endpoint {
  overflow-wrap: anywhere;
}

/* Copy and search the rendered result during localization QA. */
Back to quick reference ↑
07

Test readability, fallback behavior, and rendering cost

Typography controls must not obscure the source text or rely on generated content for meaning. Test at zoom, in narrow containers, with user font overrides, and with representative assistive technology. Balanced wrapping is useful for short headings but costs more than ordinary wrapping and should not be applied to long prose. Automatic hyphenation and ruby layout can change with fonts and dictionaries; include real translations in visual regression tests, and avoid fixed heights that clip extra ruby line space or reflowed text.

Keep headings flexible and annotation lines unclipped
.text-card {
  min-inline-size: 0;
  block-size: auto;
  overflow: visible;
}

h2 {
  max-inline-size: 28ch;
  text-wrap: balance;
}

p { line-height: 1.65; }

@media (prefers-contrast: more) {
  rt { color: currentColor; }
}
Back to quick reference ↑

Local code tester

Compare ruby, hyphenation, and overflow strategies

Resize the preview and edit language, width, ruby placement, and wrapping rules to observe their different responsibilities.

Runs in your browser
Preview

Sources and further reading

References

Authoritative documentation used to verify and expand this cheat sheet.

  1. World Wide Web ConsortiumCSS Ruby Annotation Layout Module Level 1w3.org
  2. World Wide Web ConsortiumCSS Text Module Level 3w3.org
  3. World Wide Web ConsortiumCSS Text Module Level 4w3.org
  4. WHATWGHTML Living Standard: Ruby annotationshtml.spec.whatwg.org
  5. Unicode ConsortiumUnicode Standard Annex #14: Unicode Line Breaking Algorithmunicode.org

Help us improve

Found a typo or missing example?

Tell us what would make this cheat sheet clearer, more complete, or more useful.

Share feedback