FlowingDev

Penjelasan Font Fallbacks: Menghindari Gempa Layout CLS

Pelajari bagaimana CSS font metrics seperti size-adjust dan ascent-override mencegah Cumulative Layout Shift dengan cara bikin system font cocok sempurna dengan web font kamu.

Coba tool-nya: Font Fallback Generator (CLS)

Dalam satu kalimat

Font fallback metrics adalah kekuatan super CSS yang secara artifisial merenggangkan (stretch) dan memampatkan (squash) sebuah system font sehingga ukurannya secara matematis persis sama dengan custom web font kamu, mencegah layout halaman bergeser brutal pas custom font-nya selesai di-load.

Masalah yang diselesaikannya

Buat paham masalahnya, kamu harus ngerti dulu perang tipografi paling jadul di web: apa yang harus kita tampilin ke user sambil nungguin custom web font berukuran 150KB kelar di-download lewat koneksi 3G yang bapuk?

Berdasarkan sejarah, browser milih salah satu dari dua pendekatan, dan dua-duanya sama-sama ampas. Yang pertama itu FOIT (Flash of Invisible Text), di mana browser nyembunyiin teksnya sampai font selesai di-download. User cuma bisa melototin layar kosong, mikir apa website kamu rusak. Yang kedua itu FOUT (Flash of Unstyled Text), di mana browser langsung nge-render teks pakai local system font (kayak Arial atau Times New Roman), terus buru-buru diganti sama custom font kamu yang cakep itu sepersekian milidetik pas file-nya nyampe.

Komunitas web development rata-rata setuju kalau FOUT itu lebih mendingan buat accessibility dan perceived performance. Lagian, baca teks jelek masih lebih mending daripada nggak ada teks sama sekali. Kita ngeresmiin hal ini pakai rule CSS font-display: swap.

Tapi font-display: swap ngelahirin monster baru: Cumulative Layout Shift (CLS).

Tiap font punya kerangka yang unik. Huruf "x" di Roboto secara fisik lebih lebar dari "x" di Arial. Tinggi huruf kapitalnya beda-beda. Spacing bawaan di dalam file font-nya juga beda total. Pas browser nge-swap Arial ke Roboto, teksnya tiba-tiba makan ruang horizontal dan vertikal yang beda. Paragraf jadi reflow. Teks turun ke baris baru.

Kalau ini kejadian pas user udah asyik baca atau mau ngeklik tombol, satu halaman bakal lompat kayak ada gempa bumi yang ngelanda DOM. Tombol geser dari kursor user. Gambar kedorong ke bawah. Google ngenalin metrik Core Web Vitals buat ngukur rasa frustrasi ini, ngasih penalti SEO gede-gedean buat situs yang CLS-nya tinggi. Kita butuh cara bikin system font sementara yang jelek ini bisa niruin footprint fisik dari custom font yang cantik itu secara presisi.

Cara kerjanya di balik layar

Buat nyetop layout shift, kita nggak ngubah custom web font-nya. Alih-alih, kita bikin versi "Frankenstein" dari local system font pakai rule @font-face. Kita pakai CSS descriptors khusus buat nge-override geometri internal si system font.

Anatomi dari Font Box

Buat ngotak-ngatik font, kamu harus paham gimana browser ngitung kotak yang ngelilingin satu baris teks. Ini bukan cuma soal font-size. Ini bergantung pada tiga metrik internal yang udah tertanam di dalam file font-nya itu sendiri:

  1. Ascent: Jarak dari invisible baseline (tempat huruf berpijak) sampai ke puncak karakter tertinggi (kayak ujung atas huruf 'h' atau 'T').
  2. Descent: Jarak dari baseline sampai ke bagian bawah karakter yang ngegantung (kayak ekor huruf 'y', 'g', atau 'p').
  3. Line Gap: Rekomendasi ruang kosong antara descent baris pertama dan ascent baris berikutnya (sering disebut leading).

Di CSS, total tinggi dari sebaris teks itu kira-kira ascent + descent + line gap. Kalau custom font dan system font kamu punya nilai yang beda buat tiga metrik ini, layout kamu bakal lompat secara vertikal. Kalau lebar hurufnya beda, layout kamu bakal lompat secara horizontal.

Masuklah Para Overrides

CSS Fonts Module Level 4 ngenalin empat descriptor ajaib yang bisa dipasang di dalam blok @font-face. Descriptor ini mencegat cara browser ngebaca metrik internal file font dan langsung nge-overwrite datanya on the fly.

  • size-adjust: Ini bertindak kayak multiplier buat keseluruhan font. Kalau custom font kamu rata-rata lebih lebar dari Arial, kamu bisa set size-adjust: 110% di Arial buat ngerengganginnya secara horizontal.
  • ascent-override: Nge-overwrite metrik ascent internal bawaan font.
  • descent-override: Nge-overwrite metrik descent internal bawaan font.
  • line-gap-override: Nge-overwrite metrik line gap internal bawaan font.

Menggabungkan Matematikanya

Triknya adalah size-adjust itu men-scale semuanya—termasuk lebar horizontal, ascent, dan descent. Jadi, kalau kamu nge-scale system font naik 110% supaya lebar barisnya pas sama web font kamu, tanpa sengaja kamu juga bikin tinggi vertikal system font itu jadi 110% lebih jangkung, yang mana bakal bikin vertical layout shift!

Buat ngakalin ini, nilai overrides (ascent-override, descent-override, line-gap-override) dihitung berdasarkan persentase dari nilai size-adjust, bukan ukuran font aslinya. Kamu pakai size-adjust buat ngepasin lebar horizontalnya, terus kamu pakai metrik override buat dasarnya memampatkan lagi tinggi vertikalnya ke bawah (atau narik ke atas) biar bener-bener pas sama bounding box custom font kamu.

Kayak gini kira-kira hasil kodenya. Perhatiin gimana kita bikin font family baru yang imajiner bernama Roboto-Fallback yang ngebungkus local font Arial dengan override matematis yang presisi:

/* 1. Load web font kamu yang asli */
@font-face {
  font-family: 'Roboto';
  src: url('/fonts/roboto.woff2') format('woff2');
  font-display: swap;
}

/* 2. Bikin fallback Frankenstein-nya */
@font-face {
  font-family: 'Roboto-Fallback';
  src: local('Arial');
  /* Renggangin Arial secara horizontal biar pas sama Roboto */
  size-adjust: 104.5%; 
  /* Mampatin metrik vertikal Arial biar pas sama Roboto */
  ascent-override: 89.92%;
  descent-override: 23.44%;
  line-gap-override: 0%;
}

/* 3. Pakai barengan di CSS kamu */
body {
  font-family: 'Roboto', 'Roboto-Fallback', sans-serif;
}

Pas halamannya di-load, browser bakal langsung nge-paint Roboto-Fallback. Itu cuma Arial lokal sih, tapi udah direnggangin secara horizontal dan dimampatin secara vertikal biar footprint matematisnya plek ketiplek sama Roboto. Pas file Roboto yang asli kelar di-download, swap terjadi, desain bentuk hurufnya berubah, tapi layout-nya nggak bakal geser satu piksel pun.

Cerita dari dunia nyata

Jebakan Tombol "Cancel"

Sebuah platform e-commerce gede lagi pusing ngadepin cart abandonment dan tiket customer support yang pada ngamuk. User pada komplain kalau mereka nggak sengaja ngosongin keranjang belanjaan. Tim engineer ngerekam user session dan nemuin biang keroknya. Situs itu nge-load branded font yang lumayan berat. User ngelihat tombol "Checkout" sebelahan persis sama tombol "Empty Cart". Pas banget mouse mereka ngeklik "Checkout", si branded font selesai di-load. Branded font ini ternyata jauh lebih lebar dari system default. Teksnya reflow, ngedorong tombol "Checkout" ke kanan, dan ngeposisiin tombol "Empty Cart" pas banget di bawah klik mouse user yang lagi turun. Implementasi size-adjust dan metric overrides ngunci tombol-tombol itu di tempatnya pas font-nya nge-swap, dan langsung nurunin drastis rasio cancel yang nggak disengaja.

Gempa Bumi Artikel Berita

Sebuah tech blog populer ngelakuin redesign gede-gedean, lengkap dengan serif font yang cantik dan modern buat bacaan panjang. Buat ngedepanin speed, mereka pakai font-display: swap. Tapi, pembaca dengan koneksi lambat ngalamin fenomena yang ngeselin: mereka buka artikel, scroll ke bawah tiga paragraf, dan mulai baca. Dua detik kemudian, serif font-nya ke-load. Karena serif font ini punya ascent dan descent yang lebih gede dari system default, tiap baris teks membesar sepersekian milimeter. Dikalikan tiga paragraf, efek dominonya bikin vertical shift yang lumayan gila, ngelempar kalimat yang lagi dibaca user sampai keluar dari layar. Dengan nambahin ascent-override dan descent-override ke local fallback font, teksnya nge-swap sempurna di tempat, jaga mata pembaca tetap di tempat yang semestinya.

Patah Hati Skor Lighthouse

Seorang frontend developer ngabisin waktu tiga minggu buat optimasi web app biar sesuai standar Core Web Vitals Google. Mereka nge-compress gambar jadi WebP, men-defer JavaScript yang non-critical, dan nge-minify CSS mereka. Mereka nge-run Google Lighthouse dengan pede bakal dapet skor 100 sempurna. Eh, malah dapet 75. Laporannya ngasih warning penalti Cumulative Layout Shift yang gede banget. Seluruh pergeseran itu disebabin cuma gara-gara satu headline <H1> yang turun dari satu baris jadi dua baris pas custom web font ke-load. Daripada nge-redesign header-nya atau pake invisible text, si developer nge-generate fallback metrics yang presisi buat font heading-nya. Layout shift-nya langsung nol, skor Lighthouse tembus 100, dan si developer akhirnya bisa tidur nyenyak.

Kesalahan umum dan jebakan

  • Menebak-nebak persentase: Kamu nggak bisa ngira-ngira angka ini pakai feeling. Kalkulasinya butuh ngekstrak data Unique Units Per Em (UPM), ascent, descent, dan line gap yang presisi langsung dari binary tables di dalam file web font maupun system font, lalu mengalikan silang semuanya. Selalu pakai programmatic generator biar matematikanya bener.
  • Masang overrides ke web font: Jebakan klasik itu nambahin size-adjust langsung ke deklarasi @font-face milik custom web font. Ini nggak ada gunanya sama sekali. Overrides wajib dipasang di deklarasi @font-face yang bener-bener terpisah yang nge-load system font local(), yang nantinya kamu taruh di urutan kedua dalam tumpukan font-family kamu.
  • Milih fallback yang strukturnya bertolak belakang: Font metrics itu kemampuannya terbatas. Kalau custom font kamu itu sans-serif yang ultra-condensed (sempit), terus kamu pakai serif font yang lebar dan melengkung sebagai basis fallback lokalnya, matematika size-adjust bakal bikin serif font-nya kelihatan distorsi parah dan nggak bisa dibaca sambil nunggu di-swap. Selalu pilih local system font yang kerangka strukturnya lumayan mirip sama web font kamu.
  • Lupa soal line-gap-override: Developer sering cuma fokus ke lebar sama tinggi doang dan mikir kalau nge-set line gap ke normal atau diabaikan aja udah cukup. Kalau browser mutusin buat ngasih leading bawaan ke fallback font yang nggak pas sama leading internal milik web font, ritme vertikal kamu bakal bergeser. Selalu definisiin secara eksplisit.

Kenapa ini wajib masuk radar kamu

Kamu udah harus mikirin font fallback metrics dari detik kamu mutusin pakai custom web font di project mana pun yang mengutamakan user experience dan SEO.

Secara historis, tipografi di web itu kompromi antara estetika (pakai font bagus) dan performa (ngindarin layout yang lompat-lompat). Dengan hadirnya CSS font metrics, kompromi itu udah mati. Kapan pun kamu lagi ngaudit Core Web Vitals sebuah situs, pusing sama skor CLS yang tinggi, atau ngebangun komponen UI reusable yang haram hukumnya bergetar di layar, font fallback overrides adalah solusi engineering yang definitif. Fitur ini ngubah web font dari yang tadinya beban loading jadi sebuah transisi mulus yang nyaris nggak kerasa.

Gali lebih dalam

Teori beres. Saatnya praktik — 100% di browser kamu.

Coba tool-nya: Font Fallback Generator (CLS)