<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>typography &#8211; Matthew Petroff</title>
	<atom:link href="https://mpetroff.net/tag/typography/feed/" rel="self" type="application/rss+xml" />
	<link>https://mpetroff.net</link>
	<description>mpetroff.net</description>
	<lastBuildDate>Sat, 04 May 2024 16:21:13 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	
	<item>
		<title>Pre-calculated Line Breaks for HTML / CSS</title>
		<link>https://mpetroff.net/2020/05/pre-calculated-line-breaks-for-html-css/</link>
					<comments>https://mpetroff.net/2020/05/pre-calculated-line-breaks-for-html-css/#respond</comments>
		
		<dc:creator><![CDATA[Matthew Petroff]]></dc:creator>
		<pubDate>Mon, 25 May 2020 16:12:05 +0000</pubDate>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[knuth-plass]]></category>
		<category><![CDATA[line breaks]]></category>
		<category><![CDATA[typography]]></category>
		<guid isPermaLink="false">https://mpetroff.net/?p=3225</guid>

					<description><![CDATA[Although slowly improving, typography on the web pages is considerably lower quality than that of high-quality print / PDF typography, such as that produced by LaTeX or Adobe InDesign. In particular, line breaks and hyphenation need considerable improvement. While CSS &#8230; <a href="https://mpetroff.net/2020/05/pre-calculated-line-breaks-for-html-css/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
										<content:encoded><![CDATA[<p><span class="dropcap">A</span>lthough slowly improving, typography on the web pages is considerably lower quality than that of high-quality print / PDF typography, such as that produced by <span>L<sup style="text-transform: uppercase; vertical-align: -0.3em; margin-left: -0.2em;">a</sup>T<sub style="text-transform: uppercase; vertical-align: 0.2em; margin-left: -0.15em;">e</sub>X</span> or Adobe InDesign. In particular, line breaks and hyphenation need considerable improvement. While CSS originally never specified what sort of line breaking algorithm should be used, browsers all converged on greedy line breaking, which produces poor-quality typography but is fast, simple, and stable. <a href="https://www.w3.org/TR/css-text-4/#text-wrap">CSS Text Module Level 4</a> standardizes the current behavior as the default with a <code>text-wrap</code> property while introducing a <code>pretty</code> option, which instructs the browser to use a higher quality line breaking algorithm. However, as of the time of writing, no browsers supported this property.<br />
<span id="more-3225"></span></p>
<p>I recently came across a <a href="https://latex.now.sh/">CSS library</a> for emulating <span>L<sup style="text-transform: uppercase; vertical-align: -0.3em; margin-left: -0.2em;">a</sup>T<sub style="text-transform: uppercase; vertical-align: 0.2em; margin-left: -0.15em;">e</sub>X&#8217;s</span> default appearance.<sup id="rf1-3225"><a href="https://mpetroff.net/2020/05/pre-calculated-line-breaks-for-html-css/#fn1-3225" title=" Also see corresponding &lt;a href=&quot;https://news.ycombinator.com/item?id=23282207&quot;&gt;Hacker News discussion&lt;/a&gt;. " rel="footnote">1</a></sup> However, it doesn&#8217;t emulate the Knuth&#8211;Plass line breaking algorithm, which is one of the things that makes <span>L<sup style="text-transform: uppercase; vertical-align: -0.3em; margin-left: -0.2em;">a</sup>T<sub style="text-transform: uppercase; vertical-align: 0.2em; margin-left: -0.15em;">e</sub>X</span> look good. This got me wondering whether or not it&#8217;s possible to emulate this with plain HTML and CSS. A <a href="https://github.com/robertknight/tex-linebreak">JavaScript library</a> already exists to emulate this, but it adds extra complexity and is a bit slow. It turns out that it is possible to pre-calculate line breaks and hyphenation for specific column widths in a manner that can be encoded in HTML and CSS, as long as web fonts are used to standardize the text appearance across various browsers.</p>
<p>The key is to wrap all the potential line breaks (inserted via <code>::after</code> pseudo-elements) and hyphens in <code>&lt;span&gt;</code> elements that are hidden by default with <code>display: none;</code>. Media queries are then used to selectively show the line breaks specific to a given column width. Since every line has an explicit line break, justification needs to be enabled using <code>text-align-last: justify;</code>, and <code>word-spacing: -10px;</code> is used to avoid additional automatic line breaks due to slight formatting differences between browsers. However, this presents a problem for the actual last line of each paragraph, since it is now also justified instead of left aligned. This is solved by wrapping each possible last line in a <code>&lt;span&gt;</code> element. Using media queries, the <code>&lt;span&gt;</code> element corresponding to the given column width is set to use <code>display: flex;</code>, which makes the content be left-aligned and take up the minimum space required, thereby undoing the justification; <code>word-spacing: 0;</code> is also set to undo the previous change to it and fix the word spacing. Unfortunately, the nested <code>&lt;span&gt;</code> elements are problematic, because there are no spaces between them; this is fixed by including a space in the HTML markup at the beginning of the <code>&lt;span&gt;</code> and setting <code>white-space: pre;</code> to force the space to appear.</p>
<p>I&#8217;ve prepared a <a href="https://mpetroff.net/files/pre-calculated-line-breaks-demo/">demo page</a> demonstrating this technique. It was constructed by calculating line breaks in Firefox 76 using the <a href="https://github.com/robertknight/tex-linebreak">tex-linebreak bookmarklet</a> and manually inserting the markup corresponding to the line breaks; some fixes were manually made because the library does not properly support em dashes. Line breaks were calculated for column widths between 250&thinsp;px and 500&thinsp;px at 50&thinsp;px increments. The Knuth&#8211;Plass line breaks lead to a considerable improvement in the text appearance, particularly for narrower column widths. In addition to the improved line breaks, I also implemented protrusion of hyphens, periods, and commas into the right margin, a microtypography technique, which further improves the appearance. To (hopefully) avoid issues with screen readers, <code>aria-hidden="true"</code> is set on the added markup; <code>user-select: none;</code> is also set, to avoid issues with text copying.</p>
<p>While this technique works fine in Firefox and Chrome, it does not work in Safari, since Safari does not support <code>text-align-last</code> as of Safari 13.<sup id="rf2-3225"><a href="https://mpetroff.net/2020/05/pre-calculated-line-breaks-for-html-css/#fn2-3225" title=" Even Internet Explorer 6 supports this. " rel="footnote">2</a></sup> Despite it not working, the corresponding <a href="https://bugs.webkit.org/show_bug.cgi?id=76173">WebKit bug</a> is marked as &#8220;resolved fixed&#8221;; it seems that support was actually added in 2014, but the support is behind the <code>CSS3_TEXT</code> compile-time flag, which is disabled by default. Thus, I devised an <a href="https://mpetroff.net/files/pre-calculated-line-breaks-demo/demo-partial-safari-support.html">alternative method</a> that used invisible 100% width elements to force line breaks without using explicit line breaks. This again worked in Firefox and Chrome, although it caused minor issues with text selection, but it again had significant issues in Safari. It appears that Safari does not properly handle justified text with negative word spacing; relaxing the word spacing, however, causes extra line breaks due to formatting differences, which breaks the technique. At this point, I gave up on supporting Safari and just set it to use the browser default line breaking by placing the technique&#8217;s CSS behind an <code>@supports</code> query for <code>text-align-last: justify</code>.</p>
<p>Automated creation of the markup would be necessary to make this technique more generally useful, but the <a href="https://mpetroff.net/files/pre-calculated-line-breaks-demo/">demo page</a> serves as a proof of concept. Ideally, browsers would implement an improved line breaking algorithm, which would make this technique obsolete.</p>
<p>Update 2024-05: Support for <code>text-align-last</code> was added in <a href="https://developer.apple.com/documentation/safari-release-notes/safari-16-release-notes">Safari 16</a>. Chrome 117 also <a href="https://developer.chrome.com/blog/css-text-wrap-pretty">added support</a> for <code>text-wrap: pretty</code>, but its implementation only looks at the last few lines of a paragraph to avoid orphans and does not improve the typesetting of the rest of the paragraph.</p>
<hr class="footnotes"><ol class="footnotes" style="list-style-type:decimal"><li id="fn1-3225"><p > Also see corresponding <a href="https://news.ycombinator.com/item?id=23282207">Hacker News discussion</a>. &nbsp;<a href="https://mpetroff.net/2020/05/pre-calculated-line-breaks-for-html-css/#rf1-3225" class="backlink" title="Return to footnote 1.">&#8617;</a></p></li><li id="fn2-3225"><p > Even Internet Explorer 6 supports this. &nbsp;<a href="https://mpetroff.net/2020/05/pre-calculated-line-breaks-for-html-css/#rf2-3225" class="backlink" title="Return to footnote 2.">&#8617;</a></p></li></ol>]]></content:encoded>
					
					<wfw:commentRss>https://mpetroff.net/2020/05/pre-calculated-line-breaks-for-html-css/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Page Caching using Disk: Enhanced 
Content Delivery Network via Amazon Web Services: CloudFront: cdn0.mpetroff.net
Minified using Disk

Served from: mpetroff.net @ 2026-03-31 01:34:22 by W3 Total Cache
-->