Catalina представляет в macOS новый шрифт единой системы переменных.
Раздел system-ui спецификации модуля CSS Fonts 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
теперь имеет больше переменных настроек : оптический размер и две уникальные настройки веса:
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
. В то время как system-ui
в Catalina — это переменный шрифт с настройками 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 с некоторыми другими забавными настройками 👍
Детская площадка
Нажмите «Ремикс для редактирования в сбое» ниже, чтобы получить редактируемую копию сбоя, а затем отредактируйте новые параметры font-variation-settings
, чтобы увидеть, как это повлияет на ваш шрифт. Помните, что этот глюк будет работать только в том случае, если вы используете устройство macOS Catalina.
В macOS 10.15 к системному шрифту добавлены новые функции, а в macOS 10.15 в system-ui
интерфейса. Интересно, они связаны!?
Приложение: Регрессия system-ui
Эта история начинается с другой ошибки: #1005969 . Об этом сообщалось в macOS 10.15, поскольку расстояние между шрифтами system-ui
выглядело узким и перегруженным.
![Сравнение двух абзацев со страницы группы в Facebook. Слева – Chrome, справа — Safari. Chrome неброский, но немного более узкий по пространству.](https://web.dev/static/articles/more-variable-font-options-in-chromium-83/image/a-comparison-two-paragra-c4d1b72fd8bdc.jpg?authuser=1&hl=ru)
Фон
Вы когда-нибудь замечали в macOS 10.14, как ваши абзацы или заголовки «привязывались» к другому шрифту при увеличении или уменьшении размера?
В Mojave (macOS 10.14) шрифт system-ui
переключался между двумя шрифтами в зависимости от целевого размера шрифта. Когда размер текста был менее 20px
, macOS использовала «Текст Сан-Франциско». Когда размер текста составлял 20px
и более, macOS использовала «Дисплей Сан-Франциско». Оптические размеры были встроены статически в два отдельных шрифта.
Catalina (macOS 10.15) выпустила новый единый вариативный шрифт для Сан-Франциско. Больше не нужно управлять «Текстом» и «Дисплей». Он также получил новый вариант настройки 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
еще не учтены.
![Отображение system-ui, всей его толщины и вариантов шрифта в списке. Половина из них не имеет весовых различий.](https://web.dev/static/articles/more-variable-font-options-in-chromium-83/image/a-display-system-ui-all-6299fdd54fff3.jpg?authuser=1&hl=ru)
Внутри Skia (графическая библиотека, а не одноименный шрифт) использует класс CGFontRef
из CoreGraphics
и класс CTFontRef
из CoreText
. Из-за необходимых внутренних преобразований между этими объектами (используемых для обеспечения обратной совместимости и доступа к необходимым API в обоих классах) Skia при определенных обстоятельствах теряла информацию о весе, а жирные шрифты переставали работать. Это было отслежено в выпуске № 1057654 .
Skia по-прежнему должна поддерживать macOS 10.11, поскольку Chromium по-прежнему поддерживает ее. 10 ноября шрифты «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 не могли «просто вернуться», чтобы решить проблему. Инженеры Chromium также попытались использовать другой флаг сборки для изменения кодового пути, связанного со шрифтами, в Skia, что решило проблему с жирными шрифтами, но устранило проблему с пробелами.
Исправление
В конце концов, Chromium, конечно, захотел исправить обе проблемы. Chromium теперь прибегает к использованию встроенных в HarfBuzz функций измерения шрифтов OpenType для получения горизонтальных показателей непосредственно из двоичных данных в таблицах шрифтов системного шрифта. Используя это, Chromium обходит CoreText
и Skia, когда шрифт имеет таблицу trak
(за исключением случаев, когда это шрифт emoji).
![Отображение system-ui, всей его толщины и вариантов шрифта в списке. Половина, которая раньше не работала, теперь выглядит великолепно.](https://web.dev/static/articles/more-variable-font-options-in-chromium-83/image/a-display-system-ui-all-f53cc76595e73.jpg?authuser=1&hl=ru)
Между тем, все еще существует проблема Skia № 10123, позволяющая отслеживать полное исправление этой проблемы в Skia и вернуться к использованию Skia для получения оттуда показателей системных шрифтов вместо текущего исправления, которое проходит через HarfBuzz
.