İçeriğe geç
academia.sh

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.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat