While reading the Daangn SEED documentation, I noticed a few awkward line breaks and submitted a minimal PR. A few days later I was asked for a review, and another related PR was merged. Looking through that change, I noticed the property [word-break:auto-phrase].
“Oh, does that property exist?” I opened the MDN documentation. auto-phrase was marked experimental, and the Chrome note in the compatibility table said it only applied when lang="ja" and had no effect in other locales. The page also explains that auto-phrase behaves like word-break: normal, except that language-specific analysis improves wrapping by avoiding breaks in the middle of natural phrases. Korean uses ko, so it should receive no effect and fall back to word-break: normal. The result should therefore have remained unchanged.
But when I opened the actual document, the line break had been fixed. With normal, the first line split the Korean word for “engineers” after its first syllable. With auto-phrase, it broke cleanly before the whole word. You said only Japanese was supported! Why did Korean wrap differently?
I decided to find the actual Chrome release. (This might also be a perfect chance to contribute to MDN, hehe.) I started with Chrome 119, the version named by MDN. Chrome introduced auto-phrase there as a feature for wrapping Japanese text at natural phrase boundaries.
That page also says, “Currently, Chrome supports this feature only for Japanese, using the BudouX C++ port that uses AdaBoost ML technology,” and, “We plan to support Korean and Chinese in future versions of Chrome.” So it still says only Japanese... but Korean clearly works in practice!!! I went to read the code.
Chromium calculates line breaks with ICU (International Components for Unicode). In the code that creates a LineBreakIterator, ICU explicitly says that lw=phrase is supported only for Japanese and Korean.
Meanwhile, the code that selects the actual analysis engine says phrase breaking supports Japanese and Korean, but the ML engine supports only Japanese. My first thought was: perhaps they describe Korean as unsupported because its ML engine is unsupported.
But consider the languages themselves. Korean has spaces, and those spaces effectively identify word-group boundaries. Japanese and Chinese do not normally use spaces at all, so finding those boundaries may require a separate ML engine. Chrome uses BudouX for this purpose; it divides Japanese into units called bunsetsu. They may not be linguistically identical, but they seem to play a very similar practical role. (As someone approaching a thousand days of Japanese on Duolingo, the resulting divisions feel similar to me.)
Japanese needs an ML engine to recover natural boundaries from an unspaced sentence—almost like reverse engineering. Korean does not need one in the first place, because its spaces already provide natural boundaries. BudouX itself has a section titled Korean support?, which essentially says that Korean can usually use keep-all.
That led me to conclude that Korean is, in practice, already supported by auto-phrase. I opened an issue and a PR on MDN. It would be a shame if people avoided the property because MDN said it only supported Japanese when Korean effectively works too... But then, how exactly does it differ from keep-all?
keep-all always breaks only between word groups. auto-phrase starts at those boundaries, but if overflow remains, it falls back to normal and recalculates the line. In other words, it behaves like keep-all while retaining the ability to split a word that is simply too long. The effect is close to combining keep-all with overflow-wrap: anywhere.
One difference is that auto-phrase removes the normal opportunities for hyphenation and effectively behaves like hyphens: none. A long English word that wraps would usually be connected with a hyphen, but that hyphen is not added.
My conclusion is this: if a product handles Korean (and Japanese) together with English, might this be the most practical setup?
.title {
word-break: normal;
overflow-wrap: anywhere;
text-wrap: balance;
}
.title:lang(ko),
.title:lang(ja) {
word-break: auto-phrase;
}
.title:lang(en) {
hyphens: auto;
}
Use overflow-wrap: anywhere to defend against extremely long strings and URLs, and text-wrap: balance to place lines well. Let Korean and Japanese wrap at phrase boundaries with word-break: auto-phrase, while English adds hyphens when a long word must wrap.
A few more reasons anywhere helps: dictionary words behave well when hyphenation is available, but unknown words can still overflow. It also prevents flex or grid layouts from breaking without adding min-w-0 separately to every text element.
When I first saw auto-phrase, I thought it meant semantic line breaking. Korean already has keep-all to wrap at word groups, so I assumed auto-phrase would only be meaningful if it added semantic grouping on top. Something roughly like this:
- To build a good product, improve each
- small inconvenience one by one
+ To build a good product,
+ improve each small inconvenience one by one
So I decided to build it myself with BudouX. The result proved useful, at least within some limits, and I went ahead and published it as npm packages. Here they are: GitHub and npm. In the next article, I will share how I built it. Hahaha.