Улучшены резервные шрифты

Кэти Хемпениус
Katie Hempenius

Краткое содержание

Эта статья представляет собой глубокое погружение в резервные варианты шрифтов и API-интерфейсы size-adjust , ascent-override , descent-override и line-gap-override . Эти API позволяют использовать локальные шрифты для создания резервных шрифтов, которые точно или близко соответствуют размерам веб-шрифта. Это уменьшает или устраняет сдвиги макета, вызванные заменой шрифтов.

Если вы предпочитаете пропустить чтение этой статьи, вот некоторые инструменты, которые вы можете использовать, чтобы немедленно начать использовать эти API:

Инструменты фреймворка:

  • @next/font : Начиная с версии Next 13, next/font автоматически использует переопределения метрики шрифта и size-adjust , чтобы обеспечить соответствующие резервные варианты шрифта.
  • @nuxtjs/fontaine : Начиная с Nuxt 3, вы можете использовать nuxt/fontaine для автоматического создания и вставки соответствующих резервных шрифтов в таблицы стилей, используемые вашим приложением Nuxt.

Нефреймворковые инструменты:

  • Fontaine : Fontaine — это библиотека, которая автоматически генерирует и вставляет резервные варианты шрифтов, использующие переопределения метрики шрифта.
  • Этот репозиторий содержит переопределения показателей шрифтов для всех шрифтов, размещенных в Google Fonts. Эти значения можно скопировать и вставить в ваши таблицы стилей.

Фон

Резервный шрифт — это шрифт, который используется, когда основной шрифт еще не загружен или в нем отсутствуют глифы , необходимые для отображения содержимого страницы. Например, приведенный ниже CSS указывает, что семейство шрифтов sans-serif следует использовать в качестве резервного шрифта для "Roboto" .

font-family: "Roboto" , sans-serif;

Резервные шрифты можно использовать для более быстрого рендеринга текста (то есть с помощью font-display: swap ). В результате содержимое страницы становится читабельным и полезным раньше, однако исторически это происходило за счет нестабильности макета: сдвиги макета обычно происходят, когда резервный шрифт заменяется веб-шрифтом. Однако новые API, обсуждаемые ниже, могут уменьшить или устранить эту проблему, позволяя создавать резервные шрифты, которые занимают тот же объем места, что и их аналог веб-шрифта.

Улучшены резервные шрифты

Существует два возможных подхода к созданию «улучшенных» резервных шрифтов. Более простой подход использует только API переопределения метрики шрифта. Более сложный (но более мощный) подход использует как API переопределения метрики шрифта, так и size-adjust . В этой статье объясняются оба этих подхода.

Как работают переопределения показателей шрифта

Введение

Переопределение метрики шрифта позволяет переопределить подъем, спуск и межстрочный интервал шрифта:

  • Подъем измеряет наибольшее расстояние, на которое глифы шрифта выходят за базовую линию.
  • Спуск измеряет наибольшее расстояние, на которое глифы шрифта простираются ниже базовой линии.
  • Межстрочный разрыв , также называемый «интерлиньяж», измеряет расстояние между последовательными строками текста.

Диаграмма, показывающая подъем, спуск и разрыв строки.

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

Переопределения показателей шрифта используются в таблице стилей следующим образом:

body {
    font-family: Poppins, "fallback for poppins";
}

@font-face {
    font-family: "fallback for poppins";
    src: local("Times New Roman");
    ascent-override: 105%;
    descent-override: 35%;
    line-gap-override: 10%;
}

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

Вычисление переопределений показателей шрифта

Следующие уравнения дают переопределение показателей шрифта для данного веб-шрифта. Значения переопределений показателей шрифта следует записывать в процентах (например, 105% ), а не в десятичных дробях.

ascent-override = ascent/unitsPerEm
descent-override = descent/unitsPerEm
line-gap-override = line-gap/unitsPerEm

Например, это переопределения показателей шрифта для шрифта Poppins :

/*
Poppins font metrics:
ascent = 1050
descent = 350
line-gap = 100
UPM: 1000
*/

ascent-override: 105%;  /* = 1050/1000 */
descent-override: 35%;  /* = 350/1000 */
line-gap-override: 10%; /* = 100/1000 */

Значения ascent , descent , line-gap и unitsPerEm берутся из метаданных веб-шрифта. В следующем разделе этой статьи объясняется, как получить эти значения.

Чтение таблиц шрифтов

Метаданные шрифта (в частности, его таблицы шрифтов ) содержат всю информацию, необходимую для расчета переопределений показателей шрифта.

Снимок экрана: диалоговое окно «Информация о шрифте» в FontForge. В диалоговом окне отображаются такие показатели шрифта, как «Typo Ascent», «Typo Descent» и «Typo Line Gap».
Использование FontForge для просмотра метаданных шрифта

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

  • Fontkit — это движок шрифтов, созданный для Node.js. В этом фрагменте кода показано, как использовать FontKit для расчета переопределений показателей шрифта.
  • Capsize — это библиотека размеров и макетов шрифтов. Capsize предоставляет API для получения информации о различных показателях шрифта.
  • Fontdrop.info — это веб-сайт, который позволяет просматривать таблицы шрифтов и другую информацию, связанную со шрифтами, в браузере.
  • Font Forge — популярный редактор шрифтов для настольных компьютеров. Чтобы просмотреть ascent , descent и line-gap : откройте диалоговое окно Font Info , выберите меню OS/2 , затем выберите вкладку Metrics . Чтобы просмотреть UPM : откройте диалоговое окно Font Info , затем выберите меню General .

Понимание таблиц шрифтов

Вы можете заметить, что такие понятия, как «восхождение», обозначаются несколькими метриками — например, существуют метрики hheaAscent , typoAscent и winAscent . Это результат того, что разные операционные системы используют разные подходы к рендерингу шрифтов: программы на устройствах OSX обычно используют метрики шрифтов hhea* , тогда как программы на устройствах Windows обычно используют метрики шрифтов typo* (также называемые sTypo* ) или win* .

В зависимости от шрифта, браузера и операционной системы шрифт будет отображаться с использованием метрик hhea , typo или win .

Мак Окна
Хром Использует метрики из таблицы «hhea». Использует метрики из таблицы «опечатка», если установлено «USE_TYPO_METRICS», в противном случае используются метрики из таблицы «выигрыш».
Firefox Использует метрики из таблицы «typo», если установлено «USE_TYPO_METRICS», в противном случае используются метрики из таблицы «hhea». Использует метрики из таблицы «опечатка», если установлено «USE_TYPO_METRICS», в противном случае используются метрики из таблицы «выигрыш».
Сафари Использует метрики из таблицы «hhea». Использует метрики из таблицы «опечатка», если установлено «USE_TYPO_METRICS», в противном случае используются метрики из таблицы «выигрыш».

Дополнительную информацию о том, как метрики шрифтов работают в разных операционных системах, можно найти в этой статье о вертикальных метриках .

Совместимость между устройствами

Для подавляющего большинства шрифтов (например, ~90% шрифтов, размещенных на Google Fonts) переопределения метрик шрифта можно безопасно использовать, не зная операционной системы пользователя: другими словами, для этих шрифтов значения ascent-override , descent-override и linegap-override остаются одинаковыми независимо от того, применяются ли метрики hhea , typo или win . В этом репозитории содержится информация о том, к каким шрифтам это применимо, а к каким нет.

Если вы используете шрифт, который требует использования отдельных наборов переопределений показателей шрифта для устройств OSX и Windows, использование переопределений показателей шрифта и size-adjust рекомендуется только в том случае, если у вас есть возможность изменять таблицы стилей в зависимости от операционной системы пользователя.

Использование переопределений показателей шрифта

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

body {
  font-family: "Poppins", "fallback for Poppins", "another fallback for Poppins";
}

@font-face {
  font-family: "fallback for Poppins";
  src: local("Arial");
  ascent-override: 105%;
  descent-override: 35%;
  line-gap-override: 10%;
}

@font-face {
  font-family: "another fallback for Poppins";
  src: local("Roboto");
  ascent-override: 105%;
  descent-override: 35%;
  line-gap-override: 10%;
}

Как работает регулировка размера

Введение

Дескриптор CSS size-adjust пропорционально масштабирует ширину и высоту глифов шрифта. Например, size-adjust: 200% масштабирует глифы шрифта в два раза по сравнению с их исходным размером; size-adjust: 50% масштабирует глифы шрифта до половины их исходного размера.

Диаграмма, показывающая результаты использования «регулировки размера: 50%» и «регулировки размера: 200%».

Сама по себе size-adjust имеет ограниченное применение для улучшения резервных шрифтов: в большинстве случаев резервный шрифт необходимо слегка сузить или расширить (а не масштабировать пропорционально), чтобы он соответствовал веб-шрифту. Однако сочетание size-adjust с переопределением метрики шрифта позволяет сделать так, чтобы любые два шрифта соответствовали друг другу как по горизонтали, так и по вертикали.

Вот как size-adjust используется в таблицах стилей:

@font-face {
  font-family: "fallback for poppins";
  src: local("Arial");
  size-adjust: 60.85099821%;
  ascent-override: 164.3358416%;
  descent-override: 57.51754455%;
  line-gap-override: 16.43358416%;
}

Из-за того, как рассчитывается size-adjust (который объясняется в следующем разделе), значение size-adjust (и соответствующие переопределения метрики шрифта) изменяются в зависимости от того, какой резервный шрифт используется:

body {
  font-family: "Poppins", "fallback for Poppins", "another fallback for Poppins";
}

@font-face {
  font-family: poppins-fallback;
  src: local("Arial");
  size-adjust: 60.85099821%;
  ascent-override: 164.3358416%;
  descent-override: 57.51754455%;
  line-gap-override: 16.43358416%;
}

@font-face {
  font-family: poppins-fallback-android;
  src: local("Roboto");
  size-adjust: 55.5193474%:
  ascent-override: 180.1173909%;
  descent-override: 63.04108683%;
  line-gap-override: 18.01173909%;
}

Вычисление переопределения параметров размера и шрифта

Это уравнения для расчета size-adjust и переопределения показателей шрифта:

size-adjust = avgCharacterWidth of web font / avgCharacterWidth of fallback font
ascent-override = web font ascent / (web font UPM * size-adjust)
descent-override = web font descent / (web font UPM * size-adjust)
line-gap-override = web font line-gap / (web font UPM * size-adjust)

Большинство этих входных данных (то есть подъем, спуск и межстрочный разрыв) можно прочитать непосредственно из метаданных веб-шрифта. Однако avgCharacterWidth необходимо аппроксимировать.

Приблизительная средняя ширина символа

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

Пример простого подхода к вычислению avgCharacterWidth — взять среднюю ширину всех символов [az\s] .

График сравнения ширины отдельных символов Roboto [a-zs].
Ширина символов Roboto

Однако одинаковое взвешивание всех символов, скорее всего, приведет к уменьшению ширины часто используемых букв (например, e ) и увеличению ширины редко используемых букв (например, z ).

Более сложный подход, повышающий точность, состоит в том, чтобы принять во внимание частоту букв и вместо этого вычислить средневзвешенную по частоте ширину символов [az\s] . Эта статья является хорошим справочником по частоте букв и средней длине слов в английских текстах.

График, показывающий частоту букв в английском языке.
Частота букв в английском языке

Выбор подхода

Каждый из двух подходов, обсуждаемых в этой статье, имеет свои преимущества и недостатки:

  • Использование переопределений показателей шрифта само по себе является хорошим подходом, если вы только начинаете оптимизировать резервные шрифты. Хотя это более простой из двух подходов, он обычно достаточно мощный, чтобы заметно уменьшить величину изменений макета, связанных со шрифтами.

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

Выбор резервных шрифтов

Методы, описанные в этой статье, основаны на использовании переопределений метрики шрифта и size-adjust для преобразования широко доступных локальных шрифтов, а не на попытках найти локальный шрифт, который максимально приближен к веб-шрифту. При выборе локальных шрифтов важно помнить, что очень немногие шрифты широко доступны на местном уровне, и ни один шрифт не будет существовать на всех устройствах.

Arial — рекомендуемый запасной шрифт для шрифтов без засечек, а Times New Roman — рекомендуемый запасной шрифт для шрифтов с засечками. Однако ни один из этих шрифтов недоступен на Android ( Roboto — единственный системный шрифт на Android).

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

body {
  font-family: "Poppins", poppins-fallback, poppins-fallback-android, sans-serif;
}

/*
Poppins font metrics:
- ascent = 1050
- descent = 350
- line-gap = 100
- UPM: 1000
AvgCharWidth:
- Poppins: 538.0103768
- Arial: 884.1438804
- Roboto: 969.0502537
*/

@font-face {
  font-family: poppins-fallback;
  src: local("Arial");
  size-adjust: 60.85099821%;
  ascent-override: 164.3358416%;
  descent-override: 57.51754455%;
  line-gap-override: 16.43358416%;
}

@font-face {
  font-family: poppins-fallback-android;
  src: local("Roboto");
  size-adjust: 55.5193474%:
  ascent-override: 180.1173909%;
  descent-override: 63.04108683%;
  line-gap-override: 18.01173909%;
}

Запрос обратной связи

Если у вас есть какие-либо отзывы о вашем опыте использования переопределения показателей шрифта и size-adjust , свяжитесь с нами.