⏱️ Reading time: 15 min
Furifont embeds furigana directly in the font itself: there’s no need for the <ruby> tag or a single line of CSS for the kana reading to appear above the correct kanji.
📑 En este artículo
- TL;DR
- What Is Furifont?
- Why Furigana Embedded in Glyphs Matters
- How Furigana in the Font Works
- Practical Examples and How to Get Started
- Real Use Cases
- Common Mistakes and Best Practices
- Comparison with Alternatives
- Going Deeper: Inside the GSUB Table
- Frequently Asked Questions
- Does Furifont replace the HTML ruby element?
- What happens if the browser doesn’t support the OpenType features Furifont uses?
- Can you copy the text and keep the kana reading?
- Does Furifont work with any Japanese typeface?
- Does embedded furigana annotation work for languages other than Japanese?
- How much does the font file grow when embedding furigana in the glyphs?
- References
The project, published by developer Anthony Fu at furifont.antfu.me, uses OpenType contextual substitutions and stylistic sets (the same features that combine letters into a ligature or change the style of a number) to solve a typographic problem that until now depended on external markup.
TL;DR
- Furifont draws the furigana inside the kanji glyph using OpenType contextual substitutions, with no ruby markup or CSS.
- GSUB, the glyph substitution table, picks the correct reading based on the neighboring kanji without a single line of JavaScript.
- Manually choosing the reading is possible with stylistic sets when a kanji allows multiple pronunciations.
- Without support for those OpenType features, the browser shows the kanji alone, without breaking the rest of the layout.
- The same technique works for pinyin, Arabic transliteration, or any annotation that today depends on extra HTML.
What Is Furifont?
Furifont is an experimental OpenType font that embeds furigana in the font through glyph substitutions: each kanji with its reading is replaced by a composite glyph that already includes the miniature kana characters, with no additional markup in the document.
Furigana itself isn’t new: Japanese dictionaries and children’s books have used it for more than a century to annotate the pronunciation of a complex kanji above or beside the main character. The internet solved the problem with HTML’s <ruby> element, standardized by the W3C, but that markup depends on every platform (an EPUB reader, a PDF generator, a plain text editor) implementing it correctly.
Furifont tackles the problem from a different angle, asking the font to do the work instead of relying on a new tag. Any application that already knows how to render text with OpenType, which is practically all modern software, displays the furigana with no code changes at all.
For someone just starting to read Japanese, furigana serves the same function as a small pronunciation sign next to a difficult word: it doesn’t replace learning the kanji, but it lets you read the full text from day one without stopping every three words to look something up in a dictionary.
Why Furigana Embedded in Glyphs Matters
<ruby> support on the web is consistent, but outside the browser it’s uneven. PDF generators, slide engines, and several EPUB readers still don’t position furigana correctly, or simply ignore it. For educational material that needs to look the same in an app, a printed PDF, and a web page, each renderer that fails is a different headache.
By moving the annotation into the font, Furifont removes that problem from the equation. If the software knows how to display Japanese text with a modern OpenType typeface, something that covers almost all current software, it already knows how to display the furigana. There’s no need to patch the EPUB reader or the PDF generator.
The inconsistency isn’t theoretical. Some EPUB readers position furigana too close to the previous line when the text has a lot of consecutive kanji, and certain PDF generators built on older layout engines don’t even recognize the ruby markup properly, showing the reading as loose text out of place.
The project’s value isn’t just in solving furigana. Fu presents it as a demonstration of a broader font engineering technique: any secondary annotation that today depends on markup (pinyin over a Chinese character, vocalization over an Arabic consonant, a phonetic transcription over a word) can be pushed down into the font layer using the same OpenType tools.
How Furigana in the Font Works
Everything happens at the shaping stage, the step where a text engine converts a Unicode string into a sequence of positioned glyphs. A browser, an editor, or an operating system doesn’t draw letters, it draws the glyphs the font tells it to, following the rules the font itself carries in its internal tables.
The Shaping Pipeline: From Text to Composite Glyph
Shaping engines like HarfBuzz (used by Chrome, Firefox, and most of Linux) or CoreText on macOS take the kanji string and look it up in the font’s GSUB (Glyph Substitution) table. That table defines rules: if such a sequence of characters appears in such a context, substitute the simple glyph for another one. Furifont defines, for each kanji it supports, a rule that points to a composite glyph, and that new glyph isn’t just the kanji’s strokes: it also includes the kana characters of the reading drawn in miniature, already positioned and scaled within the same outline.
flowchart TD
A["Text: kanji and context"] --> B["Shaping engine (HarfBuzz)"]
B --> C["GSUB table: calt lookup"]
C --> D["Contextual rule exists"]
D -->|"Yes"| E["Substitutes with composite glyph"]
D -->|"No"| F["Shows kanji without furigana"]
E --> G["Glyph with miniature kana"]
Contextual Substitutions (GSUB) to Pick the Right Reading
The calt (contextual alternates) feature is the key piece: it decides which glyph to show based on neighboring characters, not just the isolated character. This matters because the same kanji can be read different ways depending on the word it forms. A well-written calt rule looks at the following or preceding kanji and picks the composite glyph with the correct reading for that specific context.
Stylistic Sets for the Exceptions
Context isn’t always enough to disambiguate. When a kanji allows several valid readings in the same context, something common in Japanese proper names, Furifont falls back on stylistic sets, the family of features from ss01 to ss20 that the OpenType standard reserves so a designer or the user themselves can manually choose between alternate glyphs. Instead of the font guessing, the document activates a specific stylistic set to force the correct reading for that particular kanji.
How the Composite Glyph Is Built
Designing each composite glyph is typography work, not programming. In a tool like FontForge or Glyphs, the designer takes the kanji’s outline, adds the outlines of the kana characters shrunk to a fraction of the size, and positions them in the glyph’s upper space, adjusting the horizontal advance so the set doesn’t collide with the neighboring glyph. That new glyph is saved under its own name inside the font’s glyph table (glyf in TrueType or CFF in OpenType-CFF fonts), and the GSUB table simply states that, when the original glyph for that kanji appears in that context, this other glyph should be used instead. Tools like fonttools, the Python library that reads and writes font binaries, can automate much of that mapping by generating GSUB rules from a list of kanji-reading pairs instead of writing them by hand one by one.
Practical Examples and How to Get Started
Testing the embedded furigana annotation doesn’t require compiling anything: just load the font via @font-face and turn on the right OpenType features from CSS.
Turning on Features via CSS
@font-face {
font-family: "Furifont";
src: url("Furifont.ttf") format("truetype");
}
.furigana {
font-family: "Furifont", sans-serif;
font-feature-settings: "calt" 1;
}
This block loads the font and turns on calt, the feature that triggers the contextual substitutions. With this, a <span class="furigana"> containing a kanji supported by Furifont should already show the miniature reading above it, with no other change to the HTML.
.furigana-manual {
font-family: "Furifont", sans-serif;
font-feature-settings: "calt" 1, "ss03" 1;
}
Here ss03 is added to force a specific stylistic set, useful when the kanji has an ambiguous reading that context alone can’t resolve, for example a proper name. The variant number depends on how Furifont mapped each alternate reading in its own GSUB table.
Checking That the Substitution Is Active
Firefox ships a font inspector inside the developer tools, in the Fonts tab of the Inspector panel, which lists for the selected text which OpenType features the font carries and which are active. If calt shows as checked and the kanji on screen displays the furigana, the substitution is working. If the kanji shows alone, without the reading above it, the first thing to check is whether font-feature-settings actually reached the element and wasn’t overridden by another rule with higher specificity.
flowchart LR
A["Furifont loaded"] --> B["Renderer supports contextual GSUB"]
B -->|"Yes"| C["Shows kanji with embedded furigana"]
B -->|"No"| D["Shows only the base kanji"]
C --> E["Copied text keeps only the kanji"]
D --> E
Real Use Cases
- E-books:
<ruby>support varies between EPUB readers, so embedding furigana in the font prevents the reading from disappearing on a device that ignores the markup. - Japanese learning material: apps and practice sheets that only need to type the kanji and let the font show the reading.
- Documents and PDFs generated by systems that don’t control HTML: reports, invoices, or forms where adding
<ruby>isn’t an option. - Subtitling and digital signage: screens that render plain text without a ruby engine, where forcing a specific stylistic set is simpler than integrating a new markup parser.
- General font engineering: the same contextual substitution idea works for embedding pinyin over Chinese characters or vocalization over Arabic consonants.
Common Mistakes and Best Practices
- Copying and pasting loses the reading: the underlying text is still just the kanji, the furigana is purely visual.
- Glyph explosion: every kanji-reading combination needs its own composite glyph, so a complete font can’t cover every possible reading.
- Older rendering engines: if the software doesn’t implement contextual GSUB or ignores
caltby default, the kanji shows alone. - Line height: the composite glyph takes up more vertical space than a normal kanji, so the line height needs to be adjusted by hand so the furigana doesn’t get cut off.
💭 Key takeaway: Furifont solves furigana’s presentation, not its accessibility: for a screen reader or a search engine, the text is still just the kanji.
Comparison with Alternatives
The table below compares furigana in the font with the most common alternatives for annotating readings in Japanese text, on the web and off it.
| Option | When to use it | Advantage | Limitation |
|---|---|---|---|
| <ruby>/<rt> HTML | Web pages where you control the markup | Standard, accessible, the real text includes the reading | Requires marking up every word by hand and renderer support |
| Generated CSS (content/attr) | When you can’t touch the HTML but can touch the CSS | Doesn’t duplicate the kanji in the DOM | Not accessible for screen readers and not copyable |
| Furifont (furigana in the font) | Documents, PDFs, or apps with no control over the rendering engine | Zero extra markup, works on any plain text | The font file grows and copied text loses the reading |
| Prerendered image or SVG | Signage or fixed printed materials | Total visual control | Not real text: can’t be searched, copied, or reflowed |
Going Deeper: Inside the GSUB Table
The OpenType specification defines several lookup types within GSUB, numbered 1 through 8. A simple ligature, like combining two letters into a single glyph, uses lookup type 4. What Furifont does is closer to type 6, chained contextual substitution, which allows looking at glyphs before and after the target before deciding on the replacement. That’s the machinery calt exposes to the font designer without the document’s author having to write a single rule.
The cost of this approach is combinatorial. Every kanji-plus-reading combination the font wants to support needs its own composite glyph, drawn by hand or generated by a script, with the miniature kana already positioned within the outline. A kanji with five common readings means five distinct glyphs in the font, not one. This puts a practical ceiling on how many combinations a single font can cover before the file grows too large, so projects like this one tend to focus on a limited vocabulary rather than covering the thousands of commonly used kanji with all their readings.
A technical alternative the font could also exploit is GPOS, the glyph positioning table that uses the same mechanism as combining accents and diacritics in scripts like Arabic or Hebrew. Instead of replacing the kanji with a composite glyph, the font could attach the kana characters as anchored marks over the base kanji, reusing the same kanji glyph in other contexts. That path reduces glyph explosion, but complicates fine control over the exact size and position of each kana, which is exactly what a composite glyph solves in one shot.
Shaping happens only once per text run and the layout engine caches the result, so there’s no runtime performance cost beyond what any text with ligatures or kerning already pays. The real limitation is different: the underlying text, what ends up on the clipboard, what a search engine indexes, what a screen reader reads, is still just the kanji. The furigana lives in the visual layer, not in the data, something HTML’s <ruby> element does solve because the reading is real text within the document.
The idea of resolving typographic annotations inside the font, instead of in the document, isn’t exclusive to Furifont. Asian typography systems have spent decades wrestling with the question of where reading information lives, and HTML’s own ruby arrived late: it only became widely interoperable across browsers well into the 2010s. What Furifont contributes is a complete, end-to-end demonstration of the technique for building a typeface with embedded phonetic reading using only standard OpenType features that any font can adopt without waiting on a change in any browser.
Your next step: download the test font from furifont.antfu.me, build a span with font-feature-settings: "calt" 1; and confirm in Firefox’s font inspector that the contextual substitution fired.
Frequently Asked Questions
Does Furifont replace the HTML ruby element?
It doesn’t replace it in every case: <ruby> is still the right choice when you need the reading to exist as real, accessible, searchable text. Furifont makes sense when the output channel doesn’t let you control the markup, like an automatically generated PDF or an EPUB reader that ignores <ruby>. For new content where you control the whole pipeline, <ruby> remains the more robust choice long term.
What happens if the browser doesn’t support the OpenType features Furifont uses?
If the shaping engine doesn’t apply calt or the stylistic sets, it simply shows the kanji’s base glyph, without the furigana. It doesn’t break the layout or produce a missing character, but the reader loses the annotation.
Can you copy the text and keep the kana reading?
No. The substitution happens only in the glyph’s visual layer: the underlying Unicode text is still the original kanji, so copying and pasting, searching the page, or running it through a screen reader doesn’t recover the kana reading.
Does Furifont work with any Japanese typeface?
No: the furigana annotation has to be designed inside that specific font, glyph by glyph. It isn’t a feature you can add to any existing Japanese typeface without redesigning its GSUB tables and adding the corresponding composite glyphs. Migrating an existing typeface means, in practice, generating a derived font just for this purpose.
Does embedded furigana annotation work for languages other than Japanese?
The technique does: any script that combines a main character with a secondary phonetic annotation, like pinyin over Chinese characters or vocalization over Arabic or Hebrew consonants, can use the same mechanism of OpenType contextual substitutions and stylistic sets.
How much does the font file grow when embedding furigana in the glyphs?
It grows in direct proportion to how many kanji-reading combinations it supports: every new combination is an additional composite glyph in the glyph table. That’s why no font of this kind tries to cover the thousands of commonly used kanji with all their possible readings.
References
- Furifont: official site for Anthony Fu’s project, with the demo of furigana embedded in the font.
- Wikipedia: history and use of furigana in Japanese typography.
- Microsoft Typography: official OpenType specification, including the GSUB table and its layout features.
- MDN: documentation for the CSS
font-feature-settingsproperty for enabling OpenType features. - Wikipedia: technical background on the OpenType font format.
📱 Enjoy this content? Follow @programacion on Telegram for daily tech content in Spanish: quick summaries, fresh content every day. @programacion
Featured image: Foto de Liana S en Unsplash
Did it work for you? Got a different error? Say so below: questions get answered and help the next reader.
Leave a comment
0 Comments