CSS font display: будущее рендера шрифтов в вебе

CSS font display: будущее рендера шрифтов в вебе

От автора: если шрифт отсутствует на мобильном устройстве, его необходимо скачать. Это один из минусов веб-шрифтов. Пока шрифт не станет доступным, браузеру нужно решить, как отобразить блок текста с этим шрифтом. И сделать это нужно так, чтобы смена шрифтов несильно повлияла на UX и восприятие производительности.

Со временем браузеры приняли различные стратегии, дабы минимизировать эту проблему. Но эти стратегии работают по-разному, и разработчики совсем не контролируют процесс. Разработчикам приходилось разрабатывать различные техники и обходные решения для этих проблем.

CSS font display: будущее рендера шрифтов в вебе

Встречайте дескриптор font display CSS для правила @font-face. Это CSS свойство представляет стандартизированный подход к данному поведению и позволяет разработчикам контролировать процесс.

Использование font-display

Прежде чем подробно разобрать различные функции font-display, давайте быстро взглянем, как использовать его в CSS. Прежде всего, font-display не является свойством CSS. Как было сказано в начале, это дескриптор правила @font-face. (пример):

В этом коде я задаю значение swap для шрифта Saira Condensed. Все возможные значения: auto, block, swap, fallback, optional

Значение по умолчанию для font-display – auto.

В следующих разделах я подробно разберу все эти значения. Но сначала давайте обсудим временной период, с помощью которого браузер рендерит шрифт. В разборе значений я объясню различные аспекты таймлайна, а также как они ведут себя с каждым значением.

Таймлайн font-display

В основе этой функции лежит концепция таймлайна font-display. Время загрузки шрифта, которое начинается от его запроса и кончается либо успешной загрузкой, либо провалом, можно разделить на три последовательных периода, которые говорят браузеру, как рендерить текст. Три периода:

Блочный период. В этом периоде браузер рендерит текст невидимым фолбек шрифтом. Если запрошенный шрифт загружается, текст перерисовывается с этим шрифтом. Невидимый фолбек шрифт ведет себя, как пустой плейсхолдер для текста. Таким образом, минимизируются сдвиги макета при повторном рендеринге.

Период подмены: если необходимый шрифт еще не доступен, используется фолбек шрифт. Только в этот раз текст уже отображается. Шрифт будет задействован, как только он подгрузится.

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

Настройка продолжительности таких периодов позволяет конфигурировать кастомную стратегию рендера текста. В частности, эти значения можно установить в 0 или в бесконечность, что я покажу в следующих разделах.

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

Давайте рассмотрим, как все эти значения управляют загрузкой и отображением шрифтов.

font-display: auto

После короткого блокового периода это значение увеличивает период подмены до бесконечности (в спецификации рекомендуют 3 секунды). В таком случае период отказа отсутствует.

Браузер короткое время ждет шрифт и рендерит текст невидимым шрифтом. Далее если шрифт не доступен, фолбек шрифт становится видимым. Как только завершается загрузка запрошенного шрифта, браузер повторно рендерит текст.

Описанное поведение показано в видео ниже, где используется простая тестовая страница со специальным шрифтом в заголовке:

В начале загрузки страницы заголовок невидим, но он присутствует в DOM. Примерно через 3 секунды если шрифт все еще не доступен, текста становится видимым с фолбек шрифтом. В демо видео я имитирую слабое соединение с помощью панели разработчика Chrome. Как только шрифт загружается, заголовок повторно рендерится.

font-display: swap

С этим значением блоковый период сжимается до 0, а период подмены достигает бесконечности. Здесь также отсутствует период отказа. Другими словами, браузер не ждет шрифт и сразу рендерит текст с фолбек шрифтом. Как только шрифт загружается, текст рендерится заново. Давайте проверим:

font-display: fallback

Это первое значение, в котором есть период отказа. После очень короткого блокового периода (рекомендуется 100ms) наступает короткий период подмены (рекомендуется 3s). Если к концу этого времени шрифт все еще не готов, текст будет отображаться с фолбек шрифтом на все время посещения страницы. Посетителей не раздражают сдвиги в макете, которые могут снизить UX. В первом видео ниже шрифт загружается после более чем 6 секунд, поэтому он никогда не будет применен:

В следующем видео шрифт загружается быстрее до таймаута, поэтому шрифт используется, как ожидалось:

font-display: optional

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

requires для block

important для swap

preferable для fallback

Значение optional, скорее всего, не будет меняться. Оно и так отлично описывает поведение. С этим значением шрифт считается необязательным для рендера страницы, что говорит браузеру: «если шрифт уже доступен, используй его. Если нет, не так важно, используй фолбек шрифт. Шрифт может загрузиться к посещению будущих страниц».

С этим значением таймлайн имеет короткий блоковый период (рекомендуется 100ms) и нулевой период подмены. Таким образом, после блокового периода сразу наступает период отказа. Если шрифт не доступен, он не будет использоваться на этой странице. Шрифт может загружаться в фоновом режиме, и будет немедленно отрендерен при посещении будущих страниц.

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

В видео ниже тестовая страница загружается без имитации плохого соединения. Шрифт загружается быстро, но только после короткого блокового периода. Поэтому текст отображается с фолбек шрифтом на все время работы со страницей.

В следующем видео страница перезагружается с теми же настройками сети, но в этот раз включен кэш для имитации второго посещения:

И вот оно, теперь заголовок рендерится с ожидаемым шрифтом. Прежде чем продолжим, заметьте, что для блокового периода со значениями fallback и optional рекомендуется очень небольшая задержка в 100ms. Это позволяет кратковременно отображать быстро загруженный шрифт (или шрифт из кэша), прежде чем использовать фолбек шрифт. Таким образом, избегается эффект «мигания нестилизованного текста» или VYN/

Мне самому интересно, почему при font-display: swap блоковый период сжимается до 0, а не использует тот же короткий интервал, как для optional. Оказывается, в GitHub репозитории спецификации открыт баг, где сказано, что swap должен использовать небольшую задержку, как и остальные значения.

О фолбек шрифте

Выше я несколько раз упомянул фолбек шрифт. Но откуда он берется? Фолбек шрифт – первый доступный для представления шрифт в стеке шрифтов, который задается с помощью свойства font-family на элементе. Например, на тестовой странице значение font-family для заголовка:

Это можно проверить (см. видео выше для optional), например, на windows, которая использует для рендера шрифта Arial.

Поддержка

На момент написания статьи дескриптор font-display обладает следующей поддержкой:

Chrome 60+

Opera 47+

Для Firefox в разработке, с версии 46 доступен по флагу

Для Safari статус Webkit утверждает, что дескриптор в разработке

О скорой поддержке в Microsoft Edge говорить не приходится. На сайте Microsoft Edge Developer Feedback есть ticket, где можно проголосовать для реализацию этой функции

Обратитесь к caniuse.com для получения последних сведений о поддержке.

Стоит отметить, что поддержку font-display нельзя протестировать с помощью функциональных запросов. Как было сказано выше, это не свойство CSS, а дескриптор. В баге на GitHub вы найдете, как правильно обнаружить эту функцию.

Если вы определили, что font-display не поддерживается, можно применить несколько фолбек стратегий, но они выходят за рамки этой статьи. В статье Zach Leatherman «полное руководство по стратегиям загрузки шрифтов» представлен исчерпывающий опрос по доступным решениям.

Использование с Google Fonts

Вы могли заметить, что в демо используется шрифт с Google Fonts, но он загружается по-другому (ссылка на стили провайдера шрифта). Вместо этого я просто скопировал URL шрифта из стилей и использовал его в моем кастомном правиле @font-face. Мне пришлось сделать это, так как font-display должен задаваться внутри правила font-face.

Есть ли другой, более Google Fonts-friendly способ? Будут ли Google Fonts и другие сторонние хостинги поддерживать font-display?

В репозитории Google Fonts GitHub открыт баг с этим обсуждением. Поставьте +1, чтобы показать свою заинтересованность!

Также стоит сказать, что CSS Fonts Module Level 4 предлагает использовать font-display в качестве дескриптора для @font-feature-values, что даст разработчикам возможность устанавливать политику отображения правил @font-face, которые напрямую не контролируются. Это еще не реализовано ни в одном браузере.

Заключительные слова

Надеюсь, статья дала вам полный обзор дескриптора font-display, а также убедила в светлом будущем рендера шрифтов в вебе.

В этой статье не обсуждались специальные случаи использования для разных стратегий font-display, однако в спецификации иллюстрируются эти кейсы с понятными примерами. По этой теме разбирается несколько цитируемых ссылок. Помимо основ в этой статье вы можете поискать информацию в предоставленных мной ссылках.

Автор: Giulio Mainardi

Источник: //www.sitepoint.com/

Редакция: Команда webformyself.

Метки:

Похожие статьи:

Комментарии Вконтакте: