Catalina добавляет в macOS новый единый переменный системный шрифт.
Раздел «system-ui» спецификации CSS Fonts Module Level 4 определяет ключевое слово шрифта system-ui
, которое позволяет разработчикам использовать встроенный, оптимизированный для турбонаддува, локализованный, высококачественный, не требующий загрузки шрифт операционной системы по умолчанию прямо на своих сайтах и в приложениях.
body {
font-family: system-ui;
}
Такой выбор типографики равносилен высказыванию «использовать системный шрифт по умолчанию для текущего местоположения этого пользователя».
В macOS system-ui
является San Francisco — шрифт, который команда дизайнеров проверила, протестировала и… недавно обновила! Сначала мы рассмотрим новые интересные функции вариативных шрифтов в Catalina , а затем рассмотрим несколько ошибок и то, как их решили инженеры Chromium .
В этой статье предполагается, что вы уже знакомы с вариативными шрифтами. Если нет, ознакомьтесь со статьей «Введение в вариативные шрифты в интернете» и видео ниже.
Совместимость с браузерами
На момент написания статьи system-ui
поддерживается в Chromium (с версии 56), Edge (с версии 79), Safari (с версии 11) и Firefox (с версии 43), но с ключевым словом -apple-system
. Обновления см. в разделе «Можно ли использовать переменные шрифты?» .
Новые полномочия
Новые возможности, которые Catalina привнесла в системный шрифт, теперь доступны веб-разработчикам, начиная с Chromium 83. Шрифт system-ui
теперь имеет больше переменных настроек : оптическое изменение размера и 2 уникальные настройки насыщенности:
h1 { font-family: system-ui; font-weight: 700; font-variation-settings: 'wght' 750 ; }
h1 { font-family: system-ui; font-weight: 700; font-variation-settings: 'wght' 750, 'opsz' 20, 'GRAD' 400, 'YAXS' 400 ; }
В Mojave system-ui
— это вариативный шрифт с настройками только wght
. В Catalina system-ui
— это вариативный шрифт с настройками wght
, opsz
, GRAD
и YAXS
.
Мне кажется, это несколько интересных возможностей для прогрессивного улучшения дизайна! Если хотите, действительно изучите тонкости системного шрифта.
wght
Принимает толщину шрифта от 0
до 900
и применяется одинаково ко всем символам.
/* 0-900 */
font-variation-settings: 'wght' 750;
opsz
Оптическая калибровка похожа на кернинг или межбуквенный интервал, но интервал определяется человеческим глазом, а не математически. Значение 19
и ниже предназначено для интервала в тексте и основном тексте, а значение 20
и выше — для интервала в заголовках и названиях.
/* 19 or 20 */
font-variation-settings: 'opsz' 20;
GRAD
Аналогично весу, но без учёта горизонтального интервала. Принимает значения от 400
до 1000
.
/* 400-1000 */
font-variation-settings: 'GRAD' 500;
YAXS
Растягивает глиф по вертикали. Принимает значения от 400
до 1000
.
/* 400-1000 */
font-variation-settings: 'YAXS' 500;
Комбинирование вариантов
С помощью нескольких строк CSS мы можем изменить настройки шрифта, установив жирный шрифт по своему выбору или попробовать другие интересные комбинации:
font-weight: 700;
font-weight: bold;
font-variation-settings: 'wght' 750, 'YAXS' 600, 'GRAD' 500, 'opsz' 20;
И вот так пользователи Chromium на macOS видят ваш обновленный, индивидуальный вес 750 с некоторыми другими интересными изменениями 👍
В macOS 10.15 появились новые функции системного шрифта, а в системе отслеживания ошибок Chromium была зафиксирована сложная ошибка system-ui
интерфейса. Интересно, связаны ли они между собой?
Приложение: Регрессия system-ui
Эта история начинается с другой ошибки: #1005969 . Она была обнаружена в macOS 10.15, поскольку интервал между шрифтами system-ui
выглядел узким и перегруженным.

Фон
Вы когда-нибудь замечали, как в macOS 10.14 ваши абзацы или заголовки «привязываются» к другому шрифту при увеличении или уменьшении размера?
В Mojave (macOS 10.14) шрифт system-ui
переключался между двумя шрифтами в зависимости от целевого размера. При размере текста менее 20px
macOS использовала шрифт «San Francisco Text». При размере текста 20px
и более macOS использовала шрифт «San Francisco Display». Оптическое изменение размера было статически реализовано в двух отдельных шрифтах.
В Catalina (macOS 10.15) появился новый объединённый вариативный шрифт для San Francisco. Больше нет необходимости управлять разделами «Текст» и «Отображение». Также появилась новая настройка вариаций opsz
описанная ранее.
h1 {
font-variation-settings: 'opsz' 20;
}
К сожалению, значение opsz
по умолчанию в новом шрифте Catalina равно 20
, и разработчики Chromium не были готовы применить opsz
к системному шрифту. Это привело к тому, что шрифты меньшего размера отображались слишком узко.
Чтобы исправить это, Chromium нужно было правильно применить opsz
к системному шрифту. Это привело к исправлению ошибки № 1005969. Победа! Или…?
Пока не сделано
Вот тут-то и возникла сложность: Chromium применил opsz
но что-то всё равно выглядело не так. Системные шрифты на Mac имеют дополнительную таблицу шрифтов trak
, которая корректирует горизонтальный интервал. Работая над исправлением, инженеры Chromium заметили, что в macOS при получении горизонтальных метрик из объекта CTFontRef
метрики trak
уже учитывались в результатах. Библиотеке формирования шрифтов Chromium HarfBuzz
нужны метрики, в которых значения trak
ещё не учитываются.

Skia (графическая библиотека, а не одноимённый шрифт) использует как класс CGFontRef
из CoreGraphics
, так и класс CTFontRef
из CoreText
. Из-за необходимости внутренних преобразований между этими объектами (используемых для обеспечения обратной совместимости и доступа к необходимым API обоих классов) при определённых обстоятельствах Skia теряла информацию о весе, и полужирные шрифты переставали работать. Это было отмечено в проблеме № 1057654 .
Skia по-прежнему должна поддерживать macOS 10.11, поскольку Chromium её всё ещё поддерживает. В версии 10.11 шрифты «San Francisco Text» и «San Francisco Display» даже не были вариативными. Каждый из них представлял собой семейство отдельных шрифтов для каждой доступной насыщенности. В какой-то момент их идентификаторы глифов рассинхронизировались. Поэтому, если Skia формировала текст (преобразовывала текст в глифы, которые можно было бы отобразить) с помощью «San Francisco Text», то при отображении с помощью «San Francisco Display» это была бы полная ерунда, и наоборот. И даже если Skia просто запросит другой размер, macOS может переключиться на другой. Должно быть возможно всегда использовать один из шрифтов и просто масштабировать его (используя матрицу для увеличения вместо запроса большего размера), но у CoreText
есть проблема: он не увеличивает (только уменьшает) глифы sbix (цветные эмодзи). Всё немного сложнее. Похоже, CoreText
ограничивает вертикальный размер после применения матрицы, что, по-видимому, связано с тем, что он не может отображать эмодзи под углом 45 градусов. В любом случае, если вы хотите, чтобы ваши эмодзи отображались крупными, вам нужно сделать копию шрифта для получения увеличенной версии.
Итак, чтобы создать копии объектов CTFont
разных размеров внутри себя, гарантируя при этом использование одних и тех же базовых данных шрифта, Chromium извлек CGFont
из CTFont
, а затем создал новый CTFont
из CGFont
(объекты CGFont
не зависят от размера, магическое переключение происходит на уровне CoreText
). Это работало нормально до версии 10.154. В 10.15 этот цикл обработки закончился потерей слишком большого количества информации, что привело к проблеме с весом. Flutter заметил проблему с весом , и было сделано альтернативное исправление для изменения размера, чтобы создавать новый CTFont
непосредственно из исходного CTFont
, управляя оптическим размером напрямую с помощью старого, но недокументированного атрибута в CoreText
. Это поддерживает работу в 10.11 и устраняет другие проблемы (например, явную установку оптического размера на значение по умолчанию).
Однако это сохраняет большую часть «магии» CoreText
в шрифте. Похоже, одна из причин заключается в том, что он всё же каким-то образом корректирует перемещение глифов, помимо таблицы trak
(применение которой Chromium уже пытался подавить с помощью ещё одного недокументированного атрибута).
CGFont
не делает ничего из этого «волшебства», так что, возможно, Chromium мог бы отделить CGFont
от CTFont
и просто использовать его для получения улучшений? К сожалению, это не сработает, поскольку CoreText
известен тем, что изменяет шрифты и другими способами. Например, он делает маленькие эмодзи чуть больше, чем вы запросили (немного увеличивая их размер). CGFont
об этом не знает, поэтому ваши эмодзи на основе sbix окажутся слишком близко друг к другу, поскольку вы будете использовать один размер, а CoreText
будет отображать их немного крупнее. Chromium действительно нужны улучшения CTFont
, но без отслеживания, и желательно без каких-либо других манипуляций.
Поскольку для исправления проблемы с пробелами требовался набор взаимосвязанных исправлений Blink и Skia, инженеры Chromium не могли просто вернуться к предыдущей версии, чтобы исправить проблему. Они также попробовали использовать другой флаг сборки для изменения кодового пути, связанного со шрифтами, в Skia, что решило проблему с жирным шрифтом, но ухудшило проблему с пробелами.
Исправление
В конце концов, Chromium, конечно же, решил исправить и то, и другое. Теперь Chromium использует встроенные функции HarfBuzz для измерения метрик шрифтов OpenType, чтобы получать горизонтальные метрики непосредственно из двоичных данных в системных таблицах шрифтов. Благодаря этому Chromium обходит CoreText
и Skia, когда у шрифта есть таблица trak
(за исключением случаев, когда это шрифт эмодзи).

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