- PVSM.RU - https://www.pvsm.ru -

Шрифты в вебе, обзор от 2016 года

Шрифты в вебе, обзор от 2016 года - 1

Предисловие

Статья — не про всё возможное, связанное с типографикой и текстами, вроде letter-spacing и max-height. Это скорее некоторый список занятных возможностей, которые могут быть углублённо изучены при наличии достаточного любопытства и времени. Надеюсь, для большей части найдётся то, что они не знали или слышали краем уха.

Вступление

В 2016 году нестандартными шрифтами никого не удивишь. 93% браузеров [1] поддерживают их, и около 62% [2] сайтов их используют. Кто-то просто пишет @font-face или вставляет <link> с Google Fonts, кто-то вставляет мегабайт шрифтов в base64 прямо в css. Возможностей много.

Загрузка

Статья была бы неполной без таблички разного поведения браузеров во время загрузки шрифтов, но я не могу себе позволить её вставить — она так часто встречается, что уже, вероятно, вызывает нервный тик.

Общие понятия:

FOIT — flash of invisible text. Сначала отрисовывается страница без текста, затем — сразу с нужным шрифтом.
FOUT — flash of unstyled text. Сначала используется один шрифт, затем — загруженный.
FOFTнекоторые [3] выделяют такой подтип проблем, но встречается реже.

Очень хорошо описаны различные стратегии загрузки шрифтов в недавней статье от Zach Leatherman [4] (русская версия [5]), каждая со своими плюсами и минусами. Я же попробую дать упрощённый обзор различных вариантов: если понадобится изучить, набор ссылок будет под рукой.

@font-face без дополнительных ухищрений

Встречается часто, можно оставить всё как есть на откуп браузеру. Также плюс в том, что пользователи, скорее всего, уже привыкли к такому поведению и не замечают проблем. Минусы: разное поведение в разных браузерах, спорное поведение в некоторых случаях. В сафари и некоторых других браузерах в случае проблем загрузки шрифта может вообще ничего не отображаться [6] длительное время..

Плюсы:

  • Не требует дополнительных усилий
  • Скорее всего, пользователи привыкли к такому поведению и редко заостряют на этом внимание

Минусы:

  • Разное поведение в разных браузерах
  • Спорное поведение в некоторых случаях

Библиотека для определения загрузки шрифта

Общая идея: используем стандартный шрифт до загрузки, после загрузки переключаем класс на body и на всей странице включаются новые шрифты. Это похоже на стандартное поведение Internet Explorer и Edge.

Плюсы:

  • Контроль за использованием шрифтов
  • Небольшой размер библиотек
  • Просто использовать

Минусы:

  • Переключение шрифта заметно пользователю
  • Может приводить к перемещению элементов на странице из-за смены размера текста
  • Требуются дополнительные ухищрения для отсутствия перерисовки шрифта при перезаходе: флаги в куках, sessionStorage

Ссылки:

Кодирование шрифта в base64

Самый разнообразный способ. Можно инлайнить шрифт прямо в основной файл стилей, грузить их асинхронно или вовсе складывать в localStorage. Для кого-то окажется неожиданным то, что после gzip размер отличается от бинарного файла совсем немного.

Плюсы:

  • В общем случае не нужны дополнительные библиотеки для определения загрузки шрифтов
  • При использовании вместе с основной частью css делает ситуации с foit и fout гораздо реже
  • При сохранении в localStorage всё кеширование шрифтов в наших руках

Минусы:

  • Теряется поддержка нескольких типов шрифтов. Либо нужно их дублировать (и тем самым увеличивать общий размер), либо выбрать наиболее распространённый (например, woff и потерять экономию от woff2)
  • Окончание загрузки css — не гарант того, что шрифт может быть сразу отображён! Как и вставка этого css напрямую в страницу. Браузерам требуется время на парсинг шрифтов перед их использованием. Всё это выливается в три стадии отрисовки: дефолтный шрифт, foit, нужный шрифт
  • При вставке просто в css будет задерживать первую отрисовку всей страницы

Ссылки:

font-display

Новое css-свойство [15], которое позволяет контролировать отображение шрифтов во время загрузки. Плюсы-минусы очевидны: простота в использовании и слабая поддержка (скорее, никакая).

<link rel=preload>

Это не совсем способ загрузки, а некоторая оптимизация. С помощью preload можно сократить время до окончания загрузки веб-шрифтов, попутно уменьшить вероятность foit. Браузеры на основе Blink начинают загружать шрифты только после того, как найдут текст на странице с соответствующим шрифтом, а это сильно откладывает окончательный показ страницы: нужно загрузить css, распарсить её, применить к дом-дереву и найти нужный элемент. preload указывает браузеру, что указанный ресурс стоит грузить прямо сейчас. Требуются атрибуты as, type и crossorigin.

Ссылки:

Всё остальное

Есть ещё несколько вариаций всего перечисленного, а также вариант через JS (об этом ниже). Например, можно загрузить только одно начертание шрифта, а все остальные использовать при повторных заходах. Или сильно урезать набор используемых символов шрифта (до 5-10 кб) и положить всё это в base64. А может, на первом заходе вообще не использовать на первом заходе нестандартные шрифты, а только загружать их? Также можно не использовать шрифты, если текста почти нет: для логотипов вполне подойдёт SVG. Что выбрать? Каждый решает сам для себя, на основе дизайна, шрифта(-ов) и аудитории.

FontFace

Новое js-api [18] позволяет загружать и использовать шрифты, не используя объявление @font-face вообще. Несколько примеров, чтобы было понятно, о чём речь:

var f = new FontFace("newfont", "url(newfont.woff)", {});
f.load().then(function (loadedFace) {
  document.fonts.add(loadedFace);
  document.body.style.fontFamily = "newfont, serif";
});

fetch('newfont.woff2').then(
  res => res.arrayBuffer()
).then(
  buf => new FontFace("newfont", buf)
).then(ff => {
  document.fonts.add(ff)
});

Троеточие — не часть кода.

  new FontFace('t', 'url( "data:application/font-woff2;base64, <...>")').load();

Проблема в том, что понять, какой формат поддерживается, напрямую нельзя. Поддержка браузерами тоже не полная [19], но к ней добавится Safari 10. FontFace может быть полезен при отрисовке текста через canvas, так как не придётся создавать невидимые элементы с текстом.

Ссылки:

CSS-свойства

font-weight и font-style

font-weight — достаточно известное свойство. Часто можно увидеть bold, реже — что-то со значением в числах. Стоит отметить то, что веб всё чаще выбирается из bold/italic/bold-italic, сейчас можно увидеть всевозможные thin, light, medium (таких ключевых слов нет, но для них как раз используются числовые значения). Другой интересный вопрос — что делают браузеры, если нужного начертания нет в наличии? В случае жирного/курсивного начертания они пытаются сгенерировать глифы на основе обычной вариации шрифта.

Ссылки:

unicode-range

Данное свойство позволяет указать список символов, которые должны быть отображены шрифтом. Это может быть полезно в качестве оптимизации — если на странице не будет символов из этого списка, шрифт не будет загружен вовсе. Также unicode-range можно использовать для стилизации отдельных символов, например, кавычек или для отображения символа рубля. Проблема может быть в поддержке этого свойства браузерами, и хотя она постепенно уходит, всё равно нужно думать: «а что, если бы unicode-range не было».

Ссылки:

font-variant и font-feature-settings

font-variant — несколько обновлённый вариант font-feature-settings. Эти свойства позволяют задействиовать дополнительные возможности, включённые в шрифт. Например, кернинг, диагональные дроби, лигатуры и различные варианты иероглифов.

Ссылки:

text-rendering

Свойство задумывалось как обобщённый регулятор скорости отрисовки шрифта, влияя одновременно на кернинг и лигатуры. Несмотря на свою мощность, свойство не получило значительного распространения и заслужило славу бажного и тормозного. В настоящее время имеет смысл воспользоваться font-variant и font-kerning, они дают больше контроля (если не так важна поддержка браузерами, а иначе — font-feature-settings). На самом деле, text-rendering является свойством SVG и не описано ни в одной спецификации CSS.

Ссылки:

font-kerning

font-kerning контролирует работу кернинга (отступы между отдельными сочетаниями букв). Для включения требуется информация о кернинге внутри самого шрифта. Является более современной заменой части функционала font-feature-settings.

Ссылки:

font-stretch

Редкоиспользуемое свойство [37] с тяжёлой судьбой. Введённое в CSS 2 и поддержанное в Firefox 9 с Internet Explorer 9, оно было удално из CSS 2.1 и забыто до CSS 3, а не так давно было добавлено в Chrome 48. Оно позволяет использовать альтренативные начертания шрифта, более узкие или широкие.

Использование встроенных шрифтов

В OS X и iOS очень интересная ситуация с системными шрифтами. Недавно там были представлен San Francisco в качестве основного шрифта интерфейса системы. И если Helvitica Neue можно было указать прямо в font-family (хоть порой в сложном варианте), то с San Francisco такой способ был намеренно затруднён. По новой логике, чтобы разработчики не затачивались на какой-то конкретный шрифт, в таких случаях нужно использовать ключевые слова "-apple-system-*", которые поддерживаются с iOS 7. Как аналог, в десктопном хроме недавно добавили значение BlinkMacSystemFont.

В Android есть шрифт Roboto, который недоступен по своему имени. Однако можно использовать простые sans-serif, sans-serif-light, sans-serif-medium и другие.

Из-за лицензии, в общем случае нельзя просто взять и положить на свой сервер чьи-то системные шрифты. Допускается только указание их в css, так как тогда заботы о лицензии установленных в систему шрифтов ложатся на плечи пользователя.

Ссылки:

Оптимизация

Самое простое — использовать оптимальный формат. Появившийся не так давно woff2 некоторые оценивают как лучший вариант для шрифтов, из-за примерно 30% уменьшения размера файла по сравнению с woff. Судя по caniuse [46] — woff2 скоро будет поддерживаться в Edge и должен быть в новом Safari 10.

Другой способ — убрать неиспользуемую информацию из самого шрифта, например, лигатуры или наборы символов из неиспользуемых языков. Также есть возможность упростить сами векторные кривые символов — иногда в них слишком много точек и их можно задать проще.

Ссылки:

Определение текущего шрифта элемента

Иногда стоит задача определения текущего шрифта элемента. В случае разработки могут помочь Chromium Developer Tools и недавно вернувшаяся панелька Fonts из Firefox. В ином случае остаётся только считать размер элемента и сравнивать его после смены значения font-family. Примерно этим занимаются FontFaceOnload и FontFaceObserver, если в браузере недоступен js-интерфейс FontFace. Почему браузеры не предоставляют для этого внятного апи? Дело в том, что отдельные символы внутри одного элемента могут быть отрисованы разными шрифтами, которые перечислен в font-family. На это может влиять упомянутый выше unicode-range и сам набор глифов шрифта.

Где взять нестандартные шрифты?

Прочее

Автор: 4eb0da

Источник [56]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/css/187747

Ссылки в тексте:

[1] 93% браузеров: http://caniuse.com/#feat=fontface

[2] 62%: http://httparchive.org/trends.php

[3] некоторые: https://www.zachleat.com/web/foft/

[4] недавней статье от Zach Leatherman: https://www.zachleat.com/web/comprehensive-webfonts/

[5] русская версия: http://css-live.ru/articles/ischerpyvayushhee-rukovodstvo-po-strategiyam-zagruzki-veb-shriftov.html

[6] вообще ничего не отображаться: https://www.filamentgroup.com/lab/font-loading.html

[7] Web Font Loading Patterns: https://www.bramstein.com/writing/web-font-loading-patterns.html

[8] русская версия: http://web-standards.ru/articles/web-font-loading-patterns/

[9] FontFaceObserver: https://github.com/bramstein/fontfaceobserver

[10] FontFaceOnload: https://github.com/zachleat/fontfaceonload

[11] Описание сохранения шрифтов в localStorage: http://bdadam.com/blog/loading-webfonts-with-high-performance.html

[12] Скрипт загрузки шрифтов с сайта smashingmagazine.com: https://gist.github.com/hdragomir/8f00ce2581795fd7b1b7

[13] Web Font anti-pattern: data-uris: https://www.zachleat.com/web/web-font-data-uris/

[14] русская версия: http://css-live.ru/articles/antipattern-dlya-veb-shriftov-data-uri.html

[15] css-свойство: https://developers.google.com/web/updates/2016/02/font-display

[16] Использование preload для шрифтов: https://www.smashingmagazine.com/2016/02/preload-what-is-it-good-for/#early-loading-of-fonts

[17] русская версия: http://prgssr.ru/development/dlya-chego-stoit-ispolzovat-predzagruzku.html

[18] js-api: https://developer.mozilla.org/en/docs/Web/API/FontFace

[19] не полная: http://caniuse.com/#feat=font-loading

[20] CSS Font Loading Module Level 3: https://drafts.csswg.org/css-font-loading/

[21] Woff2 feature test: https://github.com/filamentgroup/woff2-feature-test/

[22] Пример использования: https://googlechrome.github.io/samples/font-face-set/

[23] Три способа использования разных начертаний: https://www.smashingmagazine.com/2013/02/setting-weights-and-styles-at-font-face-declaration/

[24] Статья на MDN с примерным описанием алгоритма фолбека: https://developer.mozilla.org/en/docs/Web/CSS/font-weight

[25] Правильное подключение нескольких начертаний одного шрифта: http://www.metaltoad.com/blog/how-use-font-face-avoid-faux-italic-and-bold-browser-styles

[26] Табличка с использованием bolder и lighter: http://www.quirksmode.org/css/text/fontweight.html

[27] Статья на MDN с описанием CSS-свойства font-synthesis: https://developer.mozilla.org/ru/docs/Web/CSS/font-synthesis

[28] Статья на MDN с описанием unicode-range: https://developer.mozilla.org/en/docs/Web/CSS/@font-face/unicode-range

[29] Старая статья про стилизацию амперсандов: https://24ways.org/2011/creating-custom-font-stacks-with-unicode-range

[30] Атака на сайт с помощью инъекции css с unicode-range: http://mksben.l0.cm/2015/10/css-based-attack-abusing-unicode-range.html

[31] Описание различных значений font-feature-settings: https://helpx.adobe.com/typekit/using/open-type-syntax.html

[32] Описание text-rendering с примерами: http://tympanus.net/codrops/css_reference/text-rendering/

[33] Описание использования и проблем с text-rendering: https://bocoup.com/weblog/text-rendering

[34] русская версия: http://frontender.info/text-rendering/

[35] Работа с кернингом в браузере, включая таблицы поддержки text-rendering и font-feature-settings (правда. несколько устаревшие): http://blog.typekit.com/2014/02/05/kerning-on-the-web/

[36] Статья на MDN вместе с интерактивной демкой свойства: https://developer.mozilla.org/ru/docs/Web/CSS/font-kerning

[37] свойство: https://developer.mozilla.org/ru/docs/Web/CSS/font-stretch

[38] Описание шрифтов -apple-system: https://webkit.org/blog/3709/using-the-system-font-in-web-content/

[39] Использование системных шрифтов в вебе: https://www.smashingmagazine.com/2015/11/using-system-ui-fonts-practical-guide/

[40] русская версия: http://prgssr.ru/development/ispolzovanie-shriftov-sistemnogo-interfejsa-v-veb-dizajne.html

[41] Список названий начертаний Roboto в андроиде, вместе с минимальной версией (ответ про приложения, но в вебе тоже работает): http://stackoverflow.com/a/19692168

[42] Список названий начертаний Helvetica Neue: https://gist.github.com/gpessia/8595729

[43] Список предустановленных шрифтов в Windows: https://en.wikipedia.org/wiki/List_of_typefaces_included_with_Microsoft_Windows

[44] Список предустановленных шрифтов в OS X: https://en.wikipedia.org/wiki/List_of_typefaces_included_with_OS_X

[45] Список предустановленных шрифтов в iOS, watchOS, tvOS: http://iosfonts.com/

[46] Судя по caniuse: http://caniuse.com/#feat=woff2

[47] FontSquirrel. Сайт, позволяющий конвертировать шрифты, удалять неиспользуемые начертания символов, кодировать в base64 и многое другое: https://www.fontsquirrel.com/

[48] FontForge, приложение-редактор шрифтов. Низкоуровневый инструмент — можно удалять отдельные глифы, упрощать кривые, удалять кернинг, вплоть до сдвига отдельных точек: https://fontforge.github.io/en-US/

[49] Советы по оптимизации от Google: https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/webfont-optimization

[50] fontTools. Библиотека на питоне для манипуляции шрифтами: https://github.com/behdad/fonttools/

[51] Консольная утилита для конвертации ttf > woff2: https://www.npmjs.com/package/ttf2woff2

[52] https://fonts.google.com/: https://fonts.google.com/

[53] https://www.fontshop.com/: https://www.fontshop.com/

[54] Как растровый шрифт медиум сломал: https://medium.com/design/system-shock-6b1dc6d6596f#.x78lzspx2

[55] Стоит ли вообще использовать нестандартные шрифты?: https://martinwolf.org/blog/2016/03/webfont-drama-march-2016-edition

[56] Источник: https://habrahabr.ru/post/310044/?utm_source=habrahabr&utm_medium=rss&utm_campaign=sandbox