文本换行:美观
Justifying Text-Wrap: Pretty

原始链接: https://matklad.github.io/2026/02/14/justifying-text-wrap-pretty.html

2025年,Safari在网页排版方面取得了显著进展,实现了`text-wrap: pretty`功能,旨在改善段落格式化——这项技术在浏览器中一直缺失,直到最近才出现。这使得网页更接近于自15世纪(古腾堡)以来使用的美观断行技术,并由克努斯和普拉斯在1981年正式化。 然而,将`text-wrap: pretty`与`text-align: justify`结合使用会暴露出一个错误:该算法旨在平衡行长,但会*超出*目标,导致应用两端对齐时单词之间的空格过大。该系统优先考虑行宽略微*低于*最大宽度,当拉伸以适应容器时会造成问题。 虽然这是一项重大进步,但也凸显了与印刷品的“离线”过程相比,动态网页布局中“在线”断行的复杂性。作者敦促WebKit开发者完善该实现,以实现真正美观的两端对齐文本。

黑客新闻 新 | 过去 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 文本换行理由:美观 (matklad.github.io) 10 分,来自 surprisetalk 1小时前 | 隐藏 | 过去 | 收藏 | 讨论 帮助 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请YC | 联系 搜索:
相关文章

原文

Something truly monumental happened in the world of software development in 2025. Safari shipped a reasonable implementation of text-wrap: pretty: https://webkit.org/blog/16547/better-typography-with-text-wrap-pretty/. We are getting closer and closer to the cutting-edge XV-century technology. Beautiful paragraphs!

Gutenberg bible Old Testament Epistle of St Jerome

We are not quite there yet, hence the present bug report.


A naive way to break text into lines to form a paragraph of a given width is greediness: add the next word to the current line if it fits, otherwise start a new line. The result is unlikely to be pretty — sometimes it makes sense to try to squeeze one more word on a line to make the lines more balanced overall. Johannes Gutenberg did this sort of thing manually, to produce a beautiful page above. In 1981, Knuth and Plass figured out a way to teach computers to do this, using dynamic programming, for line breaking in TeX.

Inexplicably, until 2025, browsers stuck with the naive greedy algorithm, subjecting generations of web users to ugly typography. To be fair, the problem in a browser is harder version than the one solved by Gutenberg, Plass, and Knuth. In print, the size of the page is fixed, so you can compute optimal line breaking once, offline. In the web context, the window width is arbitrary and even changes dynamically, so the line-breaking has to be “online”. On the other hand, XXI century browsers have a bit more compute resources than we had in 1980 or even 1450!


Making lines approximately equal in terms of number of characters is only half-way through towards a beautiful paragraph. No matter how you try, the length won’t be exactly the same, so, if you want both the left and the right edges of the page to be aligned, you also need to fudge the spaces between the words a bit. In CSS, text-wrap: pretty asks the browser to select line breaks in an intelligent way to make lines roughly equal, and text-align: justify adjusts whitespace to make them equal exactly.

Although Safari is the first browser to ship a non-joke implementation of text-wrap, the combination with text-align looks ugly, as you can see in this very blog post. To pin the ugliness down, the whitespace between the words is blown out of proportion. Here’s the same justified paragraph with and without text-wrap: pretty:

The paragraph happens to look ok with greedy line-breaking. But the “smart” algorithm decides to add an entire line to it, which requires inflating all the white space proportionally. By itself, either of

p {
    text-wrap: pretty;
    text-align: justify;
}

looks alright. It’s just the combination of the two that is broken.


This behavior is a natural consequence of implementation. My understanding is that the dynamic programming scoring function aims to get each line close to the target width, and is penalized for deviations. Crucially, the actual max width of a paragraph is fixed: while a line can be arbitrary shorter, it can’t be any longer, otherwise it’ll overflow. For this reason, the dynamic programming sets the target width to be a touch narrower than the paragraph. That way, it’s possible to both under and overshoot, leading to better balance overall. As per original article:

The browser aims to wrap each line sooner than the maximum limit of the text box. It wraps within the range, definitely after the magenta line, and definitely before the red line.

But if you subsequently justify all the way to the red line, the systematic overshoot will manifest itself as too wide inter-word space!

WebKit devs, you are awesome for shipping this feature ahead of everyone else, please fix this small wrinkle such that I can make my blog look the way I had intended all along ;-)

联系我们 contact @ memedata.com