Mert Özen Her Satırda Daha İleri
Frontend CSS Property'leri: Uygulamalı Rehber — #01

Font'lar ve @font-face: font Shorthand'i, font-family Stack'i, Variable Font'lar ve font-variation-settings

Mert Özen 15 Kas 2026 15 dk 10 görüntülenme
Font'lar ve @font-face: font Shorthand'i, font-family Stack'i, Variable Font'lar ve font-variation-settings

Self-host bir variable font'u @font-face ile ağırlık aralığı (font-weight: 100 900), ayrı italik face ve unicode-range ile tanımlarsın; ağırlığı font-weight ile verir, font-variation-settings'i yalnız özel eksenler için kullanırsın. Bookstore başlıklarında Fraunces ile font shorthand'inin line-height'ı sıfırlamasını, tek değerli descriptor'ın 700'ü bozmasını, sahte italiği ve ğ, ş, İ harflerinin hangi dosyadan geldiğini Chromium ve WebKit'te ölçüyoruz.

Sürüm notu: Bu yazı CSS Fonts Module Level 4 spesifikasyonuna ve Baseline'ın Kasım 2026 durumuna (web-features 3.46.0) göre yazıldı; örnekler Chromium 158 ve WebKit 27.2 (Playwright 1.65) ile denenmiştir, Firefox desteği web-features ve MDN'in (Mozilla'nın web dokümantasyon projesi) browser-compat-data 8.1.9 verisinden alınmıştır.

Önce Tahmin Et

Bu seri, sitedeki CSS serisinin (CSS3: Flexbox, Grid ve Modern CSS) uygulamalı tamamlayıcısı. O seri tarayıcının CSS'i nasıl uyguladığını ve layout'u anlattı; burada her gün yazdığımız property ailelerini tek tek ele alıp "bu görünümü hangi property ile, hangi değerle yazarım?" sorusuna cevap arıyoruz. Örneklerin hepsi sitedeki serilerin ortak örnek uygulaması Bookstore (bir online kitapçı) üzerinde: katalog kartı, kitap detayı, sepet ve checkout ekranları.

İlk yazı font'larla başlıyor. Katalog kartında kitap başlığını variable bir font ile yazdık. Kart line-height: 1.6 ve bir font ekseni ayarı veriyor, başlık da kendi font'unu shorthand ile tanımlıyor:

.card { line-height: 1.6; font-variation-settings: "SOFT" 100; }
.card .title { font: 600 1.25rem "Fraunces", serif; }

.w700-fvs { font-weight: 700; font-variation-settings: "wght" 400; }
<div class="card"><p class="title" id="title">Middlemarch</p></div>
<span class="w700-fvs">Middlemarch</span>

İki soru. Başlığın line-height'ı karttan gelen 1.6 mı olur? Kartta verdiğimiz "SOFT" 100 başlığa kalıtılır mı? İkinci satırdaki span'e font-weight: 700 verdik; ekranda kalın mı görünür? Cevaplarını not et, ölçümler yazının içinde.

@font-face: Font'u Tarayıcıya Tanıtmak

Bookstore'un başlıklarında Fraunces kullanıyoruz. Fraunces, OFL (SIL Open Font License; font'u ücretsiz kullanıp kendi sunucunda dağıtmana izin veren açık font lisansı) ile yayınlanan, ağırlık (wght), optik boyut (opsz) ve iki özel eksene sahip bir serif variable font. Dosyaları @fontsource-variable/fraunces 5.3.0 paketinden alıp web/fonts/ altına kopyaladım; lisans metni de yanında. Font'u self-host etmenin karşılığı, onu tarayıcıya @font-face ile kendin tanıtmak:

/* Fraunces: OFL lisanslı variable font; eksenler wght 100-900, opsz 9-144, SOFT, WONK */
@font-face {
    font-family: "Fraunces";
    src: url("../fonts/fraunces-latin-normal.woff2") format("woff2");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122;
}
@font-face {
    font-family: "Fraunces";
    src: url("../fonts/fraunces-latin-ext-normal.woff2") format("woff2");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
    unicode-range: U+0100-0130, U+0132-024F, U+20A0-20AB, U+20AD-20C0;
}
@font-face {
    font-family: "Fraunces";
    src: url("../fonts/fraunces-latin-italic.woff2") format("woff2");
    font-weight: 100 900;
    font-style: italic;
    font-display: swap;
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122;
}
@font-face {
    font-family: "Fraunces";
    src: url("../fonts/fraunces-latin-ext-italic.woff2") format("woff2");
    font-weight: 100 900;
    font-style: italic;
    font-display: swap;
    unicode-range: U+0100-0130, U+0132-024F, U+20A0-20AB, U+20AD-20C0;
}

Her @font-face bir "face" tanımlar ve descriptor'ları şunu söyler: bu family adıyla, bu stil ve ağırlık aralığında bir metin istenirse, şu dosyayı kullan.

src virgülle ayrılmış bir aday listesidir; tarayıcı desteklediği ilk adayı seçer. url() dosyayı indirir, local("Fraunces") ise kullanıcının bilgisayarında kurulu bir kopyayı arar. Variable font self-host ederken local() yazmıyorum: kullanıcının kurduğu sürüm farklı eksenlere ya da farklı metriklere sahip olabilir ve sayfa makineden makineye farklı görünür. format("woff2") ipucu tarayıcının desteklemediği bir formatı indirmeden atlamasını sağlar. WOFF2 (Web Open Font Format 2; font'u Brotli ile sıkıştıran web font formatı) bugün tek başına yeterli; eski font formatlarında bir yedek eklemeye gerek yok. Eski kodlarda gördüğün format("woff2-variations") yazımı variable font'u ayırmak içindi, artık format("woff2") tech(variations) şeklinde yazılabiliyor. Variable dosya düz format("woff2") ile de çalışıyor.

font-weight: 100 900 bir aralıktır ve variable font için en önemli satırdır. Tarayıcıya "bu tek dosya 100'den 900'e kadar her ağırlığı karşılar" der. Descriptor'ı hiç yazmadığında bugünkü motorlar dosyanın kendi aralığını kullanıyor, ama hazır CSS örneklerinde sık görülen font-weight: normal ya da 400 satırı aralığı tek bir değere indirir; ne olduğunu tuzaklar bölümünde ölçeceğiz. font-style da aynı mantıkla eşleşir: italik dosyayı ayrı bir face olarak font-style: italic ile tanımlıyoruz, family adı aynı kalıyor.

font-display, font henüz inmemişken metnin nasıl görüneceğini belirler. Tarayıcı bir "block" süresi boyunca metni görünmez fallback ile çizer, ardından bir "swap" süresinde görünür fallback gösterir, font bu süre içinde gelirse değiştirir. block kısa bir görünmezlik ve sınırsız swap, swap neredeyse sıfır görünmezlik ve sınırsız swap, fallback kısa bir swap süresi, optional ise hiç swap yapmadan "gelmediyse bu sayfada kullanma" demektir. Süreler spesifikasyonda kesin milisaniye olarak değil tarayıcıya bırakılmış olarak tanımlı. Hangisinin seçileceği, preload ve swap'ın neden olduğu layout kayması Web Performansı serisinin görsel ve font optimizasyonu yazısında ayrıntılı ele alınıyor.

unicode-range bu face'in hangi karakterler için indirileceğini söyler. Fraunces'i iki dosyaya bölünmüş hâlde kullanıyoruz: latin dosyası temel Latin harflerini, latin-ext dosyası ise ğ, ş, İ gibi genişletilmiş harfleri içeriyor. Syntax tek kod noktası (U+0131), aralık (U+0100-0130) ya da joker (U+4??) kabul eder. Tarayıcı bir face'i ancak sayfada o aralıkta bir karakter o family ile çizilecekse indirir. Türkçe için kritik bir ayrıntı var: noktasız ı (U+0131) Fontsource'un latin dosyasında, ğ (U+011F), ş (U+015F) ve İ (U+0130) ise latin-ext dosyasında. Türkçe bir başlıkta iki dosya birden iner.

font-family Stack'i ve Generic Family'ler

font-family bir öncelik listesidir. Tarayıcı her karakter için listeyi baştan sona dener ve o karakteri içeren ilk font'u kullanır; liste bir generic family ile biter. Bookstore'un base stilleri iki stack tanımlıyor:

:root {
    --font-body: system-ui, -apple-system, "Segoe UI", Roboto, "Noto Sans", sans-serif;
    --font-display: "Fraunces", Georgia, "Times New Roman", serif;
}

body {
    font-family: var(--font-body);
    font-size: 1rem;
    line-height: 1.6;
}

h1, h2, h3 {
    font-family: var(--font-display);
    line-height: 1.2;
    font-optical-sizing: auto;
}
h1 { font-size: 2.5rem; font-weight: 650; }
h2 { font-size: 1.5rem; font-weight: 600; }

Gövde metni için system-ui kullanıyoruz: Windows'ta Segoe UI, macOS'ta San Francisco gibi işletim sisteminin arayüz font'unu seçer ve hiç indirme gerektirmez. system-ui Baseline widely available. Arkasındaki -apple-system eski Safari ve Firefox sürümleri için, "Segoe UI" ve Roboto ise system-ui'yi tanımayan eski tarayıcılar için. Başlık stack'inde Fraunces henüz inmediyse ya da bir karakter Fraunces'te yoksa Georgia devreye giriyor.

Generic family'lerin hepsi aynı durumda değil. serif, sans-serif, monospace her yerde var; ui-sans-serif, ui-serif, ui-monospace ve ui-rounded ise yalnız Safari'de çalışıyor. Bunu ölçmenin kolay yolu, generic family'nin arkasına monospace koyup genişliğe bakmak: tarayıcı family'yi tanımıyorsa monospace'e düşer.

.generic .mono { font-family: monospace; }
.generic .ui { font-family: ui-sans-serif, monospace; }
.generic .system { font-family: system-ui, monospace; }
npm install
npx playwright install chromium webkit
node scripts/01-fonts.mjs
--- chromium
generic  mono               width: 108.0px
generic  ui                 width: 108.0px
generic  system             width: 88.6px
--- webkit
generic  mono               width: 108.4px
generic  ui                 width: 88.6px
generic  system             width: 88.6px

Chromium'da ui-sans-serif satırı monospace ile aynı genişlikte (108.0px): family tanınmadı ve sıradaki font kullanıldı. WebKit'te sistem font'u ile aynı (88.6px). Pratik sonuç: ui-sans-serif'i stack'e koyabilirsin ama arkasından system-ui ya da somut font adları gelmeli.

font Shorthand'i: Ne Yazdığın Kadar Ne Sıfırladığın

Şimdi giriş sorusuna dönelim. Lab sayfasının ölçümü:

--- chromium
.card line-height: 38.4px | .title line-height: normal | font-variation-settings: normal
--- webkit
.card line-height: 38.400002px | .title line-height: normal | font-variation-settings: normal

Kartın line-height'ı 38.4px, yani 24px font'un 1.6 katı. Başlıkta ise normal: shorthand'de line-height yazmadık, ama shorthand yazmadığın longhand'leri de başlangıç değerine çeker. Kart font-variation-settings ile "SOFT" 100 veriyordu; bu property kalıtılır, fakat font shorthand'i onu da normal'e çekti.

font shorthand'inin kuralları şöyle: font-size ve font-family zorunlu, family en sonda. font-style, font-variant (yalnız small-caps) ve font-weight boyuttan önce gelir; line-height ancak boyuttan hemen sonra / ile yazılabilir (font: 600 1.25rem/1.3 "Fraunces", serif). Ayrıca shorthand'in hiç set edemediği ama sıfırladığı bir grup property var: font-variation-settings, font-feature-settings, font-kerning, font-optical-sizing, font-size-adjust ve font-variant-* longhand'lerinin hepsi.

Bu yüzden component stillerinde font shorthand'ini yalnız gerçekten bir font'u baştan tanımlamak istediğinde kullanıyorum: form element'lerinin reset'indeki font: inherit bunun iyi bir örneği. Bir başlığın ağırlığını ya da boyutunu değiştirmek için longhand yazmak daha güvenli.

Variable Font: font-weight: 650, font-variation-settings ve font-optical-sizing

Static font'larda her ağırlık ayrı bir dosyadır ve font-weight: 650 yazarsan tarayıcı en yakın dosyayı (600 ya da 700) seçer. Variable font'ta ise ağırlık bir eksen; 650 gerçekten 600 ile 700 arasında bir ağırlık üretir. Aynı kelimeyi farklı ağırlıklarla çizip genişliğini ölçtüm:

.weights span { font-family: "Fraunces", serif; }
.w400 { font-weight: 400; }
.w600 { font-weight: 600; }
.w650 { font-weight: 650; }
.w700 { font-weight: 700; }
.w700-fvs { font-weight: 700; font-variation-settings: "wght" 400; }
weights  w400               font-weight: 400  width: 149.6px
weights  w600               font-weight: 600  width: 154.7px
weights  w650               font-weight: 650  width: 157.3px
weights  w700               font-weight: 700  width: 159.8px
weights  w700-fvs           font-weight: 700  width: 149.6px

Genişlik ağırlıkla birlikte düzenli artıyor: 400'de 149.6px, 650'de 157.3px, 700'de 159.8px. Bookstore'da h1'e 650 verdik; tasarımcının "600 ince, 700 kalın kaldı" dediği ara değer tek dosyayla mümkün.

Son satır giriş sorusunun cevabı. font-weight: 700 olmasına rağmen genişlik 400 ile aynı: font-variation-settings eksen değerlerini en son uygular ve font-weight'in ürettiği wght değerini ezer. Computed font-weight yine 700 görünür, ama ekrandaki metin 400 ağırlığındadır. DevTools'ta bakan biri "ağırlık 700, neden ince?" diye şaşırır.

Kural basit: kayıtlı eksenler için (wght, wdth, slnt, ital, opsz) her zaman karşılık gelen property'yi kullan: font-weight, font-stretch (yeni adıyla font-width, henüz yalnız Safari'de), font-style, font-optical-sizing. font-variation-settings'i yalnız özel eksenler için yaz. Fraunces'te bunlar büyük harfle yazılan SOFT (köşeleri yumuşatır) ve WONK (bazı harflerin eğik varyantları). Bir başka dikkat noktası: font-variation-settings parça parça birleşmez. Bir yerde "SOFT" 100, başka bir yerde "WONK" 1 yazarsan ikincisi birincisini tamamen siler. Bunu aşmak için her ekseni bir custom property'de tutup tek bir font-variation-settings içinde birleştirebilirsin.

font-optical-sizing: auto, opsz ekseni olan font'larda varsayılan değerdir ve ekseni font boyutuna göre ayarlar: küçük boyutta kalın çizgiler ve açık harf aralıkları, büyük boyutta ince kontrastlı formlar. 48px'lik bir başlıkta farkı ölçtüm:

.optical span { font-family: "Fraunces", serif; font-size: 48px; }
.optical .off { font-optical-sizing: none; }
optical  auto               width: 117.4px
optical  off                width: 122.0px

none ile font varsayılan opsz değerine (Fraunces'te 14) döner ve 48px'te gövde metni için tasarlanmış daha geniş harfler çizilir. Bu yüzden base stilde başlıklara açıkça auto yazdım; reset'lerden ya da bir shorthand'den gelen bir değişikliğe karşı niyeti belli ediyor.

font-synthesis: Sahte Bold ve Sahte İtalik

İstenen stil ya da ağırlık için uygun bir face yoksa tarayıcı onu sentezler: dik harfleri eğerek sahte italik, çizgileri kalınlaştırarak sahte bold üretir. Kitap detayındaki alıntıyı font-style: italic ile yazıyoruz. Gerçek italik dosyası olmasaydı ne olurdu? Yalnız dik dosyayı tanımlayan bir family ile denedim:

/* yalnız dik (upright) dosya: italik sentezlenmek zorunda */
@font-face {
    font-family: "Fraunces Upright";
    src: url("../fonts/fraunces-latin-normal.woff2") format("woff2");
    font-weight: 100 900;
    font-style: normal;
}

.upright span { font-family: "Fraunces Upright", serif; }
.upright .real { font-family: "Fraunces", serif; }
.upright .italic { font-style: italic; }
.upright .no-synth { font-synthesis: none; }
--- chromium
upright  plain              width: 149.6px
upright  italic             width: 149.6px
upright  italic no-synth    width: 149.6px
upright  real italic        width: 140.7px
same pixels? .upright .plain vs .upright .italic: false
same pixels? .upright .plain vs .upright .no-synth: true
--- webkit
same pixels? .upright .plain vs .upright .italic: false
same pixels? .upright .plain vs .upright .no-synth: true

Sahte italik, dik metinle aynı genişlikte (149.6px), çünkü yalnızca harfleri eğiyor; gerçek italik dosyası ise kendi harf genişliklerine sahip (140.7px). Pikseller de farklı: sentez yapıldı. font-synthesis: none eklediğimizde metin dik dosyayla birebir aynı piksellerle çiziliyor; tarayıcı italik istenmesine rağmen hiçbir şey uydurmuyor. Bookstore'da gerçek italik dosyası olduğu için bu bir sorun değil, ama italik dosyasını unutan bir projede tasarımcının fark edeceği ilk şey bu eğik ve sıkışık harfler olur.

font-synthesis bir listedir: weight, style, small-caps ve position. font-synthesis: style yalnız italik sentezine izin verir, none hepsini kapatır. Longhand'leri de var (font-synthesis-weight: none gibi). Gerçek italik ve gerçek ağırlık aralığı tanımlı bir projede font-synthesis: none eklemek, eksik bir face'i sessizce sentezlemek yerine hatayı görünür kılar.

Bookstore'da Uygulama: Hangi Dosyalar İniyor, Türkçe Harfler Nereden Geliyor?

Katalog ve kitap detayı sayfalarını açıp hangi font dosyalarının istendiğine ve document.fonts içindeki face'lerin durumuna baktım:

node scripts/01-pages.mjs
node scripts/baseline.mjs font-face font-display font-family-system font-family-ui font-variation-settings font-optical-sizing font-synthesis font-metric-overrides font-size-adjust
catalog.html  requested: fraunces-latin-normal.woff2
              FontFace status: normal/latin: loaded | normal/latin-ext: unloaded | italic/latin: unloaded | italic/latin-ext: unloaded
book.html     requested: fraunces-latin-normal.woff2, fraunces-latin-italic.woff2
              FontFace status: normal/latin: loaded | normal/latin-ext: unloaded | italic/latin: loaded | italic/latin-ext: unloaded

Katalog sayfasında başlıklar yalnız temel Latin harflerinden oluşuyor ve tek dosya iniyor; üç face unloaded kalıyor. Kitap detayında alıntı italik olduğu için italik dosyası da iniyor. unicode-range ve ayrı stil dosyaları sayesinde kullanıcı hiç kullanmadığı karakterlerin dosyasını indirmiyor.

Türkçe karakterleri kontrol etmek için lab'e iki satır koydum. Birincisi normal Fraunces family'si ile, ikincisi bilerek yalnız latin dosyasını tanımlayan bir family ile:

/* yalnız latin subset'i: latin-ext face'i yok */
@font-face {
    font-family: "Fraunces Latin";
    src: url("../fonts/fraunces-latin-normal.woff2") format("woff2");
    font-weight: 100 900;
    unicode-range: U+0000-00FF, U+0131;
}

.glyphs .full { font-family: "Fraunces", serif; }
.glyphs .latin-only { font-family: "Fraunces Latin", Georgia, serif; }
<p class="glyphs" lang="tr">
    <span class="full">ğ ş ı İ ç ö ü</span> <span class="latin-only">ğ ş ı İ ç ö ü</span>
</p>
font requests: fraunces-latin-normal.woff2, fraunces-latin-italic.woff2, fraunces-latin-ext-normal.woff2
.glyphs .full        Fraunces x13
.glyphs .latin-only  Fraunces x10, Georgia x3

Son iki satır Chromium'un, DevTools'un "Rendered Fonts" bölümünde gösterdiği veriyi CDP (Chrome DevTools Protocol; DevTools'un tarayıcıyla konuştuğu protokol) üzerinden okumasının sonucu. Normal family'de 13 glyph'in (7 harf ve 6 boşluk) hepsi Fraunces'ten geliyor. Yalnız latin dosyasını tanımlayan family'de ise 3 glyph Georgia'dan çizilmiş: ğ, ş ve İ. Noktasız ı ise Fraunces'ten geliyor, çünkü U+0131 latin aralığında. Ekranda bu, bir başlıkta üç harfin farklı bir font'la çizilmesi demek. Görsel olarak kolayca gözden kaçıyor, özellikle de fallback benzer bir serif ise.

Türkçe arayüzde hangi font'un Türkçe karakterlerde iyi göründüğü, ağırlık ve boyut seçimi UI/UX Tasarım İlkeleri serisinin Typography yazısının konusu. Bir font'u Türkçe için subset'leyip dosya boyutunu küçültmek ise Web Performansı serisinin görsel ve font optimizasyonu yazısında anlatılıyor.

Üretimde Dikkat

Font dosyası bir sayfanın en büyük kaynaklarından biri. Burada dört dosyanın toplamı yaklaşık 500 KB, ama unicode-range sayesinde katalog sayfası yalnız 121 KB'lık tek dosyayı indiriyor. Yeni bir face eklediğinde DevTools'un Network panelini font filtresiyle açıp hangi sayfanın hangi dosyayı istediğine bak; bu yazıdaki 01-pages.mjs gibi bir script'i CI'da çalıştırıp beklenmeyen bir font isteğini yakalayabilirsin.

Fallback font ile web font arasındaki metrik farkı, font geldiğinde metnin yer değiştirmesine yol açar. @font-face içindeki size-adjust descriptor'ı (Baseline newly available) fallback font'u ölçekleyerek bu farkı azaltır; ascent-override, descent-override ve line-gap-override ise Safari'de olmadığı için Baseline değil. Bunları ancak progressive enhancement (eski tarayıcıda da çalışan bir temel üzerine destekleyen tarayıcıya ek iyileştirme koymak) olarak kullan; hesaplama yöntemi Web Performansı serisinin layout kaymasını anlatan yazısında.

Kendi sunucunda barındırdığın font'un lisansını snapshot'a ve deploy edilen dosyaların yanına koy. OFL, font'u dağıtmana izin verir ama lisans metninin font'la birlikte gitmesini ister.

Sık Düşülen Tuzaklar

Birincisi, font shorthand'i ile line-height'ı farkında olmadan sıfırlamak. Ölçtüğümüz gibi kartın 1.6'sı başlıkta normal'e döndü. Ya longhand yaz ya da line-height'ı shorthand'e / ile ekle.

İkincisi, variable font'u @font-face'te tek bir ağırlıkla tanımlamak. Aynı dosyayı bir kez font-weight: 400 ile, bir kez de hiç ağırlık descriptor'ı yazmadan tanımladım ve metne 700 verdim:

/* aynı dosya, bu kez ağırlık aralığı OLMADAN tanımlanıyor */
@font-face {
    font-family: "Fraunces Single";
    src: url("../fonts/fraunces-latin-normal.woff2") format("woff2");
    font-weight: 400;
}
/* hiç font-weight descriptor'ı yok */
@font-face {
    font-family: "Fraunces Auto";
    src: url("../fonts/fraunces-latin-normal.woff2") format("woff2");
}

.single span { font-family: "Fraunces Single", serif; }
.single .no-synth { font-synthesis: none; }
.single .auto { font-family: "Fraunces Auto", serif; }
--- chromium
single   w400               font-weight: 400  width: 149.6px
single   w700               font-weight: 700  width: 149.6px
single   w700 no-synth      font-weight: 700  width: 149.6px
single   w700 auto          font-weight: 700  width: 159.8px
same pixels? .single .w400 vs .single .w700: true
same pixels? .single .w400 vs .single .no-synth: true
--- webkit
single   w400               font-weight: 400  width: 149.6px
single   w700               font-weight: 700  width: 149.6px
single   w700 no-synth      font-weight: 700  width: 149.6px
single   w700 auto          font-weight: 700  width: 159.8px
same pixels? .single .w400 vs .single .w700: false
same pixels? .single .w400 vs .single .no-synth: true

font-weight: 400 ile tanımlanan face'te iki motor da istenen 700'ü üretmiyor: genişlik ilk üç satırda 400 ile aynı. Chromium metni 400 ağırlığında çiziyor (pikseller 400 ile aynı), WebKit ise 400'ün üzerine sahte bold uyguluyor (pikseller farklı). font-synthesis: none ile WebKit de 400'e dönüyor. Descriptor'ı hiç yazmadığımız auto satırı ise doğru: 159.8px, yani gerçek 700. Sorun tek değerli descriptor'da; birçok eski örnek kod ve font servisinin ürettiği CSS her face'e font-weight: normal yazar. Variable font için aralığı (100 900) açıkça yazmak niyeti belli eder ve bu hatayı engeller. Bu hatanın static font karşılığı, her ağırlık için ayrı dosya tanımlayıp variable font'un tek dosyada sunduğu aralığı kullanmamak.

Üçüncüsü, font-variation-settings: "wght" ... yazıp font-weight'i ezmek. Computed değer 700 görünürken ekranda 400 çizilir ve hover'da, dark mode'da ya da bir media query'de yazdığın font-weight değişiklikleri hiç etki etmez. Kayıtlı eksenler için standart property'leri kullan.

Dördüncüsü, unicode-range'i elle kısaltıp Türkçe harfleri dışarıda bırakmak. Fallback benzer bir font olduğunda bu hata testte gözükmeyebilir; Türkçe karakter içeren bir sayfada rendered font'u kontrol et.

Baseline Durumu

Bu yazıdaki property ve descriptor'ların durumu, web-features paketinden okunarak:

font-face                  widely 2019-03-20  Chrome 36, Firefox 39, Safari 10, iOS 10
font-display               widely 2022-07-15  Chrome 60, Firefox 58, Safari 11.1, iOS 11.3
font-family-system         widely 2024-03-07  Chrome 56, Firefox 92, Safari 11, iOS 11
font-family-ui             not Baseline       Chrome -, Firefox -, Safari 13.1, iOS 13.4
font-variation-settings    widely 2021-03-05  Chrome 62, Firefox 62, Safari 11, iOS 11
font-optical-sizing        widely 2022-09-24  Chrome 79, Firefox 62, Safari 13.1, iOS 13.4
font-synthesis             widely 2024-07-06  Chrome 97, Firefox 34, Safari 9, iOS 9
font-metric-overrides      not Baseline       Chrome 87, Firefox 89, Safari -, iOS -
font-size-adjust           newly 2024-07-25   Chrome 127, Firefox 118, Safari 17, iOS 17
ÖzellikDurumNot
@font-face, unicode-range, WOFF2Widely availableEk bir şey gerekmez
font-displayWidely availableSüreler tarayıcıya bırakılmış
system-uiWidely availableStack'te somut font adlarıyla birlikte
ui-sans-serif ve diğer ui-*Baseline değilYalnız Safari; arkasına fallback koy
font-variation-settings, font-optical-sizingWidely availableÖzel eksenler için
font-synthesisWidely availableposition değeri yalnız Firefox'ta
size-adjust (font-size-adjust özelliğinin parçası)Newly available2024-07'den beri
ascent-override ve diğer metric override'larBaseline değilSafari yok; progressive enhancement

Küçük Bir Deneme

★☆☆ Lab'deki .card .title kuralını, kartın line-height'ını ve SOFT eksenini koruyacak şekilde yeniden yaz. node scripts/01-fonts.mjs ile ilk satırın değiştiğini doğrula.

★★☆ book.html'deki alıntıya Türkçe bir cümle ekle (ğ ve ş içeren). Hangi yeni dosyanın istendiğini tahmin et, sonra 01-pages.mjs ile kontrol et.

★★★ SOFT ve WONK eksenlerini --font-soft ve --font-wonk custom property'leriyle tek bir font-variation-settings'te birleştir; kartta yalnız --font-soft'u değiştirdiğinde WONK'ın kaybolmadığını computed değerden ölç.

Bir sonraki yazıda font'u seçtikten sonra metni biçimlendiren property'lere geçiyoruz: text-decoration ailesi ve okunur bir link alt çizgisi, letter-spacing'in neden em ile verilmesi gerektiği, text-shadow ve inline bir ikonu fiyatın yanına hizalayan vertical-align.