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

в 6:27, , рубрики: css, font-face, fontfaceobserver, fonts, Разработка веб-сайтов

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

Предисловие

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

Вступление

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

Загрузка

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

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

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

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

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

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

Плюсы:

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

Минусы:

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

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

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

Плюсы:

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

Минусы:

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

Ссылки:

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

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

Плюсы:

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

Минусы:

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

Ссылки:

font-display

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

<link rel=preload>

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

Ссылки:

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

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

FontFace

Новое js-api позволяет загружать и использовать шрифты, не используя объявление @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();

Проблема в том, что понять, какой формат поддерживается, напрямую нельзя. Поддержка браузерами тоже не полная, но к ней добавится 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

Редкоиспользуемое свойство с тяжёлой судьбой. Введённое в 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 — woff2 скоро будет поддерживаться в Edge и должен быть в новом Safari 10.

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

Ссылки:

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

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

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

Прочее

Автор: 4eb0da

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js