Ders 22 / 23
Yardımcı Sınıf Yaklaşımı
Kısıt tabanlı biçem sistemleri; kapalı ölçekten değer alan tek bildirimlik sınıflar, kümenin bileşen sayısından bağımsız büyümesi, yinelemenin biçem dosyasından belgeye taşınması ve yaklaşımın kırıldığı yerler.
İçindekiler
Buraya kadarki yaklaşımların ortak varsayımı vardı: her bileşenin kendi kuralları olur ve biçem dosyası bileşen bileşen büyür. Bunun tersini savunan bir yaklaşım daha vardır.
Fikir şudur: bileşene özel kural hiç yazılmaz. Belge, önceden tanımlı ve tek bildirimlik sınıflardan kurulur. Kutu tasarımı biçem dosyasında değil, belgede yapılır.
Kısıt Düşüncesi
Yardımcı sınıf (utility class), tek bir bildirim yazan ve değerini kapalı bir ölçekten
alan sınıftır. Adı yaptığı işi bildirir: p-1 bir iç boşluk değeri, gap-0 bir aralık
değeri, bg-zemin bir zemin rengi verir.
Yaklaşımın adı kısalığı çağrıştırır ama asıl savunusu kısalık değil kısıttır. Ölçek kapalıdır: iç boşluk için beş değer varsa, altıncı bir değer yazmanın yolu yoktur. Tasarım tutarlılığı bir gözden geçirme sorusu olmaktan çıkar; sistemin kendisi rastgele değeri imkânsız kılar.
İkinci sonuç adlandırmayla ilgilidir. Yardımcı sınıf yaklaşımında yeni ad üretilmez; kümedeki adlar baştan bellidir. Önceki üç dersin sorunları — ad çakışması, sahiplik, silinebilirlik — ortadan kalkmaz, konu dışı kalır: sınıf kimseye ait değildir.
Kümenin Sınırlı Büyümesi
// yardimci.mjs — yardimci sinif kumesinin sinirli buyumesi ve bilesen yazimiyla karsilastirmasi // Yardimci sinif: tek bildirim yazan, degerini kapali bir olcekten alan sinif. // Kapali olcek: her ozellik icin secilebilecek deger sayisi sabittir. const OLCEK = { "padding": 5, // --aralik-0 .. --aralik-4 "margin-block": 5, "gap": 5, "font-size": 6, "color": 8, "background": 8, "border-radius": 3, "display": 4, }; const ONEKLER = ["", "hover:", "focus:", "gs:"]; // gs: genis ekran kesme noktasi const yardimciSayisi = Object.values(OLCEK).reduce((t, n) => t + n, 0) * ONEKLER.length; const YARDIMCI_BAYT = 26; // ornek: ".p-3{padding:var(--aralik-3)}" const yardimciToplam = yardimciSayisi * YARDIMCI_BAYT; console.log("--- yardimci sinif kumesi (bilesen sayisindan bagimsiz) ---"); console.log(` olcek: ${Object.keys(OLCEK).length} ozellik, toplam ${Object.values(OLCEK).reduce((t, n) => t + n, 0)} deger`); console.log(` onek sayisi: ${ONEKLER.length} (${ONEKLER.map((o) => o || "(oneksiz)").join(", ")})`); console.log(` uretilen sinif sayisi: ${yardimciSayisi}`); console.log(` yaklasik boyut: ${yardimciToplam} bayt`); // Bilesen yazimi: her yeni bilesen yeni kurallar ve yeni bayt ekler. const BILESEN_KURAL = 5; // bilesen basina ortalama kural const KURAL_BAYT = 62; // ortalama secici + bildirim govdesi console.log("\n--- iki yazimin bilesen sayisina gore boyutu ---"); console.log("bilesen".padStart(8) + "bilesen yazimi".padStart(18) + "yardimci yazimi".padStart(18) + " kucuk olan"); for (const n of [5, 10, 20, 40, 60, 80, 120]) { const bilesenToplam = n * BILESEN_KURAL * KURAL_BAYT; console.log( String(n).padStart(8) + `${bilesenToplam} bayt`.padStart(18) + `${yardimciToplam} bayt`.padStart(18) + " " + (bilesenToplam < yardimciToplam ? "bilesen yazimi" : "yardimci yazimi"), ); } const esik = Math.ceil(yardimciToplam / (BILESEN_KURAL * KURAL_BAYT)); console.log(` esik: ${esik} bilesenden sonra yardimci kume daha kucuk kalir`); // --- ayni bildirimin bilesenler arasinda kac kez yinelendigi --- const BILESENLER = { "olcum-kart": ["padding: var(--aralik-1)", "border-radius: 4px", "display: grid", "gap: var(--aralik-0)"], "yan-bilgi-kutu": ["padding: var(--aralik-1)", "border-radius: 4px", "display: grid"], "kunye": ["padding: var(--aralik-1)", "display: flex", "gap: var(--aralik-0)"], "olcum-suzgeci": ["display: flex", "gap: var(--aralik-0)", "padding: var(--aralik-0)"], }; const sayac = new Map(); for (const bildirimler of Object.values(BILESENLER)) for (const b of bildirimler) sayac.set(b, (sayac.get(b) ?? 0) + 1); console.log("\n--- bildirimlerin bilesenler arasinda yinelenmesi ---"); const toplamBildirim = [...sayac.values()].reduce((t, n) => t + n, 0); for (const [b, n] of [...sayac.entries()].sort((x, y) => y[1] - x[1])) console.log(` ${b.padEnd(30)} ${n} bilesende`); console.log(` toplam bildirim: ${toplamBildirim}, ayri bildirim: ${sayac.size}, yineleme: ${toplamBildirim - sayac.size}`); // --- belgedeki sinif listesi uzunlugu --- console.log("\n--- ayni kutunun iki yazimi ---"); const kartYardimci = "grid gap-0 p-1 br-1 bg-zemin"; const kartBilesen = "olcum-kart"; console.log(` yardimci yazimi : class="${kartYardimci}" (${kartYardimci.length} karakter, ${kartYardimci.split(" ").length} sinif)`); console.log(` bilesen yazimi : class="${kartBilesen}" (${kartBilesen.length} karakter, 1 sinif)`); console.log(` kart belgede 12 kez geciyorsa fark: ${(kartYardimci.length - kartBilesen.length) * 12} karakter`);
--- yardimci sinif kumesi (bilesen sayisindan bagimsiz) ---
olcek: 8 ozellik, toplam 44 deger
onek sayisi: 4 ((oneksiz), hover:, focus:, gs:)
uretilen sinif sayisi: 176
yaklasik boyut: 4576 bayt
--- iki yazimin bilesen sayisina gore boyutu ---
bilesen bilesen yazimi yardimci yazimi kucuk olan
5 1550 bayt 4576 bayt bilesen yazimi
10 3100 bayt 4576 bayt bilesen yazimi
20 6200 bayt 4576 bayt yardimci yazimi
40 12400 bayt 4576 bayt yardimci yazimi
60 18600 bayt 4576 bayt yardimci yazimi
80 24800 bayt 4576 bayt yardimci yazimi
120 37200 bayt 4576 bayt yardimci yazimi
esik: 15 bilesenden sonra yardimci kume daha kucuk kalir
--- bildirimlerin bilesenler arasinda yinelenmesi ---
padding: var(--aralik-1) 3 bilesende
gap: var(--aralik-0) 3 bilesende
border-radius: 4px 2 bilesende
display: grid 2 bilesende
display: flex 2 bilesende
padding: var(--aralik-0) 1 bilesende
toplam bildirim: 13, ayri bildirim: 6, yineleme: 7
--- ayni kutunun iki yazimi ---
yardimci yazimi : class="grid gap-0 p-1 br-1 bg-zemin" (28 karakter, 5 sinif)
bilesen yazimi : class="olcum-kart" (10 karakter, 1 sinif)
kart belgede 12 kez geciyorsa fark: 216 karakter
İlk iki blok iki büyüme eğrisini karşılaştırıyor. Yardımcı küme sabittir: sekiz özellik, kırk dört değer ve dört önek 176 sınıf üretiyor ve bu sayı kaç bileşen yazıldığından etkilenmiyor. Bileşen yazımı ise doğrusal büyüyor.
Modelin verdiği eşik on beş bileşen. Bu sayı kesin bir değer değildir; ölçek genişliğine, önek sayısına ve bileşen başına kural sayısına bağlıdır. Verdiği bilgi eşiğin kendisi değil, iki eğrinin biçimidir: biri sabit, diğeri artan.
Üçüncü blok yinelemeyi sayıyor. Dört bileşende on üç bildirim var ama bunların yalnız altısı ayrı; yedi bildirim yineleniyor. Yardımcı sınıflar tam olarak bu altı bildirimi tek kural hâline getirir.
Yineleme Kaybolmaz, Yer Değiştirir
Dördüncü blok yaklaşımın bedelini gösteriyor. Aynı kutu bileşen yazımında on karakter, yardımcı yazımında yirmi sekiz karakter; kart belgede on iki kez geçtiğinde fark iki yüz on altı karaktere çıkıyor.
Biçem dosyasından silinen yineleme belgeye taşınmıştır. Toplam bayt hesabı yapılırken bu taraf da sayılmalıdır; iki dosya birlikte gönderilir.
Ama iki yineleme aynı türden değildir. Biçem dosyasındaki yineleme elle yönetilir: bir değeri değiştirmek dört kuralı bulmayı gerektirir. Belgedeki yineleme genellikle bir şablon ya da bileşen soyutlamasının içindedir; kart bir kez yazılır, on iki kez üretilir. Yardımcı sınıf yaklaşımı bu yüzden şablon üreten bir katmanı varsayar; düz yazılmış belgelerde yineleme gerçekten elle yönetilir.
Durum ve Kesme Noktası Önekleri
Yardımcı sınıf tek bildirim yazdığı için sözde sınıflara ve ortam sorgularına doğrudan yer yoktur. Çözüm, koşulu ada yazmaktır:
.p-1 { padding: var(--aralik-1); } .hover\:p-2:hover { padding: var(--aralik-2); } @media (min-width: 48rem) { .gs\:p-2 { padding: var(--aralik-2); } }
Ad içindeki iki nokta üst üste, seçicide ters eğik çizgiyle kaçırılır; belgede hover:p-2
yazılır, seçicide .hover\:p-2 olarak eşleşir.
Bunun bedeli kümenin çarpan kadar büyümesidir. Çıktının ilk bloğunda dört önek, kırk dört değeri 176 sınıfa çıkarıyor. Her yeni durum ve her yeni kesme noktası kümeyi bir kat daha büyütür; üretilmiş kümeden yalnız belgede geçen sınıfların ayıklanması bu yüzden bu yaklaşımın ayrılmaz parçasıdır — ve üçüncü dersteki uyarı burada da geçerlidir: adlar kaynakta tam metin olarak geçmelidir.
Nerede Kırılır
Üç yerde. Birincisi, ölçek dışında bir değer gerektiğinde: bir görselin belirli bir en–boy oranı ya da içerikten gelen bir ölçü kapalı ölçekte yoktur ve tek seferlik bir kural yazmak gerekir.
İkincisi okunurluktur. Uzun bir sınıf listesi kutunun ne olduğunu değil nasıl göründüğünü
söyler. class="olcum-kart" yazan bir belge kendini açıklar; on sınıflık bir liste
açıklamaz.
Üçüncüsü karmaşık seçici gerektiren durumlardır. Kardeşe göre biçim, alt ögeye göre biçim ya da bir üst ögenin durumuna bağlı biçim tek bildirimlik sınıflara sığmaz.
Karma Kullanım
İki yaklaşım birbirini dışlamaz ve pratikte sınır şu ölçütle çizilir: yapı yinelenmiyorsa yardımcı sınıf, yineleniyorsa bileşen sınıfı.
Sayfada bir kez geçen bir bölümün iç boşluğunu ayarlamak için ad üretmek gereksizdir; on iki kez geçen bir kartın beş bildirimini on iki yere kopyalamak da gereksizdir. Ölçek her iki yazımda da aynı özel özelliklerden okunur, dolayısıyla iki katman aynı tasarım kısıtını paylaşır.
İstasyon Sayfasında
/* yardimcilar.css — kapalı ölçekten üretilen tek bildirimlik sınıflar */ .p-0 { padding: var(--aralik-0); } .p-1 { padding: var(--aralik-1); } .gap-0 { gap: var(--aralik-0); } .gap-1 { gap: var(--aralik-1); } .grid { display: grid; } .flex { display: flex; } .bg-zemin { background-color: var(--zemin); } .metin-soluk { color: var(--metin-soluk); }
Bu küme, ölçüm istasyonu sayfasında tek seferlik ayarlar için kullanılır: künyenin alt boşluğu, konum bölümünün iç boşluğu, kaynak notunun rengi. Ölçüm kartı ise bileşen sınıfı olarak kalır — sayfada on iki kez geçer ve kendi varyantları vardır.
Ayrım bir kurala bağlanabilir: bir sınıf adı belgede bir kez geçiyorsa yardımcı sınıflarla yazılabilir; iki kereden fazla geçiyorsa bileşen olmayı hak etmiştir.
Özet
- Yardımcı sınıf tek bildirim yazar ve değerini kapalı bir ölçekten alır; yaklaşımın asıl savunusu kısalık değil, ölçek dışı değeri imkânsız kılan kısıttır.
- Yardımcı kümenin boyutu bileşen sayısından bağımsızdır; bileşen yazımı doğrusal büyür ve iki eğri belirli bir bileşen sayısında kesişir.
- Yineleme ortadan kalkmaz, biçem dosyasından belgeye taşınır; yaklaşım şablon üreten bir katmanı varsayar.
- Durum ve kesme noktası önekleri kümeyi çarpan kadar büyütür; kullanılmayan sınıfların ayıklanması bu yüzden yaklaşımın parçasıdır.
- Yapı yinelenmiyorsa yardımcı sınıf, yineleniyorsa bileşen sınıfı; iki katman aynı özel özellik ölçeğini paylaşır.
Sonraki Adım
Bu konuda beş ayrı yazım yaklaşımı ele alındı ve hepsi aynı soruyu farklı yerden yanıtladı: biçem nasıl düzenlenir. Bir soru daha var ve tarayıcı tarafından sorulur — biçem dosyasının kendisi sayfanın açılışını ne kadar geciktirir, seçiciler eşleştirilirken ne kadar iş yapılır? Sonraki ders biçemin başarım maliyetini ele alır ve kursu kapatır.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.