İçeriğe geç
academia.sh

Ders 10 / 19

Kesme Noktaları ve Izgara

Kesme noktalarının düzen yapılandırması taşıyan belirteçlere dönüştürülmesi, sütun aritmetiğinin her kesme noktasında denetlenmesi, boşta kalan kesme noktasının saptanması ve sınırların içerik ölçütünden türetilmesi.

İçindekiler

Belirteçlerin şimdiye kadarki tamamı tek bir görüntü alanı varsayımıyla kuruldu. Renk rolleri genişlikten bağımsızdır, tipografi basamakları da öyle. Aralık ve boyut belirteçleri ise öyle değil: kenar boşluğu dar bir ekranda 16, geniş bir ekranda 24 piksel olur ve sütun sayısı tümüyle değişir.

Kesme noktası (breakpoint) bu değişimin nerede olacağını söyler. Duyarlı Tasarım İlkesi dersinde kesme noktası bir ortam sorgusu eşiği olarak tanıtılmıştı; sistem düzeyinde ondan fazlasıdır. Bir kesme noktası tek bir sayı değil, o eşikten sonra geçerli olan bütün düzen kararlarını taşıyan bir kayıttır: sütun sayısı, kenar boşluğu, oluk ve kapsayıcının üst sınırı. Bu ders o kaydı belirteç hâline getirir ve kayıtlar arasındaki aritmetiği denetler.

Kesme Noktası Bir Yapılandırma Taşır

Izgara Sistemleri dersinde sütun genişliğinin bağımlı bir büyüklük olduğu gösterilmişti:

su¨tun=kapsayıcı2kenar bos¸lug˘u(n1)olukn\text{sütun} = \frac{\text{kapsayıcı} - 2 \cdot \text{kenar boşluğu} - (n - 1) \cdot \text{oluk}}{n}

Kesme noktası kümesi bu bağıntının girdilerini genişlik aralıklarına dağıtır. Denetimin işi her aralıkta bağıntının anlamlı bir sonuç verdiğini ve aralıkların birbirine göre tutarlı olduğunu göstermektir.

Denetim beş soruya yanıt arar. Sütun genişliği tam sayı mı çıkıyor? Kenar boşluğu ve oluk değerleri aralık ölçeğinden mi geliyor? Bir kesme noktası bir öncekinden farklı bir yapılandırma taşıyor mu? İçerik ölçütleri hangi genişlikten itibaren karşılanıyor? Kapsayıcının üst sınırı neye göre seçilmiş?

// kesme.mjs — kesme noktasi kumesinin sutun aritmetigiyle denetlenmesi

const ARALIK_OLCEGI = [4, 8, 12, 16, 20, 24, 32, 48, 64, 96];

// Her kesme noktasi bir duzen yapilandirmasi tasir. ustSinir null ise kapsayici akiskandir.
const KESME = [
  { ad: "dar", alt: 320, sutun: 4, kenar: 16, oluk: 16, ustSinir: null },
  { ad: "orta", alt: 640, sutun: 8, kenar: 24, oluk: 24, ustSinir: null },
  { ad: "genis", alt: 1024, sutun: 12, kenar: 24, oluk: 24, ustSinir: null },
  { ad: "cok-genis", alt: 1440, sutun: 12, kenar: 24, oluk: 24, ustSinir: 1200 },
  { ad: "ultra", alt: 1920, sutun: 12, kenar: 24, oluk: 24, ustSinir: 1200 },
];

const kapsayici = (k, gorusAlani) => (k.ustSinir === null ? gorusAlani : Math.min(gorusAlani, k.ustSinir));
const sutunGenisligi = (kapsayici, k) => (kapsayici - 2 * k.kenar - (k.sutun - 1) * k.oluk) / k.sutun;
const acilim = (n, sutun, oluk) => n * sutun + (n - 1) * oluk;

console.log("kesme      alt sinir  sutun  kenar  oluk  ust sinir  kapsayici  sutun genisligi  tam sayi");
for (const k of KESME) {
  const kap = kapsayici(k, k.alt);
  const s = sutunGenisligi(kap, k);
  console.log(
    `${k.ad.padEnd(10)} ${String(k.alt).padStart(9)} ${String(k.sutun).padStart(6)} ${String(k.kenar).padStart(6)} ` +
      `${String(k.oluk).padStart(5)} ${String(k.ustSinir ?? "-").padStart(10)} ${String(kap).padStart(10)} ` +
      `${s.toFixed(3).padStart(16)} ${(Number.isInteger(s) ? "evet" : "hayir").padStart(9)}`
  );
}

// Aralik degerleri olcekten mi geliyor?
console.log("\nkesme      kenar olcekte  oluk olcekte");
for (const k of KESME) {
  console.log(
    `${k.ad.padEnd(10)} ${(ARALIK_OLCEGI.includes(k.kenar) ? "evet" : "HAYIR").padStart(13)} ` +
      `${(ARALIK_OLCEGI.includes(k.oluk) ? "evet" : "HAYIR").padStart(13)}`
  );
}

// Bosta kalan kesme noktasi: bir onceki ile ayni duzen yapilandirmasini tasiyor.
const imza = (k) => `${k.sutun}/${k.kenar}/${k.oluk}/${k.ustSinir}`;
console.log("\nkesme      imza               onceki ile ayni mi");
for (let i = 0; i < KESME.length; i++) {
  const ayni = i > 0 && imza(KESME[i]) === imza(KESME[i - 1]);
  console.log(`${KESME[i].ad.padEnd(10)} ${imza(KESME[i]).padEnd(18)} ${ayni ? "EVET (bosta)" : "hayir"}`);
}

// Akiskan aralikta sutun genisligi kac gorus alani genisliginde tam sayi cikiyor?
console.log("\nkesme      aralik            ornek genislik  tam sayi ciktigi genislik sayisi");
for (const k of KESME) {
  const ust = KESME[KESME.indexOf(k) + 1]?.alt ?? 2560;
  let tam = 0;
  let ornek = 0;
  for (let w = k.alt; w < ust; w++) {
    ornek++;
    if (Number.isInteger(sutunGenisligi(kapsayici(k, w), k))) tam++;
  }
  console.log(
    `${k.ad.padEnd(10)} ${(k.alt + " - " + (ust - 1)).padEnd(17)} ${String(ornek).padStart(14)} ` +
      `${(tam + "  (" + ((100 * tam) / ornek).toFixed(1) + "%)").padStart(31)}`
  );
}

// Icerik olcutu: suzgec paneli en az 270 px, sonuc listesi en az 480 px istiyor
// (Izgara Sistemleri dersinde hesaplanan degerler).
const SUZGEC_EN_AZ = 270;
const LISTE_EN_AZ = 480;
console.log("\nkesme      bolunme   suzgec (px)  liste (px)  suzgec >=270  liste >=480  karar");
for (const k of KESME) {
  const kap = kapsayici(k, k.alt);
  const s = sutunGenisligi(kap, k);
  let secilen = null;
  for (let a = 1; a < k.sutun; a++) {
    const suzgec = acilim(a, s, k.oluk);
    const liste = acilim(k.sutun - a, s, k.oluk);
    if (suzgec >= SUZGEC_EN_AZ && liste >= LISTE_EN_AZ) {
      secilen = { a, suzgec, liste };
      break;
    }
  }
  if (secilen) {
    console.log(
      `${k.ad.padEnd(10)} ${(secilen.a + "+" + (k.sutun - secilen.a)).padEnd(9)} ${secilen.suzgec.toFixed(1).padStart(11)} ` +
        `${secilen.liste.toFixed(1).padStart(11)} ${"evet".padStart(13)} ${"evet".padStart(12)}  iki sutun`
    );
  } else {
    console.log(
      `${k.ad.padEnd(10)} ${"-".padEnd(9)} ${"-".padStart(11)} ${"-".padStart(11)} ${"-".padStart(13)} ${"-".padStart(12)}  tek sutun`
    );
  }
}

// Iki sutunlu duzenin acildigi en kucuk gorus alani genisligi
const genis = KESME.find((k) => k.ad === "genis");
let esik = null;
for (let w = 320; w <= 1600; w++) {
  const s = sutunGenisligi(kapsayici(genis, w), genis);
  const uygun = [...Array(genis.sutun - 1).keys()]
    .map((i) => i + 1)
    .some((a) => acilim(a, s, genis.oluk) >= SUZGEC_EN_AZ && acilim(genis.sutun - a, s, genis.oluk) >= LISTE_EN_AZ);
  if (uygun) {
    esik = w;
    break;
  }
}
console.log(`\n12 sutunlu yapilandirmayla iki sutunlu duzenin acildigi en kucuk genislik: ${esik} px`);
console.log(`genis kesme noktasinin alt siniri: ${genis.alt} px  ->  ${genis.alt >= esik ? "icerik olcutunu karsiliyor" : "ERKEN"}`);

// Ust sinirin gerekcesi: satir uzunlugu. 16 px metinde ortalama karakter genisligi 7.005 px
// (Satir Uzunlugu ve Araligi dersinde olculdu); 75 karakter ust siniri 525 px eder.
const KARAKTER_PX = 7.005;
console.log("\nkapsayici  9 sutun acilimi  karakter  45-75 araliginda mi");
for (const kap of [1024, 1200, 1440, 1920]) {
  const k = { sutun: 12, kenar: 24, oluk: 24 };
  const s = sutunGenisligi(kap, k);
  const en = acilim(9, s, k.oluk);
  const karakter = en / KARAKTER_PX;
  console.log(
    `${String(kap).padStart(9)} ${en.toFixed(1).padStart(16)} ${karakter.toFixed(1).padStart(9)} ` +
      `${(karakter <= 75 ? "evet" : "HAYIR").padStart(20)}`
  );
}
kesme      alt sinir  sutun  kenar  oluk  ust sinir  kapsayici  sutun genisligi  tam sayi
dar              320      4     16    16          -        320           60.000      evet
orta             640      8     24    24          -        640           53.000      evet
genis           1024     12     24    24          -       1024           59.333     hayir
cok-genis       1440     12     24    24       1200       1200           74.000      evet
ultra           1920     12     24    24       1200       1200           74.000      evet

kesme      kenar olcekte  oluk olcekte
dar                 evet          evet
orta                evet          evet
genis               evet          evet
cok-genis           evet          evet
ultra               evet          evet

kesme      imza               onceki ile ayni mi
dar        4/16/16/null       hayir
orta       8/24/24/null       hayir
genis      12/24/24/null      hayir
cok-genis  12/24/24/1200      hayir
ultra      12/24/24/1200      EVET (bosta)

kesme      aralik            ornek genislik  tam sayi ciktigi genislik sayisi
dar        320 - 639                    320                     80  (25.0%)
orta       640 - 1023                   384                     48  (12.5%)
genis      1024 - 1439                  416                      34  (8.2%)
cok-genis  1440 - 1919                  480                   480  (100.0%)
ultra      1920 - 2559                  640                   640  (100.0%)

kesme      bolunme   suzgec (px)  liste (px)  suzgec >=270  liste >=480  karar
dar        -                   -           -             -            -  tek sutun
orta       -                   -           -             -            -  tek sutun
genis      4+8             309.3       642.7          evet         evet  iki sutun
cok-genis  3+9             270.0       858.0          evet         evet  iki sutun
ultra      3+9             270.0       858.0          evet         evet  iki sutun

12 sutunlu yapilandirmayla iki sutunlu duzenin acildigi en kucuk genislik: 888 px
genis kesme noktasinin alt siniri: 1024 px  ->  icerik olcutunu karsiliyor

kapsayici  9 sutun acilimi  karakter  45-75 araliginda mi
     1024            726.0     103.6                HAYIR
     1200            858.0     122.5                HAYIR
     1440           1038.0     148.2                HAYIR
     1920           1398.0     199.6                HAYIR

Boşta Kalan Kesme Noktası

Üçüncü tablo en doğrudan bulguyu veriyor. ultra kesme noktası, cok-genis ile aynı yapılandırmayı taşıyor: 12 sütun, 24 kenar boşluğu, 24 oluk, 1200 piksel üst sınır. İkisi arasında hiçbir düzen kararı değişmiyor.

Böyle bir kesme noktası bir kural üretmez, yalnız bir ad üretir. Bedeli üç yerde ödenir: biçem dosyası bir ortam sorgusu daha taşır, sınama listesi bir genişlik daha içerir ve yeni gelen biri bu genişlikte ne değiştiğini bulmaya çalışır. Boşta kalan kesme noktası, önceki derslerdeki boşta kalan belirtecin düzen tarafındaki karşılığıdır ve aynı biçimde kaldırılır.

Kesme noktalarının sayısı bir hedef değildir. Her kesme noktası bir düzen kararı değiştirmelidir; değiştirmiyorsa kesme noktası değil, bir sayıdır.

Tam Sayı Sütun Bir Kural Olamaz

Dördüncü tablo düzen aritmetiğinin en çok yanlış anlaşılan yanını ölçüyor. Akışkan aralıklarda sütun genişliği çok nadiren tam sayı çıkıyor: dar aralıkta genişliklerin yüzde 25’inde, orta aralıkta yüzde 12.5’inde, geniş aralıkta yalnız yüzde 8.2’sinde.

Kapsayıcının üst sınırla sabitlendiği iki aralıkta oran yüzde 100. Nedeni açıktır: kapsayıcı sabitlendiğinde sütun genişliği de sabitlenir ve tek bir değer hesaplanır.

Buradan çıkan sonuç, tam sayı sütun genişliğinin bir tasarım hedefi olamayacağıdır. Akışkan bir ızgarada sütun genişliği sürekli değişir; onu tam sayıya zorlamak, kapsayıcıyı tam sayı katlarına yuvarlamak demektir ve bu, kenarlarda düzensiz boşluklar bırakır. Doğru yaklaşım sütun genişliğini hiç yazmamaktır: ızgara pay birimleriyle tanımlanır, sütun genişliği çizim aşamasında hesaplanır ve hizalar ızgaranın kendisinden gelir.

Hesabın işlevi de burada netleşir. Sütun genişliği bir bildirim için değil, içerik ölçütlerini sınamak için hesaplanır: bir bloğun kaç piksel yer bulacağı ve bunun yeterli olup olmadığı.

Kesme Noktası İçerikten Türetilir, Aygıttan Değil

Beşinci ve altıncı bloklar kesme noktası değerlerinin nereden geleceğini yanıtlıyor. Süzgeç paneli en az 270, sonuç listesi en az 480 piksel istiyor; bu değerler Izgara Sistemleri dersinde içerik ölçütlerinden hesaplanmıştı.

Dar ve orta kesme noktalarında hiçbir bölünme iki ölçütü birden karşılamıyor; düzen tek sütunlu kalıyor. Geniş kesme noktasında 4+8 bölünmesi çalışıyor, çok geniş kesme noktasında 3+9.

Altıncı blok bir uyumsuzluk gösteriyor. 12 sütunlu yapılandırmayla iki sütunlu düzenin açılabildiği en küçük genişlik 888 piksel; oysa genis kesme noktasının alt sınırı 1024. Aradaki 136 piksellik bant boyunca düzen tek sütunlu kalıyor, ama içerik iki sütuna sığıyor.

Bu, kesme noktası değerlerinin nereden seçildiğine dair bir bulgudur. 1024 bir içerik ölçütü değil, bir aygıt genişliğidir; hesaptan değil alışkanlıktan gelir. İçerikten türetilen değer 888’dir ve aralık ölçeğine yakın bir yuvarlama ile 896 alınabilir. Beş Yıl testinin düzen tarafındaki karşılığı budur: aygıt genişliklerine bağlanan bir kesme noktası, aygıtlar değiştiğinde yanlış hâle gelir; içerik ölçütüne bağlanan kesme noktası, içerik değişmediği sürece doğru kalır.

Üst Sınır da Bir İçerik Kararıdır

Son tablo kapsayıcının üst sınırının gerekçesini arıyor ve beklenmedik bir sonuç veriyor. Dokuz sütunluk sonuç listesi alanı 1024 piksellik kapsayıcıda 726, 1200’de 858, 1920’de 1398 piksel genişliğinde. Satır Uzunluğu ve Aralığı dersinde ölçülen ortalama karakter genişliğiyle bu, sırasıyla 103.6, 122.5 ve 199.6 karakter eder. Dördü de 45–75 aralığının dışında.

Bu, üst sınırın satır uzunluğunu tek başına çözmediğini gösteriyor. 1200 piksellik üst sınır sonuç listesi alanını 858 piksele indiriyor ama 858 piksel hâlâ 122 karakterlik bir satır demektir.

Doğru okuma şudur: kapsayıcı üst sınırı düzenin üst sınırıdır, metnin değil. Metnin üst sınırı ayrı bir belirteçtir ve sütun sayısına değil karakter sayısına bağlıdır. Kayıt kartındaki özet paragrafı 9 sütunun tamamını değil, kendi ölçü sınırını kullanır. İki sınır karıştırıldığında ya düzen gereksiz yere daraltılır ya da metin okunamayacak kadar uzar.

Yazılı Biçim

Kesme noktaları belirteç olarak tanımlanır, ama ortam sorgusu koşullarında doğrudan kullanılamazlar: bir ortam sorgusu koşulu özel özellik okuyamaz. Bu, belirteç sisteminin biçemle olan sınırının ikinci örneğidir; birincisi kontrast sözleşmesiydi.

:root {
  --kesme-orta: 640px;
  --kesme-genis: 896px;
  --kesme-cok-genis: 1440px;

  --izgara-sutun: 4;
  --izgara-kenar: var(--adim-4);
  --izgara-oluk: var(--adim-4);
  --izgara-ust-sinir: none;
}

@media (min-width: 640px) {
  :root {
    --izgara-sutun: 8;
    --izgara-kenar: var(--adim-6);
    --izgara-oluk: var(--adim-6);
  }
}

@media (min-width: 896px) {
  :root { --izgara-sutun: 12; }
}

@media (min-width: 1440px) {
  :root { --izgara-ust-sinir: 1200px; }
}

.izgara {
  display: grid;
  grid-template-columns: repeat(var(--izgara-sutun), 1fr);
  gap: var(--izgara-oluk);
  padding-inline: var(--izgara-kenar);
  max-width: var(--izgara-ust-sinir);
  margin-inline: auto;
}

Sorgu koşullarındaki sayılar elle yazıldığı için belirteç değerleriyle çakışma riski taşır. Çözüm, sorgu koşullarını belirteç dosyasından üreten bir derleme adımıdır: kesme noktası değerleri tek bir kaynakta durur, biçem dosyası oradan üretilir. Ön ve Son İşlemciler dersinde ayrılan iş bölümü burada uygulanır — sorgu koşulu derleme zamanına, sütun sayısı çalışma zamanına aittir.

Sütun genişliğinin hiçbir yerde yazmadığına dikkat edilmelidir. Izgara pay birimleriyle tanımlandığı için genişlik çizim aşamasında hesaplanır; bu dersteki hesap bildirim üretmek için değil, içerik ölçütlerini sınamak için yapıldı.

Özet

  • Kesme noktası bir sayı değil, o eşikten sonra geçerli olan bütün düzen kararlarını taşıyan bir yapılandırma kaydıdır: sütun sayısı, kenar boşluğu, oluk ve kapsayıcı üst sınırı.
  • Bir öncekiyle aynı yapılandırmayı taşıyan kesme noktası boştadır; kural üretmez, yalnız bakım yükü üretir ve kaldırılır.
  • Akışkan aralıklarda sütun genişliği nadiren tam sayı çıkar — geniş aralıkta genişliklerin yalnız yüzde 8.2’sinde. Tam sayı sütun bir tasarım hedefi olamaz; ızgara pay birimleriyle tanımlanır. Hesabın amacı bildirim üretmek değil, içerik ölçütlerini sınamaktır.
  • Kesme noktası değeri aygıt genişliğinden değil içerik ölçütünden türetilir; ölçülen kümede iki sütunlu düzen 888 pikselde açılabiliyorken kesme noktası 1024’te duruyor.
  • Kapsayıcı üst sınırı düzenin sınırıdır, metnin değil; metin ölçüsü ayrı bir belirteçtir ve karakter sayısına bağlıdır.
  • Ortam sorgusu koşulları özel özellik okuyamaz; kesme noktası değerleri tek kaynakta tutulup sorgu koşulları derleme zamanında üretilir.

Sonraki Adım

Temel katman burada tamamlanıyor: renk, tipografi, aralık, boyut ve düzen kararlarının hepsi adlandırılmış ve türetilebilir hâlde. Geriye tek bir eksik kalıyor. Renk Belirteçleri dersinde yirmi rolün yalnız sekizinin koyu tema karşılığı vardı; on iki hücre boştu. Bir sistemin birden çok temayı taşıması, her tema için ayrı bir değer listesi yazmak değil, temaları tek bir kuraldan türetmektir. Sonraki ders bu türetmeyi kurar: açık temadan koyu temayı ve bir marka temasını üretir, eksik belirteç raporunu kapatır ve belirteç kaynağından biçem çıktısını üretir.

İ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