Catalina menghadirkan font sistem variabel united baru ke macOS.
Bagian'system-ui' pada spesifikasi Modul Font CSS Level 4 menentukan kata kunci font system-ui
yang memungkinkan developer menggunakan font sistem operasi default bawaan, dioptimalkan turbo, dilokalkan, berkualitas sangat tinggi, tidak perlu didownload, langsung di situs dan aplikasi mereka.
body {
font-family: system-ui;
}
Pilihan tipografi ini mirip dengan mengatakan "gunakan font sistem default untuk lokalitas pengguna saat ini."
Di macOS, font system-ui
adalah San Francisco, font yang telah diperiksa, diuji, dan... baru-baru ini oleh tim desain. Pertama, kita akan membahas fitur font variabel baru yang menarik di Catalina, lalu kita akan membahas beberapa bug dan cara engineer Chromium menyelesaikannya.
Postingan ini mengasumsikan bahwa Anda sudah memahami font variabel. Jika belum, lihat Pengantar font variabel di web dan video di bawah.
Kompatibilitas browser
Pada saat penulisan ini, system-ui
memiliki dukungan dari Chromium (sejak 56), Edge (sejak 79), Safari (sejak 11), dan dari Firefox (sejak 43), tetapi dengan kata kunci -apple-system
. Lihat Dapatkah saya menggunakan font variabel? untuk mengetahui info terbaru.
Kekuatan baru
Kemampuan baru yang dihadirkan Catalina ke font sistem kini tersedia untuk developer web mulai Chromium 83. Font system-ui
sekarang memiliki lebih banyak setelan variabel: ukuran optik dan 2 penyesuaian ketebalan yang unik:
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 ; }
Di Mojave, system-ui
adalah font variabel dengan hanya setelan wght
. Sedangkan system-ui
pada Catalina adalah font variabel dengan setelan wght
, opsz
, GRAD
, dan YAXS
.
Sepertinya saya bisa mendapatkan beberapa peluang {i>progressive enhancement<i} yang bagus. Pelajari seluk-beluk {i>font<i} sistem jika Anda mau.
wght
Menerima ketebalan font antara 0
dan 900
serta diterapkan secara merata untuk semua karakter.
/* 0-900 */
font-variation-settings: 'wght' 750;
opsz
Ukuran optik mirip dengan kerning atau spasi huruf, tetapi spasi dilakukan oleh mata manusia, bukan matematika. Nilai 19
atau lebih rendah ditujukan untuk spasi teks dan isi teks, sedangkan 20
atau lebih tinggi ditujukan untuk spasi header dan judul tampilan.
/* 19 or 20 */
font-variation-settings: 'opsz' 20;
GRAD
Mirip dengan berat, tetapi tanpa menyentuh spasi horizontal. Properti ini menerima nilai antara 400
dan 1000
.
/* 400-1000 */
font-variation-settings: 'GRAD' 500;
YAXS
Meregangkan glyph secara vertikal. Properti ini menerima nilai antara 400
dan 1000
.
/* 400-1000 */
font-variation-settings: 'YAXS' 500;
Menggabungkan opsi
Dengan beberapa baris CSS, kita dapat mengubah pengaturan font menjadi tebal pilihan kita atau mencoba kombinasi menarik lainnya:
font-weight: 700;
font-weight: bold;
font-variation-settings: 'wght' 750, 'YAXS' 600, 'GRAD' 500, 'opsz' 20;
Dengan begitu, pengguna Chromium di macOS melihat bobot 750 khusus Anda yang telah diupgrade dengan beberapa penyesuaian menyenangkan lainnya 👍
Taman Bermain
Klik Remix to Edit di Glitch di bawah untuk mendapatkan salinan Glitch yang dapat diedit, lalu edit opsi font-variation-settings
baru untuk melihat pengaruhnya terhadap font Anda. Perlu diingat bahwa Glitch ini hanya akan berfungsi jika Anda menggunakan perangkat macOS Catalina.
macOS 10.15 menambahkan fitur baru ke font sistemnya, dan di macOS 10.15, bug system-ui
yang rumit dicatat di pelacak bug Chromium. Apakah mereka terkait?
Lampiran: Regresi system-ui
Cerita ini dimulai dengan bug yang berbeda: #1005969. Hal ini dilaporkan terhadap macOS 10.15 karena spasi font system-ui
tampak sempit dan penuh.
Latar belakang
Apakah Anda pernah memperhatikan di macOS 10.14 bagaimana paragraf atau header Anda "dipaskan" ke {i>font<i} yang terlihat berbeda ketika ukurannya naik atau turun?
Di Mojave (macOS 10.14), font system-ui
beralih di antara dua font bergantung pada ukuran font target. Saat teks dalam format 20px
, macOS menggunakan "San Francisco Text". Saat teks adalah 20px
atau lebih, macOS menggunakan "San Francisco Display". Ukuran optik dibangun secara statis menjadi dua {i>font<i} terpisah.
Catalina (macOS 10.15) mengirimkan font variabel united baru untuk San Francisco. Tidak perlu lagi mengelola "Teks" dan "Tampilan". Versi ini juga mendapatkan setelan variasi baru opsz
yang dijelaskan sebelumnya.
h1 {
font-variation-settings: 'opsz' 20;
}
Sayangnya, nilai opsz
default dalam font Catalina baru adalah 20
, dan engineer Chromium tidak siap untuk menerapkan opsz
ke font sistem. Hal ini menyebabkan ukuran yang lebih kecil ditampilkan terlalu sempit.
Untuk memperbaikinya, Chromium perlu menerapkan opsz
dengan benar ke font sistem. Hal ini menyebabkan Masalah #1005969 diperbaiki. Kemenangan! Atau...?
Belum selesai
Di sini menjadi rumit: Chromium menerapkan opsz
, tetapi ada sesuatu yang tidak terlihat dengan baik. Font sistem di Mac memiliki tabel font tambahan yang disebut trak
, yang menyesuaikan spasi horizontal. Selagi melakukan perbaikan, engineer Chromium melihat bahwa di macOS, saat mengambil metrik horizontal dari objek CTFontRef
, metrik trak
sudah diperhitungkan dalam hasil metrik. Library pembentukan Chromium HarfBuzz
memerlukan metrik yang belum memperhitungkan nilai trak
.
Secara internal, Skia (library grafis, bukan jenis huruf dengan nama yang sama) menggunakan class CGFontRef
dari CoreGraphics
dan class CTFontRef
dari CoreText
. Karena konversi internal yang diperlukan di antara objek tersebut (digunakan untuk menjaga kompatibilitas mundur dan mengakses API yang diperlukan di kedua class), Skia akan kehilangan informasi berat dalam keadaan tertentu dan font tebal akan berhenti berfungsi. Hal ini dilacak dalam Masalah #1057654.
Skia masih perlu mendukung macOS 10.11 karena Chromium masih mendukungnya. Pada versi 10.11, font "San Francisco Text" dan "San Francisco Display" bahkan bukan font variabel. Sebaliknya, masing-masing merupakan kelompok {i>font<i} yang terpisah untuk setiap ketebalan yang tersedia. Pada titik tertentu, ID glyph mereka menjadi tidak sinkron. Jadi, jika Skia melakukan pembentukan teks (mengonversi teks menjadi glyph yang dapat digambar) dengan "Teks San Francisco", akan menjadi nonsens jika digambar dengan "Tampilan San Francisco", dan sebaliknya. Dan bahkan jika Skia hanya meminta ukuran macOS yang berbeda, mungkin akan beralih ke ukuran yang lain. Seharusnya Anda dapat selalu menggunakan salah satu font dan hanya menskalakannya (menggunakan matriks untuk meningkatkan skalanya, bukan meminta ukuran yang lebih besar). Namun, CoreText
memiliki masalah yang tidak akan menskalakan glyph sbix (emoji warna) ke atas (hanya ke bawah). Hal ini sedikit lebih rumit. CoreText
sebenarnya tampaknya membatasi tingkatan vertikal setelah penerapan matriks, yang tampaknya terkait dengan kemampuannya untuk menggambar emoji pada sudut 45 derajat. Apa pun itu, jika Anda ingin emoji ditampilkan berukuran besar, Anda harus membuat salinan font untuk mendapatkan versi yang besar.
Jadi, untuk membuat salinan objek CTFont
dengan ukuran yang berbeda secara internal sambil memastikan bahwa data font dasar yang sama digunakan, Chromium mengambil CGFont
dari CTFont
, lalu membuat CTFont
baru dari CGFont
(objek CGFont
tidak bergantung pada ukuran, pengalihan ajaib terjadi pada level CoreText
). Hal ini berfungsi dengan baik hingga 10.154. Pada 10.15 perjalanan dua arah ini akhirnya kehilangan terlalu banyak informasi, mengakibatkan masalah berat. Flutter melihat masalah berat dan perbaikan alternatif untuk pengubahan ukuran dilakukan untuk membuat CTFont
baru langsung dari CTFont
asli sambil mengontrol ukuran optik secara langsung menggunakan atribut lama tetapi tidak terdokumentasi di CoreText
. Ini membuat semuanya tetap berfungsi pada 10.11 dan memperbaiki masalah lainnya (seperti menyetel ukuran optik ke nilai default secara eksplisit).
Namun, tindakan ini mempertahankan lebih banyak 'magic' CoreText
dalam font. Salah satunya tampaknya kode tersebut masih menyesuaikan kemajuan glyph dengan cara tertentu selain hanya tabel trak
(aplikasi yang sudah berusaha disembunyikan oleh Chromium melalui atribut lain yang tidak terdokumentasi).
CGFont
tidak melakukan 'sulap' ini, jadi mungkin Chromium bisa mengambil CGFont
dari CTFont
dan hanya menggunakannya untuk mendapatkan kemajuan? Sayangnya, cara ini tidak akan berhasil karena CoreText
juga diketahui merusak font dengan cara lain. Misalnya, emoji kecil akan dibuat sedikit lebih besar dari yang sebenarnya Anda minta (sedikit meningkatkan ukurannya). CGFont
tidak mengetahui hal ini, jadi Anda akan memiliki emoji berbasis sbix yang terlalu berdekatan satu sama lain karena Anda akan mengukur pada satu ukuran, tetapi CoreText
akan menggambarnya lebih besar dalam jumlah tertentu. Chromium memang menginginkan kemajuan CTFont
, tetapi membutuhkannya tanpa pelacakan, dan sebaiknya tanpa pembongkaran lainnya.
Karena perbaikan untuk masalah spasi memerlukan serangkaian perbaikan Blink dan Skia yang saling berhubungan, engineer Chromium tidak dapat "kembali" untuk memperbaiki masalah. Para engineer Chromium juga mencoba menggunakan tanda build yang berbeda untuk mengubah codepath terkait font di Skia, yang memperbaiki masalah font tebal, tetapi memundurkan masalah spasi.
Perbaikan
Pada akhirnya, tentu saja Chromium ingin memperbaiki kedua masalah tersebut. Chromium kini memanfaatkan fungsi metrik font OpenType font bawaan HarfBuzz untuk mengambil metrik horizontal langsung dari data biner dalam tabel font font sistem. Dengan menggunakan ini, Chromium men-sidestep CoreText
dan Skia saat font memiliki tabel trak
(kecuali jika font emoji).
Sementara itu, masih ada Masalah Skia #10123 untuk melacak perbaikan ini sepenuhnya di Skia, dan kembali menggunakan Skia untuk mengambil metrik font sistem dari sana, bukan perbaikan saat ini yang melalui HarfBuzz
.