İçeriğe geç
academia.sh

Ders 12 / 22

Tipografik Ölçek

Boyut basamaklarının bir taban ve bir orandan türetilmesi, yuvarlamanın komşu basamak oranını nasıl bozduğu, basamak bütçesinin hesabı ve düzeylerin basamaklara yerleştirilmesi.

İçindekiler

Önceki ders gövde metninin taban boyutunu bir yazı tipi kararına bağladı ve aynı görünen büyüklüğün ailelere göre farklı nominal boyutlar gerektirdiğini hesapladı. Ancak arayüzde tek bir boyut yoktur. Katalog arayüzü en az beş metin düzeyi taşıyor: sayfa başlığı, kayıt başlığı, ödünç alma düğmesinin metni, yazar adı ve üstveri. Bu beş sayı tek tek seçilirse ne olur?

Olan şudur: sayılar birbirinden bağımsız seçilir, aralarındaki oranlar rastgele çıkar ve Görsel Hiyerarşi dersinde konan 1.15 boyut oranı eşiği kimi çiftte tesadüfen tutturulur, kimi çiftte kaçırılır. Ölçek, bu tesadüfü ortadan kaldıran yapıdır: boyutlar tek tek seçilmez, bir tabandan ve bir orandan türetilir.

Ölçek Bir Üstel Dizidir

Tipografik ölçek (typographic scale), bir taban boyuttan başlayarak sabit bir oranla çarpılan ya da bölünen boyut basamakları dizisidir. n numaralı basamağın boyutu şu biçimde yazılır:

bn=Trnb_n = T \cdot r^{\,n}

Burada TT taban boyut, rr ölçek oranı, nn ise basamak numarasıdır. Taban basamağı sıfır kabul edilir; pozitif basamaklar büyür, negatif basamaklar küçülür. Ölçeğin verdiği güvence şudur: herhangi iki komşu basamağın oranı sabittir ve rr değerine eşittir. Ayrımı denetlemek için tek bir sayıya bakmak yeterli olur.

Bu yapı M14/K02 CSS ile Görsel Sunum kursunda modüler ölçek adıyla tanıtılmıştı; orada sorun bir bildirim yazma sorunuydu. Burada sorun karar sorunudur: hangi oran, kaç basamak ve hangi düzey hangi basamağa.

Yuvarlama Sabit Oranı Bozar

Formül sürekli bir dizi üretir; ekran ise metni tam sayı piksel değerlerinde daha kararlı çizer. Aradaki fark önemsiz görünür ama komşu basamak oranını doğrudan bozar.

// olcek.mjs — oran tabanli tipografik olcek uretimi ve yuvarlamanin ayrima etkisi

const TABAN = 16;          // govde metni boyutu (px)
const ADIMLAR = [-2, -1, 0, 1, 2, 3, 4];
const ORANLAR = [1.125, 1.200, 1.250, 1.333];
const ESIK = 1.15;         // Gorsel Hiyerarsi dersinde konan boyut orani esigi

function olcek(oran) {
  return ADIMLAR.map((n) => {
    const ham = TABAN * Math.pow(oran, n);
    return { n, ham, yuvarlanmis: Math.round(ham) };
  });
}

for (const oran of ORANLAR) {
  const s = olcek(oran);
  console.log(`\n--- oran ${oran.toFixed(3)} ---`);
  console.log("adim   ham (px)  yuvarlanmis  komsu orani (ham)  komsu orani (yuv)  esik");
  for (let i = 0; i < s.length; i++) {
    const a = s[i];
    if (i === 0) {
      console.log(
        `${String(a.n).padStart(4)} ${a.ham.toFixed(3).padStart(10)} ${String(a.yuvarlanmis).padStart(12)}` +
          `${"-".padStart(20)}${"-".padStart(19)}${"-".padStart(6)}`
      );
      continue;
    }
    const onceki = s[i - 1];
    const hamOran = a.ham / onceki.ham;
    const yuvOran = a.yuvarlanmis / onceki.yuvarlanmis;
    console.log(
      `${String(a.n).padStart(4)} ${a.ham.toFixed(3).padStart(10)} ${String(a.yuvarlanmis).padStart(12)}` +
        `${hamOran.toFixed(4).padStart(20)}${yuvOran.toFixed(4).padStart(19)}` +
        `${(yuvOran >= ESIK ? "gecti" : "KALDI").padStart(8)}`
    );
  }
}
--- oran 1.125 ---
adim   ham (px)  yuvarlanmis  komsu orani (ham)  komsu orani (yuv)  esik
  -2     12.642           13                   -                  -     -
  -1     14.222           14              1.1250             1.0769   KALDI
   0     16.000           16              1.1250             1.1429   KALDI
   1     18.000           18              1.1250             1.1250   KALDI
   2     20.250           20              1.1250             1.1111   KALDI
   3     22.781           23              1.1250             1.1500   gecti
   4     25.629           26              1.1250             1.1304   KALDI

--- oran 1.200 ---
adim   ham (px)  yuvarlanmis  komsu orani (ham)  komsu orani (yuv)  esik
  -2     11.111           11                   -                  -     -
  -1     13.333           13              1.2000             1.1818   gecti
   0     16.000           16              1.2000             1.2308   gecti
   1     19.200           19              1.2000             1.1875   gecti
   2     23.040           23              1.2000             1.2105   gecti
   3     27.648           28              1.2000             1.2174   gecti
   4     33.178           33              1.2000             1.1786   gecti

--- oran 1.250 ---
adim   ham (px)  yuvarlanmis  komsu orani (ham)  komsu orani (yuv)  esik
  -2     10.240           10                   -                  -     -
  -1     12.800           13              1.2500             1.3000   gecti
   0     16.000           16              1.2500             1.2308   gecti
   1     20.000           20              1.2500             1.2500   gecti
   2     25.000           25              1.2500             1.2500   gecti
   3     31.250           31              1.2500             1.2400   gecti
   4     39.063           39              1.2500             1.2581   gecti

--- oran 1.333 ---
adim   ham (px)  yuvarlanmis  komsu orani (ham)  komsu orani (yuv)  esik
  -2      9.005            9                   -                  -     -
  -1     12.003           12              1.3330             1.3333   gecti
   0     16.000           16              1.3330             1.3333   gecti
   1     21.328           21              1.3330             1.3125   gecti
   2     28.430           28              1.3330             1.3333   gecti
   3     37.897           38              1.3330             1.3571   gecti
   4     50.517           51              1.3330             1.3421   gecti

Birinci ölçek başarısız. Oranı 1.125 seçmek, eşiğin (1.15) altında bir ayrım seçmek demektir; yuvarlama bunu ne düzeltir ne de kötüleştirir, yalnızca düzensizleştirir. Gerçekleşen oranlar 1.0769 ile 1.1500 arasında salınıyor: bir basamak çiftinde artış yüzde 7.7, başka bir çiftte yüzde 15, yani tam iki katı. Ölçeğin verdiği tek güvence — komşu oranın sabit olması — yuvarlamayla birlikte kayboluyor.

Küçük boyutlarda salınımın büyümesi tesadüf değil. Yuvarlama hatası en çok bir yarım pikseldir; bu hatanın orana etkisi boyutla ters orantılıdır. 13 pikselde yarım piksel yüzde 3.8’lik bir sapma, 39 pikselde yüzde 1.3’lük bir sapmadır. Ölçeğin alt ucu, üst ucundan üç kat daha kırılgandır.

Diğer üç ölçekte yuvarlanmış oranların hepsi eşiği geçiyor. Oran büyüdükçe salınımın etkisi de göreli olarak küçülüyor: 1.333 oranlı ölçekte gerçekleşen oranlar 1.3125 ile 1.3571 arasında, yani en geniş oran en darının 1.034 katı.

Buradan çıkan kural şu biçimde yazılabilir: ölçek oranı, ayrım eşiğinden belirgin biçimde büyük seçilir. Eşiğe eşit ya da yakın bir oran, yuvarlamanın hangi yönde çalıştığına göre kimi basamak çiftinde eşiğin altına düşer.

Basamak Bütçesi

Oranı büyütmenin bir bedeli vardır. Arayüzün kullanabileceği boyut aralığı sınırlıdır: alt ucu okunabilirlik, üst ucu ekranda kapladığı yer belirler. Oran büyüdükçe bu aralığa daha az basamak sığar.

// basamak.mjs — olcegin basamak butcesi ve duzeylerin basamaklara yerlestirilmesi

const TABAN = 16;
const EN_KUCUK = 12;   // altina inilmeyecek govde-disi metin boyutu
const EN_BUYUK = 40;   // katalog arayuzunde gereken en buyuk baslik boyutu

console.log("oran    basamak sayisi (12-40 px arasi)  ilk basamak  son basamak");
for (const oran of [1.125, 1.2, 1.25, 1.333, 1.5]) {
  const altAdim = Math.ceil(Math.log(EN_KUCUK / TABAN) / Math.log(oran));
  const ustAdim = Math.floor(Math.log(EN_BUYUK / TABAN) / Math.log(oran));
  const sayi = ustAdim - altAdim + 1;
  const ilk = Math.round(TABAN * Math.pow(oran, altAdim));
  const son = Math.round(TABAN * Math.pow(oran, ustAdim));
  console.log(
    `${oran.toFixed(3)} ${String(sayi).padStart(28)} ${String(ilk).padStart(12)} ${String(son).padStart(12)}`
  );
}

// Katalog arayuzunun duzeyleri, 1.25 oranli olcegin basamaklarina yerlestirildi.
const ORAN = 1.25;
const boyut = (n) => Math.round(TABAN * Math.pow(ORAN, n));

const duzeyler = [
  { ad: "sayfa basligi", adim: 3, agirlik: 700 },
  { ad: "kayit basligi", adim: 1, agirlik: 600 },
  { ad: "dugme metni",   adim: 0, agirlik: 600 },
  { ad: "yazar",         adim: 0, agirlik: 400 },
  { ad: "ustveri",       adim: -1, agirlik: 400 },
];

const ESIK = { boyutOrani: 1.15, agirlikFarki: 200 };

console.log("\nduzey           adim  boyut(px)  agirlik");
for (const d of duzeyler) {
  console.log(
    `${d.ad.padEnd(15)} ${String(d.adim).padStart(4)} ${String(boyut(d.adim)).padStart(9)} ${String(d.agirlik).padStart(8)}`
  );
}

console.log("\nkomsu duzey cifti               boyut orani  agirlik farki  gecen kanal");
for (let i = 0; i < duzeyler.length - 1; i++) {
  const ust = duzeyler[i];
  const alt = duzeyler[i + 1];
  const bOran = boyut(ust.adim) / boyut(alt.adim);
  const aFark = ust.agirlik - alt.agirlik;
  const gecen = [];
  if (bOran >= ESIK.boyutOrani) gecen.push("boyut");
  if (aFark >= ESIK.agirlikFarki) gecen.push("agirlik");
  const etiket = `${ust.ad} > ${alt.ad}`;
  console.log(
    `${etiket.padEnd(31)} ${bOran.toFixed(3).padStart(11)} ${String(aFark).padStart(14)}  ${gecen.length ? gecen.join("+") : "ZAYIF"}`
  );
}
oran    basamak sayisi (12-40 px arasi)  ilk basamak  son basamak
1.125                           10           13           36
1.200                            7           13           40
1.250                            6           13           39
1.333                            5           12           38
1.500                            3           16           36

duzey           adim  boyut(px)  agirlik
sayfa basligi      3        31      700
kayit basligi      1        20      600
dugme metni        0        16      600
yazar              0        16      400
ustveri           -1        13      400

komsu duzey cifti               boyut orani  agirlik farki  gecen kanal
sayfa basligi > kayit basligi         1.550            100  boyut
kayit basligi > dugme metni           1.250              0  boyut
dugme metni > yazar                   1.000            200  agirlik
yazar > ustveri                       1.231              0  boyut

Birinci tablo ölçek oranı seçiminin gerçek ödünleşimini gösteriyor. Aynı 12–40 piksel aralığına 1.125 oranıyla on basamak, 1.5 oranıyla üç basamak sığıyor. Bir önceki hesap 1.125 oranının eşiği tutturamadığını göstermişti; bu tablo da 1.5 oranının yalnızca üç düzeye yer bıraktığını gösteriyor. Katalog arayüzü beş düzey istiyor, dolayısıyla 1.5 oranı doğrudan elenir. Kalan aday 1.2, 1.25 ve 1.333; hepsi eşiği geçiyor ve hepsi beş düzeye yetiyor.

Karar 1.25 oranıyla verildi. Gerekçe, ikinci tablodaki boşluktur: altı basamak, beş düzey için bir basamaklık pay bırakır. Ölçeğin dolu olması, sonradan bir düzey eklenmesi gerektiğinde ölçeğin tamamının yeniden hesaplanması demektir.

Her Düzey Yeni Bir Basamak İstemez

Üçüncü tablodaki düzey yerleşiminde iki nokta dikkat çekiyor.

Birincisi, düğme metni ile yazar adı aynı basamakta duruyor: ikisi de sıfırıncı basamak, 16 piksel. Boyut oranı 1.000; boyut kanalı ayrım üretmiyor. Ayrım ağırlıkta kuruluyor ve 200 birimlik fark eşiği geçiyor. Görsel Hiyerarşi dersindeki iki kanal kuralı burada üçüncü bir kanalla karşılanıyor: düğme metni dolgulu bir yüzeyin üzerinde duruyor, yazar adı düz zeminde. Yüzey, bu tabloda görünmeyen ama gerçekte çalışan bir kanaldır ve Renk Sistemi dersinin konusudur.

İkincisi, dördüncü satırdaki karşılaştırma aslında hiyerarşik bir çift değil. Düğme metni ile yazar adı aynı görsel alanda yarışmaz; biri eylem bölgesinde, diğeri kayıt satırının içindedir. Komşuluk denetimi düzeyleri sıralı bir liste sanar; hiyerarşi ise yalnızca aynı anda görülen ögeler arasında anlamlıdır. Tablo bir uyarı üretmediği için bu ayrım sorun çıkarmadı, ancak “ZAYIF” çıkan bir satırın gerçek bir sorun olup olmadığı her zaman bu soruyla denetlenir.

Son satır ise ilk dersteki bir bulgunun kapanışıdır. Yazar ile üstveri arasındaki ayrım o derste yalnız kontrast kanalında duruyordu ve tek bacaklı sayılmıştı. Ölçek, üstveriyi 14 yerine 13 piksele indirerek boyut oranını 1.231’e çıkardı; artık ayrım hem boyutta hem kontrastta duruyor. Basamak kararı, tek tek boyut seçmenin çözemediği bir sorunu ölçeğin kendi yapısıyla çözdü.

Ölçeğin Yazılı Biçimi

Ölçek bir hesap olarak kalırsa her kullanımda yeniden yapılır ve sapar. Yazılı biçimi, basamakların adlandırılmış değerlere dönüştürülmesidir:

:root {
  --boyut--1: 13px;
  --boyut-0: 16px;
  --boyut-1: 20px;
  --boyut-2: 25px;
  --boyut-3: 31px;
}

Adların basamak numarasını taşıması, “başlık” ya da “küçük” gibi anlam taşımasından daha dayanıklıdır. Anlam taşıyan adlar arayüz değiştiğinde yalan söylemeye başlar: “başlık” adlı değer bir gün başlık olmayan bir yerde kullanılır. Basamak numarası ise yalnızca ölçekteki konumu bildirir ve o konum değişmez.

Bu listede ara değer yoktur ve olmamalıdır. Bir düzey için 18 piksel gerektiği hissi doğduğunda yanıt yeni bir değişken eklemek değil, düzeyin hangi basamağa ait olduğuna karar vermektir. Ölçeğin dışına çıkan her sayı, ölçeğin verdiği güvenceyi o noktada iptal eder.

Özet

  • Tipografik ölçek, boyutları bir taban ve bir orandan üstel olarak türetir; sağladığı güvence, komşu basamak oranının sabit olmasıdır.
  • Tam sayı piksele yuvarlama bu sabitliği bozar; sapmanın orana etkisi küçük boyutlarda büyüktür, dolayısıyla ölçeğin alt ucu en kırılgan yeridir.
  • Ölçek oranı ayrım eşiğine eşit değil, ondan belirgin biçimde büyük seçilir; eşiğe yakın oran kimi basamak çiftinde yuvarlamayla eşiğin altına düşer.
  • Oran büyüdükçe verilen boyut aralığına sığan basamak sayısı azalır; oran seçimi ayrım gücü ile basamak bütçesi arasındaki ödünleşimdir.
  • Her düzey yeni bir basamak istemez; aynı basamaktaki iki düzey ağırlık ya da yüzey kanalında ayrılabilir.
  • Ölçek adlandırılmış basamak değerleri olarak yazılır; ara değer eklemek, ölçeğin verdiği güvenceyi o noktada iptal eder.

Sonraki Adım

Ölçek metnin ne kadar büyük olacağını söyledi, ne kadar geniş olacağını değil. Bir kayıt ayrıntısındaki özet paragrafı sütunun tamamına yayıldığında satırlar uzar ve göz satır sonundan bir sonraki satırın başına dönerken hedefi kaçırmaya başlar. Sonraki ders satır uzunluğunu karakter cinsinden hesaplar, ölçüyü sütun genişliğine bağlar ve satır aralığının neden satır uzunluğuyla birlikte ayarlanması gerektiğini gösterir.

İ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