Catalina는 macOS에 새로운 통합 가변 시스템 글꼴을 도입합니다.
CSS 글꼴 모듈 레벨 4 사양의 'system-ui' 섹션에서는 개발자가 사이트와 앱에서 바로 기본 운영체제 글꼴을 사용할 수 있는 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
키워드가 사용됩니다. 업데이트는 가변 글꼴을 사용할 수 있나요?를 참고하세요.
새로운 힘
이제 Chromium 83부터 Catalina에서 시스템 글꼴에 도입된 새로운 기능을 웹 개발자가 사용할 수 있습니다. 이제 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;
이렇게 하면 macOS의 Chromium 사용자에게 업그레이드된 맞춤 750 가중치가 다른 재미있는 조정과 함께 표시됩니다 👍
macOS 10.15에서는 시스템 글꼴에 새로운 기능이 추가되었으며, macOS 10.15에서는 Chromium 버그 추적기에 까다로운 system-ui
버그가 기록되었습니다. 이 둘이 관련이 있을까요?
부록: system-ui
회귀
이 이야기는 다른 버그(#1005969)로 시작됩니다. system-ui
글꼴 간격이 좁고 빽빽해 보인다는 이유로 macOS 10.15에서 신고되었습니다.

배경
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;
}
아쉽게도 새 Catalina 글꼴의 기본 opsz
값은 20
이며 Chromium 엔지니어는 opsz
를 시스템 글꼴에 적용할 준비가 되어 있지 않았습니다. 이로 인해 작은 크기가 너무 좁게 표시되었습니다.
이 문제를 해결하려면 Chromium이 시스템 글꼴에 opsz
를 올바르게 적용해야 했습니다. 이로 인해 문제 #1005969가 해결되었습니다. 승리! 아니면…
아직 완료되지 않음
여기서 문제가 발생했습니다. Chromium이 opsz
를 적용했지만 여전히 뭔가 잘못된 것 같았습니다. Mac의 시스템 글꼴에는 가로 간격을 조정하는 trak
이라는 추가 글꼴 테이블이 있습니다. 수정 작업을 진행하는 동안 Chromium 엔지니어는 macOS에서 CTFontRef
객체에서 가로 측정항목을 가져올 때 trak
측정항목이 이미 측정항목 결과에 반영되고 있음을 확인했습니다. Chromium의 셰이핑 라이브러리 HarfBuzz
에는 trak
값이 아직 반영되지 않은 측정항목이 필요합니다.

내부적으로 Skia (동일한 이름의 서체가 아닌 그래픽 라이브러리)는 CoreGraphics
의 CGFontRef
클래스와 CoreText
의 CTFontRef
클래스를 모두 사용합니다. 이러한 객체 간에 필요한 내부 변환 (이전 버전과의 호환성을 유지하고 두 클래스에서 필요한 API에 액세스하는 데 사용됨)으로 인해 특정 상황에서 Skia가 두께 정보를 잃고 굵은 글꼴이 작동하지 않습니다. 이 문제는 문제 #1057654에서 추적되었습니다.
Chromium에서 여전히 지원하므로 Skia는 macOS 10.11을 계속 지원해야 합니다. 10.11에서는 'San Francisco Text' 및 'San Francisco Display' 글꼴이 가변 글꼴이 아니었습니다. 대신, 각 글꼴은 사용 가능한 모든 두께에 대해 별도의 글꼴 모음이었습니다. 어느 시점부터 글리프 ID가 서로 동기화되지 않았습니다. 따라서 Skia가 'San Francisco Text'로 텍스트 셰이핑 (그릴 수 있는 글리프로 텍스트 변환)을 한 경우 'San Francisco Display'로 그리면 의미가 없어지고 그 반대의 경우도 마찬가지입니다. Skia가 다른 크기를 요청하더라도 macOS가 다른 크기로 전환될 수 있습니다. 항상 글꼴 중 하나를 사용하고 크기를 조정할 수 있어야 합니다 (더 큰 크기를 요청하는 대신 행렬을 사용하여 크기를 조정). 하지만 CoreText
에는 sbix (컬러 그림 이모티콘) 글리프가 위로 조정되지 않는 (아래로만 조정됨) 문제가 있습니다. 그보다 약간 더 복잡합니다. CoreText
는 실제로 매트릭스 적용 후 세로 범위를 제한하는 것으로 보이며, 이는 45도 각도로 그림 이모티콘을 그릴 수 없는 것과 관련이 있는 것으로 보입니다. 어떤 경우든 그림 이모티콘을 크게 표시하려면 글꼴을 복사하여 큰 버전을 만들어야 합니다.
따라서 동일한 기본 글꼴 데이터가 사용되도록 하면서 내부적으로 다양한 크기의 CTFont
객체를 만들려면 Chromium이 CTFont
에서 CGFont
을 가져온 다음 CGFont
에서 새 CTFont
을 만들었습니다 (CGFont
객체는 크기에 독립적이며, 마법 같은 전환은 CoreText
수준에서 발생함). 10.154까지는 문제가 없었습니다. 10.15에서는 이 왕복으로 인해 정보가 너무 많이 손실되어 가중치 문제가 발생했습니다. Flutter에서 가중치 문제를 발견했으며, CoreText
의 오래되었지만 문서화되지 않은 속성을 사용하여 광학 크기를 직접 제어하면서 원래 CTFont
에서 직접 새 CTFont
를 만드는 크기 조절을 위한 대체 수정사항이 적용되었습니다. 이렇게 하면 10.11에서 작동하고 광학 크기를 기본값으로 명시적으로 설정하는 등의 다른 문제가 해결됩니다.
하지만 이렇게 하면 글꼴에 CoreText
'마법'이 더 많이 보존됩니다. 이러한 문제 중 하나는 trak
테이블 (Chromium이 아직 문서화되지 않은 다른 속성을 통해 이미 억제하려고 시도한 테이블) 외에 다른 방식으로 글리프 전진을 여전히 조정하는 것으로 보입니다.
CGFont
는 이러한 '마법'을 수행하지 않으므로 Chromium이 CTFont
에서 CGFont
를 가져와서 고급 기능을 얻는 데 사용할 수 있을까요? CoreText
는 다른 방식으로도 글꼴을 망치는 것으로 알려져 있으므로 이 방법은 작동하지 않습니다. 예를 들어 실제로 요청한 것보다 약간 더 큰 이모티콘을 만듭니다 (크기를 약간 늘림). CGFont
는 이를 알지 못하므로 한 크기로 측정하지만 CoreText
는 일정량 더 크게 그리므로 sbix 기반 이모티콘이 서로 너무 가까워집니다. Chromium은 CTFont
의 발전을 원하지만 추적 없이, 그리고 다른 혼란 없이 이를 원합니다.
간격 문제를 수정하려면 상호 연결된 Blink 및 Skia 수정사항이 필요했기 때문에 Chromium 엔지니어는 문제를 수정하기 위해 '단순히 되돌릴' 수 없었습니다. Chromium 엔지니어는 Skia에서 글꼴 관련 코드 경로를 변경하기 위해 다른 빌드 플래그를 사용해 보기도 했습니다. 이 방법으로 굵은 글꼴 문제는 해결되었지만 간격 문제가 회귀되었습니다.
수정
결국 Chromium은 두 가지 모두 수정하고 싶어 했습니다. 이제 Chromium은 시스템 글꼴의 글꼴 테이블에 있는 바이너리 데이터에서 가로 측정항목을 직접 가져오기 위해 HarfBuzz 내장 글꼴 OpenType 글꼴 측정항목 함수를 사용합니다. 이를 통해 글꼴에 trak
테이블이 있는 경우 (그림 이모티콘 글꼴인 경우 제외) Chromium은 CoreText
및 Skia를 우회합니다.

그동안 Skia에서 이 문제를 완전히 수정하고 현재 HarfBuzz
를 통해 진행되는 수정 대신 Skia를 사용하여 시스템 글꼴 측정항목을 검색하는 방법을 추적하는 Skia 문제 #10123이 있습니다.