A place to cache linked articles (think custom and personal wayback machine)
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. <!doctype html><!-- This is a valid HTML5 document. -->
  2. <!-- Screen readers, SEO, extensions and so on. -->
  3. <html lang=fr>
  4. <!-- Has to be within the first 1024 bytes, hence before the <title>
  5. See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
  6. <meta charset=utf-8>
  7. <!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
  8. <!-- The viewport meta is quite crowded and we are responsible for that.
  9. See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
  10. <meta name=viewport content="width=device-width,minimum-scale=1,initial-scale=1,shrink-to-fit=no">
  11. <!-- Required to make a valid HTML5 document. -->
  12. <title>The State of Web Type (archive) — David Larlet</title>
  13. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  14. <link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons/apple-touch-icon.png">
  15. <link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons/favicon-32x32.png">
  16. <link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons/favicon-16x16.png">
  17. <link rel="manifest" href="/manifest.json">
  18. <link rel="mask-icon" href="/static/david/icons/safari-pinned-tab.svg" color="#5bbad5">
  19. <link rel="shortcut icon" href="/static/david/icons/favicon.ico">
  20. <meta name="apple-mobile-web-app-title" content="David Larlet">
  21. <meta name="application-name" content="David Larlet">
  22. <meta name="msapplication-TileColor" content="#da532c">
  23. <meta name="msapplication-config" content="/static/david/icons/browserconfig.xml">
  24. <meta name="theme-color" content="#f0f0ea">
  25. <!-- That good ol' feed, subscribe :p. -->
  26. <link rel=alternate type="application/atom+xml" title=Feed href="/david/log/">
  27. <meta name="robots" content="noindex, nofollow">
  28. <meta content="origin-when-cross-origin" name="referrer">
  29. <!-- Canonical URL for SEO purposes -->
  30. <link rel="canonical" href="https://dev.opera.com/articles/state-of-web-type/">
  31. <style>
  32. /* http://meyerweb.com/eric/tools/css/reset/ */
  33. html, body, div, span,
  34. h1, h2, h3, h4, h5, h6, p, blockquote, pre,
  35. a, abbr, address, big, cite, code,
  36. del, dfn, em, img, ins,
  37. small, strike, strong, tt, var,
  38. dl, dt, dd, ol, ul, li,
  39. fieldset, form, label, legend,
  40. table, caption, tbody, tfoot, thead, tr, th, td,
  41. article, aside, canvas, details, embed,
  42. figure, figcaption, footer, header, hgroup,
  43. menu, nav, output, ruby, section, summary,
  44. time, mark, audio, video {
  45. margin: 0;
  46. padding: 0;
  47. border: 0;
  48. font-size: 100%;
  49. font: inherit;
  50. vertical-align: baseline;
  51. }
  52. /* HTML5 display-role reset for older browsers */
  53. article, aside, details, figcaption, figure,
  54. footer, header, hgroup, menu, nav, section { display: block; }
  55. body { line-height: 1; }
  56. blockquote, q { quotes: none; }
  57. blockquote:before, blockquote:after,
  58. q:before, q:after {
  59. content: '';
  60. content: none;
  61. }
  62. table {
  63. border-collapse: collapse;
  64. border-spacing: 0;
  65. }
  66. /* http://practicaltypography.com/equity.html */
  67. /* https://calendar.perfplanet.com/2016/no-font-face-bulletproof-syntax/ */
  68. /* https://www.filamentgroup.com/lab/js-web-fonts.html */
  69. @font-face {
  70. font-family: 'EquityTextB';
  71. src: url('/static/david/css/fonts/Equity-Text-B-Regular-webfont.woff2') format('woff2'),
  72. url('/static/david/css/fonts/Equity-Text-B-Regular-webfont.woff') format('woff');
  73. font-weight: 300;
  74. font-style: normal;
  75. font-display: swap;
  76. }
  77. @font-face {
  78. font-family: 'EquityTextB';
  79. src: url('/static/david/css/fonts/Equity-Text-B-Italic-webfont.woff2') format('woff2'),
  80. url('/static/david/css/fonts/Equity-Text-B-Italic-webfont.woff') format('woff');
  81. font-weight: 300;
  82. font-style: italic;
  83. font-display: swap;
  84. }
  85. @font-face {
  86. font-family: 'EquityTextB';
  87. src: url('/static/david/css/fonts/Equity-Text-B-Bold-webfont.woff2') format('woff2'),
  88. url('/static/david/css/fonts/Equity-Text-B-Bold-webfont.woff') format('woff');
  89. font-weight: 700;
  90. font-style: normal;
  91. font-display: swap;
  92. }
  93. @font-face {
  94. font-family: 'ConcourseT3';
  95. src: url('/static/david/css/fonts/concourse_t3_regular-webfont-20190806.woff2') format('woff2'),
  96. url('/static/david/css/fonts/concourse_t3_regular-webfont-20190806.woff') format('woff');
  97. font-weight: 300;
  98. font-style: normal;
  99. font-display: swap;
  100. }
  101. /* http://practice.typekit.com/lesson/caring-about-opentype-features/ */
  102. body {
  103. /* http://www.cssfontstack.com/ Palatino 99% Win 86% Mac */
  104. font-family: "EquityTextB", Palatino, serif;
  105. background-color: #f0f0ea;
  106. color: #07486c;
  107. font-kerning: normal;
  108. -moz-osx-font-smoothing: grayscale;
  109. -webkit-font-smoothing: subpixel-antialiased;
  110. text-rendering: optimizeLegibility;
  111. font-variant-ligatures: common-ligatures contextual;
  112. font-feature-settings: "kern", "liga", "clig", "calt";
  113. }
  114. pre, code, kbd, samp, var, tt {
  115. font-family: 'TriplicateT4c', monospace;
  116. }
  117. em {
  118. font-style: italic;
  119. color: #323a45;
  120. }
  121. strong {
  122. font-weight: bold;
  123. color: black;
  124. }
  125. nav {
  126. background-color: #323a45;
  127. color: #f0f0ea;
  128. display: flex;
  129. justify-content: space-around;
  130. padding: 1rem .5rem;
  131. }
  132. nav:last-child {
  133. border-bottom: 1vh solid #2d7474;
  134. }
  135. nav a {
  136. color: #f0f0ea;
  137. }
  138. nav abbr {
  139. border-bottom: 1px dotted white;
  140. }
  141. h1 {
  142. border-top: 1vh solid #2d7474;
  143. border-bottom: .2vh dotted #2d7474;
  144. background-color: #e3e1e1;
  145. color: #323a45;
  146. text-align: center;
  147. padding: 5rem 0 4rem 0;
  148. width: 100%;
  149. font-family: 'ConcourseT3';
  150. display: flex;
  151. flex-direction: column;
  152. }
  153. h1.single {
  154. padding-bottom: 10rem;
  155. }
  156. h1 span {
  157. position: absolute;
  158. top: 1vh;
  159. left: 20%;
  160. line-height: 0;
  161. }
  162. h1 span a {
  163. line-height: 1.7;
  164. padding: 1rem 1.2rem .6rem 1.2rem;
  165. border-radius: 0 0 6% 6%;
  166. background: #2d7474;
  167. font-size: 1.3rem;
  168. color: white;
  169. text-decoration: none;
  170. }
  171. h2 {
  172. margin: 4rem 0 1rem;
  173. border-top: .2vh solid #2d7474;
  174. padding-top: 1vh;
  175. }
  176. h3 {
  177. text-align: center;
  178. margin: 3rem 0 .75em;
  179. }
  180. hr {
  181. height: .4rem;
  182. width: .4rem;
  183. border-radius: .4rem;
  184. background: #07486c;
  185. margin: 2.5rem auto;
  186. }
  187. time {
  188. display: bloc;
  189. margin-left: 0 !important;
  190. }
  191. ul, ol {
  192. margin: 2rem;
  193. }
  194. ul {
  195. list-style-type: square;
  196. }
  197. a {
  198. text-decoration-skip-ink: auto;
  199. text-decoration-thickness: 0.05em;
  200. text-underline-offset: 0.09em;
  201. }
  202. article {
  203. max-width: 50rem;
  204. display: flex;
  205. flex-direction: column;
  206. margin: 2rem auto;
  207. }
  208. article.single {
  209. border-top: .2vh dotted #2d7474;
  210. margin: -6rem auto 1rem auto;
  211. background: #f0f0ea;
  212. padding: 2rem;
  213. }
  214. article p:last-child {
  215. margin-bottom: 1rem;
  216. }
  217. p {
  218. padding: 0 .5rem;
  219. margin-left: 3rem;
  220. }
  221. p + p,
  222. figure + p {
  223. margin-top: 2rem;
  224. }
  225. blockquote {
  226. background-color: #e3e1e1;
  227. border-left: .5vw solid #2d7474;
  228. display: flex;
  229. flex-direction: column;
  230. align-items: center;
  231. padding: 1rem;
  232. margin: 1.5rem;
  233. }
  234. blockquote cite {
  235. font-style: italic;
  236. }
  237. blockquote p {
  238. margin-left: 0;
  239. }
  240. figure {
  241. border-top: .2vh solid #2d7474;
  242. background-color: #e3e1e1;
  243. text-align: center;
  244. padding: 1.5rem 0;
  245. margin: 1rem 0 0;
  246. font-size: 1.5rem;
  247. width: 100%;
  248. }
  249. figure img {
  250. max-width: 250px;
  251. max-height: 250px;
  252. border: .5vw solid #323a45;
  253. padding: 1px;
  254. }
  255. figcaption {
  256. padding: 1rem;
  257. line-height: 1.4;
  258. }
  259. aside {
  260. display: flex;
  261. flex-direction: column;
  262. background-color: #e3e1e1;
  263. padding: 1rem 0;
  264. border-bottom: .2vh solid #07486c;
  265. }
  266. aside p {
  267. max-width: 50rem;
  268. margin: 0 auto;
  269. }
  270. /* https://fvsch.com/code/css-locks/ */
  271. p, li, pre, code, kbd, samp, var, tt, time, details, figcaption {
  272. font-size: 1rem;
  273. line-height: calc( 1.5em + 0.2 * 1rem );
  274. }
  275. h1 {
  276. font-size: 1.9rem;
  277. line-height: calc( 1.2em + 0.2 * 1rem );
  278. }
  279. h2 {
  280. font-size: 1.6rem;
  281. line-height: calc( 1.3em + 0.2 * 1rem );
  282. }
  283. h3 {
  284. font-size: 1.35rem;
  285. line-height: calc( 1.4em + 0.2 * 1rem );
  286. }
  287. @media (min-width: 20em) {
  288. /* The (100vw - 20rem) / (50 - 20) part
  289. resolves to 0-1rem, depending on the
  290. viewport width (between 20em and 50em). */
  291. p, li, pre, code, kbd, samp, var, tt, time, details, figcaption {
  292. font-size: calc( 1rem + .6 * (100vw - 20rem) / (50 - 20) );
  293. line-height: calc( 1.5em + 0.2 * (100vw - 50rem) / (20 - 50) );
  294. margin-left: 0;
  295. }
  296. h1 {
  297. font-size: calc( 1.9rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  298. line-height: calc( 1.2em + 0.2 * (100vw - 50rem) / (20 - 50) );
  299. }
  300. h2 {
  301. font-size: calc( 1.5rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  302. line-height: calc( 1.3em + 0.2 * (100vw - 50rem) / (20 - 50) );
  303. }
  304. h3 {
  305. font-size: calc( 1.35rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  306. line-height: calc( 1.4em + 0.2 * (100vw - 50rem) / (20 - 50) );
  307. }
  308. }
  309. @media (min-width: 50em) {
  310. /* The right part of the addition *must* be a
  311. rem value. In this example we *could* change
  312. the whole declaration to font-size:2.5rem,
  313. but if our baseline value was not expressed
  314. in rem we would have to use calc. */
  315. p, li, pre, code, kbd, samp, var, tt, time, details, figcaption {
  316. font-size: calc( 1rem + .6 * 1rem );
  317. line-height: 1.5em;
  318. }
  319. p, li, pre, details {
  320. margin-left: 3rem;
  321. }
  322. h1 {
  323. font-size: calc( 1.9rem + 1.5 * 1rem );
  324. line-height: 1.2em;
  325. }
  326. h2 {
  327. font-size: calc( 1.5rem + 1.5 * 1rem );
  328. line-height: 1.3em;
  329. }
  330. h3 {
  331. font-size: calc( 1.35rem + 1.5 * 1rem );
  332. line-height: 1.4em;
  333. }
  334. figure img {
  335. max-width: 500px;
  336. max-height: 500px;
  337. }
  338. }
  339. figure.unsquared {
  340. margin-bottom: 1.5rem;
  341. }
  342. figure.unsquared img {
  343. height: inherit;
  344. }
  345. @media print {
  346. body { font-size: 100%; }
  347. a:after { content: " (" attr(href) ")"; }
  348. a, a:link, a:visited, a:after {
  349. text-decoration: underline;
  350. text-shadow: none !important;
  351. background-image: none !important;
  352. background: white;
  353. color: black;
  354. }
  355. abbr[title] { border-bottom: 0; }
  356. abbr[title]:after { content: " (" attr(title) ")"; }
  357. img { page-break-inside: avoid; }
  358. @page { margin: 2cm .5cm; }
  359. h1, h2, h3 { page-break-after: avoid; }
  360. p3 { orphans: 3; widows: 3; }
  361. img {
  362. max-width: 250px !important;
  363. max-height: 250px !important;
  364. }
  365. nav, aside { display: none; }
  366. }
  367. ul.with_columns {
  368. column-count: 1;
  369. }
  370. @media (min-width: 20em) {
  371. ul.with_columns {
  372. column-count: 2;
  373. }
  374. }
  375. @media (min-width: 50em) {
  376. ul.with_columns {
  377. column-count: 3;
  378. }
  379. }
  380. ul.with_two_columns {
  381. column-count: 1;
  382. }
  383. @media (min-width: 20em) {
  384. ul.with_two_columns {
  385. column-count: 1;
  386. }
  387. }
  388. @media (min-width: 50em) {
  389. ul.with_two_columns {
  390. column-count: 2;
  391. }
  392. }
  393. .gallery {
  394. display: flex;
  395. flex-wrap: wrap;
  396. justify-content: space-around;
  397. }
  398. .gallery figure img {
  399. margin-left: 1rem;
  400. margin-right: 1rem;
  401. }
  402. .gallery figure figcaption {
  403. font-family: 'ConcourseT3'
  404. }
  405. footer {
  406. font-family: 'ConcourseT3';
  407. display: flex;
  408. flex-direction: column;
  409. border-top: 3px solid white;
  410. padding: 4rem 0;
  411. background-color: #07486c;
  412. color: white;
  413. }
  414. footer > * {
  415. max-width: 50rem;
  416. margin: 0 auto;
  417. }
  418. footer a {
  419. color: #f1c40f;
  420. }
  421. footer .avatar {
  422. width: 200px;
  423. height: 200px;
  424. border-radius: 50%;
  425. float: left;
  426. -webkit-shape-outside: circle();
  427. shape-outside: circle();
  428. margin-right: 2rem;
  429. padding: 2px 5px 5px 2px;
  430. background: white;
  431. border-left: 1px solid #f1c40f;
  432. border-top: 1px solid #f1c40f;
  433. border-right: 5px solid #f1c40f;
  434. border-bottom: 5px solid #f1c40f;
  435. }
  436. </style>
  437. <h1>
  438. <span><a id="jumper" href="#jumpto" title="Un peu perdu ?">?</a></span>
  439. The State of Web Type (archive)
  440. <time>Pour la pérennité des contenus liés. Non-indexé, retrait sur simple email.</time>
  441. </h1>
  442. <section>
  443. <article>
  444. <h3><a href="https://dev.opera.com/articles/state-of-web-type/">Source originale du contenu</a></h3>
  445. <p>Typography has a long and rich history, but much has been lost in the transition to the web. While browser support for typography has advanced a lot in the last couple years, we still have a long way to go. Features print designers take for granted are either nonexistent on the web or have insufficient browser support in order to be useful. Challenges unique to web browsers such as responsive design and web font loading could use some improvement as well. Let’s take a look at some of the features we need for an optimal and beautiful reading experience.</p>
  446. <h2 id="opentype-features">OpenType Features</h2>
  447. <p>Typeface designers often put extra features in a font that can be used to customise text rendering. These are called OpenType features and include character spacing, alignment, ligatures, alternative characters, and so on. There are in fact <a href="https://www.microsoft.com/typography/otspec/featurelist.htm">more than 140 registered OpenType features</a>. Many of these features are optional, but some are actually required to properly render text (e.g. kerning and required ligatures). OpenType features are reasonably well supported by modern web browsers, but still come with a lot of caveats that make them hard to use.</p>
  448. <figure class="figure"><img src="/articles/state-of-web-type/figure-2.png" alt="" class="figure__media"/><figcaption class="figure__caption">From left to right: contextual alternates set in Caflisch Script Pro, ligatures set in Warnock Pro, and small caps set in Chaparral Pro.</figcaption></figure>
  449. <p>An important caveat is that not all fonts include all 140+ OpenType features. Most fonts only contain a small subset of features, such as kerning and ligatures. Others may include discretionary features, such as swashes and alternate characters. With the proliferation of web font and subsetting services we can’t always rely on information about OpenType features and character support provided by typeface designers. We need better tools to look inside our font files to see which features and characters are supported and which are not.</p>
  450. <p>If a font includes the features you wish to use, you still need to check if your target browsers support OpenType features. While most modern browsers support either the low-level <code>font-feature-settings</code> syntax or the high level <code>font-variant-*</code> syntax, there are still several browsers in common use that don’t support either syntax. Notable examples are Internet Explorer versions 6 to 9 and all versions of Android WebKit until 4.4. Luckily, the fallback behaviour for most OpenType features is graceful: text is still readable without them.</p>
  451. <table><thead><tr><th>Feature</th><th>IE10</th><th>IE11</th><th>Chrome</th><th>Firefox</th><th>Safari</th><th>Opera</th></tr></thead><tbody><tr><td><code>font-feature-settings</code></td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td><td>No</td><td>Yes</td></tr><tr><td>Ligatures (<code>liga</code>)</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr><tr><td>Swashes (<code>swsh</code>)</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td><td>No</td><td>Yes</td></tr><tr><td>Old style numerals (<code>onum</code>)</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td><td>No</td><td>Yes</td></tr><tr><td>Contextual alternates (<code>calt</code>)</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td></tr><tr><td>Small caps (<code>smcp</code>)</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Yes</td><td>No</td><td>Yes</td></tr></tbody></table>
  452. <p>The above table summarizes browser support for the <code>font-feature-settings</code> property and a select number of OpenType features. You can find more browser <a href="http://stateofwebtype.com/#opentype%20features">support data for common OpenType features on the State of Web Type</a>.</p>
  453. <p>Unfortunately, even if a browser supports the OpenType feature syntax it is not always guaranteed that it will support all individual features. A good (or rather bad) example of this is Safari which technically supports the <code>font-feature-settings</code> syntax, but ignores any value. Instead it explicitly enables a select number of features which you have no way of turning off.</p>
  454. <h2 id="justification--hyphenation">Justification &amp; Hyphenation</h2>
  455. <p>Many web developers think of justification as a solved problem (or worse, one to avoid). Set <code>text-align</code> to <code>justify</code> and you’re done, right? Not quite. The algorithm used in all web browsers is actually a very ineffective justification implementation. Tools like TeX and InDesign use a more sophisticated line breaking algorithm that optimises break points over an entire paragraph, whereas browsers only look at a single line. This leads to suboptimal justification and large spaces between words.</p>
  456. <figure class="figure"><img src="/articles/state-of-web-type/figure-3.png" alt="" class="figure__media"/><figcaption class="figure__caption">Left: a justified paragraph, middle: extraneous word spaces are highlighted, right: word spacing and justification is improved by enabling hyphenation.</figcaption></figure>
  457. <p>Browsers could implement the same line breaking algorithm as used in TeX, but have decided not to for performance reasons. This is an odd reason — TeX was developed and runs on computers much less powerful than those commonly used in mobile phones. Another way to improve poor line breaking is by hyphenating words. This introduces more potential line break points and reduces the chance of awkward line breaks. A common misunderstanding is that hyphenation is only useful for justified text. This is not true. Hyphenation is also a useful tool to control the raggedness of center, left, and right aligned text. The CSS <code>hyphens</code> property can be used to control hyphenation. Setting it to <code>auto</code> will enable hyphenation (provided the document or element specifies a language using the <code>lang</code> attribute), while setting it to <code>none</code> disables hyphenation.</p>
  458. <table><thead><tr><th>IE8</th><th>IE9</th><th>IE10</th><th>IE11</th><th>Chrome</th><th>Firefox</th><th>Safari</th><th>Opera</th></tr></thead><tbody><tr><td>No</td><td>No</td><td>Yes</td><td>Yes</td><td>No</td><td>Yes</td><td>Yes</td><td>No</td></tr></tbody></table>
  459. <p>The <a href="http://stateofwebtype.com/#hyphens"><code>hyphens</code> property is supported by almost all modern browsers</a> except those based on the Blink rendering engine. Chrome and Opera previously supported the <code>hyphens</code> syntax but neither browser shipped with hyphenation dictionaries. In a surprising move they recently dropped support for the <code>hyphens</code> syntax completely. The Blink developers decided to <a href="https://groups.google.com/a/chromium.org/d/topic/blink-dev/STiDJjDwVF8/discussion">remove the <code>hyphens</code> property</a> because it was never fully implemented and broke feature detection. While such regressions are not common, they are worrisome. A feature required for correct text layout should be supported everywhere. So, for now, you’ll need to rely on either server-side hyphenation or one of the two client-side hyphenation libraries: <a href="https://github.com/bramstein/hypher">Hypher</a> and <a href="https://code.google.com/p/hyphenator/">Hyphenator</a>.</p>
  460. <h2 id="font-loading">Font Loading</h2>
  461. <p>Web font usage has increased significantly in the past couple years. This is great news. However, it also means that web fonts have become a critical part of web sites and, by extension, a performance bottleneck. You may have experienced the dreaded Flash Of Invisible Text (FOIT) while visiting a website on a slow network connection. The decision by some browsers to block rendering of text until web fonts have downloaded is opposite to the tenets of progressive enhancement. Content should come first and web fonts are an enhancement. After all, you can still read the text, even though it might not render in the intended font (well, unless your browser hides text while it is downloading fonts — better pray it uses a timeout).</p>
  462. <p>Not all browsers hide text while downloading web fonts. For example Internet Explorer always renders text in a fallback font while it is downloading fonts. This has been dubbed the Flash Of Unstyled Text (FOUT). This misnomer. FOUT is a feature and a condition everyone should anticipate and design for. Selecting and testing fallback fonts is an important task while designing and building a site.</p>
  463. <table><thead><tr><th/><th>IE9</th><th>IE10</th><th>IE11</th><th>Chrome</th><th>Firefox</th><th>Safari</th><th>Opera</th></tr></thead><tbody><tr><td>font rendering</td><td>FOUT</td><td>FOUT</td><td>FOUT</td><td>FOIT</td><td>FOIT</td><td>FOIT</td><td>FOIT</td></tr><tr><td>timeout</td><td>n/a</td><td>n/a</td><td>n/a</td><td>3 sec.</td><td>3 sec.</td><td>∞</td><td>3 sec.</td></tr></tbody></table>
  464. <p>The above table shows the usage of the FOUT and FOIT across browsers. Note that Safari (and older Android WebKit versions) do not have a timeout. On these browsers, text won’t render until fonts have completely loaded.</p>
  465. <p>Browser vendors are working on a proposal for a new CSS property to control font loading and rendering. It is meant to give developers more control over the blocking and swapping behaviour of web fonts. <a href="https://github.com/KenjiBaheux/css-font-rendering">The proposed <code>font-rendering</code> property</a> accepts three parameters:</p>
  466. <ul><li><code>block</code>: block rendering of the text while fonts are downloading with an optional timeout;</li><li><code>swap</code>: use a fallback font and render the font when it becomes available with an optional timeout;</li><li><code>optional</code>: use the font if it is cached and otherwise use the fallback font. Do not re-render the page, even if the web font becomes available at a later time.</li></ul>
  467. <p>These parameters can also be used to develop custom font loading schemes. For example, for an important and fast loading font we can block text rendering for <code>1s</code>. If the font doesn’t load within that time we can allow up to 10 seconds where it is acceptable to re-render the page.</p>
  468. <pre><code>font-rendering: block 1s swap 10s;
  469. </code></pre>
  470. <p>Browsers should standardize the default font loading behaviour once the <code>font-rendering</code> property is implemented. Ideally the default value should be <code>block 0s swap infinite</code> as used by Internet Explorer (i.e. the Flash of Unstyled Text). Blocking text rendering while loading fonts should be opt-in and not a default. Browser should treat web fonts as progressive enhancement by default and make content available as soon as possible. Opting out of that behaviour is the responsibility of a web developer and not the browser.</p>
  471. <p>Until the <code>font-rendering</code> property is implemented we can use <a href="https://dev.opera.com/articles/better-font-face/">the CSS Font Loading API</a> to implement the same behaviour in JavaScript. The Font Loading API is supported by Chrome, Opera, and soon Firefox. There is also <a href="https://github.com/bramstein/fontloader">a Font Loading API polyfill</a> for browsers that do not support it natively.</p>
  472. <h2 id="looking-to-the-future">Looking to the Future</h2>
  473. <p>This is just the tip of the iceberg. To compete with and surpass the typographic quality of print publications we need support for drop caps, colour fonts, advanced layout (akin to shapes, exclusions and regions), sizing text to fit a container, widows and orphans, balanced text, math typesetting (though MathML is now an officially recommended standard, <a href="https://www.chromestatus.com/features/5240822173794304">Chromium</a> and <a href="https://status.modern.ie/mathml">Internet Explorer</a> have no plans to support it), and so on. Clearly, we need to do better and push browser vendors for these features if we want to improve the web’s reading experience. You can help out by participating in the W3C mailing lists, building demos, implementing polyfills and drafting specifications for features <em>you</em> want to see. Don’t worry about getting it right the first time. Sometimes the best thing to come out of a specification is a new and better specification.</p>
  474. <figure class="figure"><a href="http://stateofwebtype.com/"><img src="/articles/state-of-web-type/figure-1.png" alt="" class="figure__media"/></a></figure>
  475. <p>Another way to contribute is to draw attention to partially implemented specifications and bugs by keeping track of what works and what doesn’t. That’s why I recently launched a new project called the <a href="http://stateofwebtype.com/">State of Web Type</a>. Its goal is to contain up to date browser support data for all type and typography features on the web. The project is <a href="https://github.com/bramstein/stateofwebtype">open source</a> and contributions and corrections are more than welcome. Let’s work together to make the web a better platform for publishing and reading!</p>
  476. </article>
  477. </section>
  478. <nav id="jumpto">
  479. <p>
  480. <a href="/david/blog/">Accueil du blog</a> |
  481. <a href="https://dev.opera.com/articles/state-of-web-type/">Source originale</a> |
  482. <a href="/david/stream/2019/">Accueil du flux</a>
  483. </p>
  484. </nav>
  485. <footer>
  486. <div>
  487. <img src="/static/david/david-larlet-avatar.jpg" loading="lazy" class="avatar" width="200" height="200">
  488. <p>
  489. Bonjour/Hi!
  490. Je suis <a href="/david/" title="Profil public">David&nbsp;Larlet</a>, je vis actuellement à Montréal et j’alimente cet espace depuis 15 ans. <br>
  491. Si tu as apprécié cette lecture, n’hésite pas à poursuivre ton exploration. Par exemple via les <a href="/david/blog/" title="Expériences bienveillantes">réflexions bimestrielles</a>, la <a href="/david/stream/2019/" title="Pensées (dés)articulées">veille hebdomadaire</a> ou en t’abonnant au <a href="/david/log/" title="S’abonner aux publications via RSS">flux RSS</a> (<a href="/david/blog/2019/flux-rss/" title="Tiens c’est quoi un flux RSS ?">so 2005</a>).
  492. </p>
  493. <p>
  494. Je m’intéresse à la place que je peux avoir dans ce monde. En tant qu’humain, en tant que membre d’une famille et en tant qu’associé d’une coopérative. De temps en temps, je fais aussi des <a href="https://github.com/davidbgk" title="Principalement sur Github mais aussi ailleurs">trucs techniques</a>. Et encore plus rarement, <a href="/david/talks/" title="En ce moment je laisse plutôt la place aux autres">j’en parle</a>.
  495. </p>
  496. <p>
  497. Voici quelques articles choisis :
  498. <a href="/david/blog/2019/faire-equipe/" title="Accéder à l’article complet">Faire équipe</a>,
  499. <a href="/david/blog/2018/bivouac-automnal/" title="Accéder à l’article complet">Bivouac automnal</a>,
  500. <a href="/david/blog/2018/commodite-effondrement/" title="Accéder à l’article complet">Commodité et effondrement</a>,
  501. <a href="/david/blog/2017/donnees-communs/" title="Accéder à l’article complet">Des données aux communs</a>,
  502. <a href="/david/blog/2016/accompagner-enfant/" title="Accéder à l’article complet">Accompagner un enfant</a>,
  503. <a href="/david/blog/2016/senior-developer/" title="Accéder à l’article complet">Senior developer</a>,
  504. <a href="/david/blog/2016/illusion-sociale/" title="Accéder à l’article complet">L’illusion sociale</a>,
  505. <a href="/david/blog/2016/instantane-scopyleft/" title="Accéder à l’article complet">Instantané Scopyleft</a>,
  506. <a href="/david/blog/2016/enseigner-web/" title="Accéder à l’article complet">Enseigner le Web</a>,
  507. <a href="/david/blog/2016/simplicite-defaut/" title="Accéder à l’article complet">Simplicité par défaut</a>,
  508. <a href="/david/blog/2016/minimalisme-esthetique/" title="Accéder à l’article complet">Minimalisme et esthétique</a>,
  509. <a href="/david/blog/2014/un-web-omni-present/" title="Accéder à l’article complet">Un web omni-présent</a>,
  510. <a href="/david/blog/2014/manifeste-developpeur/" title="Accéder à l’article complet">Manifeste de développeur</a>,
  511. <a href="/david/blog/2013/confort-convivialite/" title="Accéder à l’article complet">Confort et convivialité</a>,
  512. <a href="/david/blog/2013/testament-numerique/" title="Accéder à l’article complet">Testament numérique</a>,
  513. et <a href="/david/blog/" title="Accéder aux archives">bien d’autres…</a>
  514. </p>
  515. <p>
  516. On peut <a href="mailto:david%40larlet.fr" title="Envoyer un courriel">échanger par courriel</a>. Si éventuellement tu souhaites que l’on travaille ensemble, tu devrais commencer par consulter le <a href="http://larlet.com">profil dédié à mon activité professionnelle</a> et/ou contacter directement <a href="http://scopyleft.fr/">scopyleft</a>, la <abbr title="Société coopérative et participative">SCOP</abbr> dont je fais partie depuis six ans. Je recommande au préalable de lire <a href="/david/blog/2018/cout-site/" title="Attention ce qui va suivre peut vous choquer">combien coûte un site</a> et pourquoi je suis plutôt favorable à une <a href="/david/pro/devis/" title="Discutons-en !">non-demande de devis</a>.
  517. </p>
  518. <p>
  519. Je ne traque pas ta navigation mais mon
  520. <abbr title="Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33.184162340">hébergeur</abbr>
  521. conserve des logs d’accès.
  522. </p>
  523. </div>
  524. </footer>
  525. <script type="text/javascript">
  526. ;(_ => {
  527. const jumper = document.getElementById('jumper')
  528. jumper.addEventListener('click', e => {
  529. e.preventDefault()
  530. const anchor = e.target.getAttribute('href')
  531. const targetEl = document.getElementById(anchor.substring(1))
  532. targetEl.scrollIntoView({behavior: 'smooth'})
  533. })
  534. })()
  535. </script>