Ders 08 / 26
Kalıtım ve Varsayılan Değerler
Hiçbir bildirimin ulaşmadığı bir özelliğin değerinin nasıl belirlendiği; kalıtılan ve kalıtılmayan özellikler, başlangıç değeri ve inherit, initial, unset, revert anahtar sözcükleri.
İçindekiler
Basamaklama, bir ögeye uyan bildirimler arasından kazananı seçiyor. Bir sorun kaldı: hiçbir
bildirim uymuyorsa ne olur? Ölçüm çizelgesindeki bir hücreye hiçbir kural color
yazmamışsa o hücrenin metin rengi nedir?
Boşluk iki ayrı mekanizmayla doldurulur. Bazı özellikler değerlerini üst ögeden devralır; kalanlar tanımlı bir başlangıç değerine düşer. Bu ders iki mekanizmayı ayırır, hangi özelliğin hangisine tabi olduğunu gerekçelendirir ve ikisini açıkça çağıran anahtar sözcükleri tanımlar.
Kalıtım Ağaçta Aşağı Doğru İşler
Kalıtım (inheritance), bir özelliğin değerinin belge ağacında üst ögeden alt ögeye geçmesidir. Her özellik kalıtılmaz; hangi özelliğin kalıtıldığı özellik tanımının bir parçasıdır ve rastgele değildir.
Kabaca: metnin görünümünü belirleyen özellikler kalıtılır — color, font-family,
font-size, font-weight, line-height, text-align, letter-spacing, visibility.
Kutunun geometrisini belirleyen özellikler kalıtılmaz — margin, padding, border,
width, height, background, display, position.
Ayrımın gerekçesi kullanışlılıktır. Bir bölümün yazı tipini bir kez ayarlayıp içindeki bütün metnin onu almasını istemek olağandır; bir bölüme kenarlık verip içindeki her paragrafın da kenarlık almasını istemek olağan değildir. Kalıtım, tekrarı olağan olan kararlarda açıktır.
Kalıtılan değer, üst ögenin hesaplanmış değeridir; kaynakta yazılan metin değil.
Bir üst ögede font-size: 150% yazılıysa, çocuğa geçen şey 150% değil, o yüzdenin
çözülmüş sonucudur. Bu ayrım birimler dersinde sayıyla ele alınacak.
Başlangıç Değeri Tarayıcı Varsayılanı Değildir
Kalıtılmayan bir özelliğe hiçbir bildirim ulaşmazsa başlangıç değeri (initial value) kullanılır. Bu değer, özelliğin tanımında yazılıdır ve gerçekleştirimden bağımsızdır.
Burada sık karıştırılan bir ayrım vardır. div ögesinin blok kutu üretmesi, display
özelliğinin başlangıç değerinden gelmez — display özelliğinin başlangıç değeri inline
’dır. div ögesinin blok olması, tarayıcının kendi varsayılan biçem dosyasında
div { display: block } yazdığı içindir.
Ayrım şöyle özetlenir: başlangıç değeri dilin tanımından, tarayıcı varsayılanı bir biçem dosyasından gelir. Birincisi hiçbir kural yazılmadığında değil, hiçbir kural kazanmadığında devreye girer; ikincisi ise kazanabilecek bir bildirimdir ve önceki derste gördüğümüz basamaklamada en zayıf kaynaktır.
Değer Çözümlemesinin Yürütülmesi
Aşağıdaki program, basamaklama sonucu kazanmış bildirimleri girdi alır ve ağaçta aşağı inerek her ögenin dört özellik için değerini çözer. Her satırın sonunda değerin nereden geldiği yazılıdır.
// kalitim.mjs — deger cozumlemesini agacta asagi dogru yurutur const KALITILAN = new Set(["color", "font-family", "line-height", "text-align", "visibility"]); const BASLANGIC = { "color": "canvastext", "font-family": "serif", "line-height": "normal", "text-align": "start", "visibility": "visible", "border-color": "currentcolor", "background-color": "transparent", }; // kazanan bildirimler (basamaklama sonucu) — dugum yolu -> {ozellik: deger} const kazananlar = { "body": { "color": "#1c2733", "font-family": "system-ui" }, "body/main": {}, "body/main/table": { "text-align": "right", "border-color": "#d5dbe0" }, "body/main/table/tr": {}, "body/main/table/tr/td.ad": { "text-align": "start" }, "body/main/table/tr/td.eksik": { "color": "inherit", "text-align": "unset", "border-color": "unset", "font-family": "initial" }, }; const agac = { ad: "body", cocuk: [ { ad: "main", cocuk: [ { ad: "table", cocuk: [ { ad: "tr", cocuk: [ { ad: "td.ad", cocuk: [] }, { ad: "td.eksik", cocuk: [] } ] }, ] } ] } ] }; const OZELLIKLER = ["color", "font-family", "text-align", "border-color"]; function coz(dugum, yol, ustDegerler) { const tamYol = yol ? `${yol}/${dugum.ad}` : dugum.ad; const yazilan = kazananlar[tamYol] ?? {}; const degerler = {}; for (const oz of OZELLIKLER) { let d = yazilan[oz]; let kaynak; if (d === undefined) { // bildirim yok: kalitilan ozellikse ustten al, degilse baslangic degeri if (KALITILAN.has(oz) && ustDegerler) { d = ustDegerler[oz]; kaynak = "kalitim"; } else { d = BASLANGIC[oz]; kaynak = "baslangic"; } } else if (d === "inherit") { d = ustDegerler ? ustDegerler[oz] : BASLANGIC[oz]; kaynak = "inherit"; } else if (d === "initial") { d = BASLANGIC[oz]; kaynak = "initial"; } else if (d === "unset") { if (KALITILAN.has(oz) && ustDegerler) { d = ustDegerler[oz]; kaynak = "unset->kalitim"; } else { d = BASLANGIC[oz]; kaynak = "unset->baslangic"; } } else { kaynak = "bildirim"; } degerler[oz] = d; console.log(` ${oz.padEnd(12)} = ${String(d).padEnd(12)} (${kaynak})`); } for (const c of dugum.cocuk) { console.log(`${tamYol}/${c.ad}`); coz(c, tamYol, degerler); } } console.log("body"); coz(agac, "", null);
body color = #1c2733 (bildirim) font-family = system-ui (bildirim) text-align = start (baslangic) border-color = currentcolor (baslangic) body/main color = #1c2733 (kalitim) font-family = system-ui (kalitim) text-align = start (kalitim) border-color = currentcolor (baslangic) body/main/table color = #1c2733 (kalitim) font-family = system-ui (kalitim) text-align = right (bildirim) border-color = #d5dbe0 (bildirim) body/main/table/tr color = #1c2733 (kalitim) font-family = system-ui (kalitim) text-align = right (kalitim) border-color = currentcolor (baslangic) body/main/table/tr/td.ad color = #1c2733 (kalitim) font-family = system-ui (kalitim) text-align = start (bildirim) border-color = currentcolor (baslangic) body/main/table/tr/td.eksik color = #1c2733 (inherit) font-family = serif (initial) text-align = right (unset->kalitim) border-color = currentcolor (unset->baslangic)
Çıktıdan üç gözlem çıkar.
color ve font-family yalnızca body ögesinde bildirildi ve beş kuşak aşağı, hücrelere
kadar taşındı. Bir bildirim, ağacın kökünde yazıldığında bütün alt ağacı etkiler.
border-color tabloda #d5dbe0 iken satırda yeniden currentcolor’a düştü. Kenarlık
rengi kalıtılan bir özellik değildir; tabloya verilen kenarlık rengi hücrelere geçmez.
Tabloda kenarlık kurmak için hücrelere ayrıca kural yazmak gerekmesinin sebebi budur.
text-align tabloda right oldu ve satır ile hücrelere kalıtımla indi; td.ad ögesinde
bir bildirimle start’a çevrildi. Kalıtım, alt ögede bildirim varsa geçersizdir — kalıtım
en zayıf kaynaktır, bir bildirimle her zaman bastırılır.
Dört Anahtar Sözcük
Her özelliğin değerine yazılabilen dört anahtar sözcük vardır. Çıktının son bloğu dördünden üçünü gösteriyor.
inherit — kalıtılmayan bir özelliği bile üst ögeden almaya zorlar. td.eksik ögesinde
color: inherit yazıldı ve değer üstten geldi. Bu, kalıtılmayan bir özellikte anlamlıdır;
border-color: inherit yazmak, kenarlık rengini üstten çekmenin yoludur.
initial — özelliğin başlangıç değerine döner. Çıktıda font-family: initial yazan hücre
serif değerine düştü; üstteki system-ui kalıtımı kesildi. Bu sonuç sıklıkla istenmeyen
bir sonuçtur: initial, dilin tanımına döner, sayfanın tasarımına değil.
unset — koşullu davranır: özellik kalıtılan bir özellikse inherit gibi, değilse
initial gibi işler. Çıktıda text-align: unset kalıtıma, border-color: unset başlangıç
değerine düştü. Bu, “bu bildirimi hiç yazmamış olsaydım ne olurdu” sorusunun yanıtıdır.
revert — dördüncüsüdür ve farklı bir soruya yanıt verir: değeri, daha zayıf bir
kaynağın kazanacağı hâle döndürür. Yazar biçeminde revert yazmak, o özellikte tarayıcı
varsayılanına dönmek demektir. initial ile farkı burada görülür: bir bağlantıda
color: initial yazmak rengi dilin başlangıç değerine götürür, color: revert ise
tarayıcının bağlantılar için tanımladığı renge götürür.
Dördü de all kısayoluyla bütün özelliklere birden yazılabilir. all: revert bir ögeyi
yazar biçeminden yalıtır; all: unset ise kalıtılanları koruyup kalanları sıfırlar.
Değer Aşamaları
Bu bölümde geçen “hesaplanmış değer” terimi tanımlanmalıdır. Bir bildirimin yazımından ekrandaki sonuca kadar değer birkaç aşamadan geçer:
| Aşama | Ne olur |
|---|---|
| bildirilen değer | Kaynakta yazılan metin |
| basamaklanmış değer | Basamaklamayı kazanan bildirim |
| belirtilmiş değer | Kazanan yoksa kalıtım veya başlangıç değeriyle doldurulmuş hâli |
| hesaplanmış değer | Göreli birimlerin çözüldüğü, kalıtımla aktarılan hâli |
| kullanılan değer | Yerleşim yapıldıktan sonra kesinleşen hâli |
Kalıtımla aktarılan aşama hesaplanmış değerdir. Bir üst ögede font-size: 1.5em
yazılıysa, çocuk 1.5em metnini değil, o ifadenin çözülmüş sonucunu devralır — aksi hâlde
her kuşakta yeniden çarpılır ve yazı boyutu üstel büyürdü.
Kullanılan değer aşaması ise yerleşimi bekler. width: 50% bildiriminde hesaplanmış değer
hâlâ yüzdedir; kesin sayı, kapsayan kutunun genişliği bilindikten sonra ortaya çıkar. Bu
aşamayı kutu modeli konusunda ayrıntısıyla göreceğiz.
İstasyon Sayfasında Kalıtımın Kullanımı
/* istasyon.css — 7. adım: kalıtımı taban olarak kullanmak */ body { color: #1c2733; font-family: system-ui, sans-serif; line-height: 1.5; } /* form denetimleri tipografiyi kendiliğinden devralmaz */ input, select, textarea, button { font: inherit; color: inherit; } .olcum-cizelgesi { border-collapse: collapse; } .olcum-cizelgesi th, .olcum-cizelgesi td { border-block-end: 1px solid #d5dbe0; }
İkinci kural bir istisnayı kapatır. Form denetimleri tipografilerini belgeden almaz;
kendi varsayılan yazı tiplerini taşırlar. font: inherit yazmak, bu istisnayı kaldırıp
denetimleri belgenin tipografisine bağlar.
Üçüncü grup, kenarlık rengi kalıtılmadığı için kenarlığın hücrelere ayrı ayrı yazılması gerektiğini gösteriyor — çıktının dördüncü bloğunda gördüğümüz davranışın doğrudan sonucu.
Özet
- Bir özellik ya kalıtılır ya da bildirim yoksa başlangıç değerine düşer; hangisinin geçerli olduğu özelliğin tanımında yazılıdır ve metin özellikleri kalıtılır, kutu geometrisi özellikleri kalıtılmaz.
- Başlangıç değeri dilin tanımından gelir; tarayıcının varsayılan görünümü ise bir biçem
dosyasından gelir ve basamaklamada en zayıf kaynaktır.
display: blockbir başlangıç değeri değil, o dosyada yazan bir bildirimdir. - Kalıtım en zayıf kaynaktır: alt ögede o özelliğe yazan bir bildirim varsa kalıtım geçersizdir.
inheritüstten almaya zorlar,initialdilin başlangıç değerine döner,unsetikisi arasında özelliğin türüne göre seçer,revertdaha zayıf bir kaynağın değerine döner.- Kalıtımla aktarılan şey hesaplanmış değerdir; göreli birimler aktarılmadan önce çözülür, aksi hâlde her kuşakta yeniden çarpılırlardı.
Sonraki Adım
Bu konu boyunca kuralların hangi ögelere ulaştığı ve hangi değerin kazandığı çözüldü. Değer
kesinleşti; ama o değerin ne anlama geldiği henüz kurulmadı. padding: 8px bir hücrenin
neresine 8 piksel ekler? Genişlik verilen bir kutunun toplam eni ne olur? Sonraki konu her
ögenin bir kutuya dönüştüğü modeli tanımlar ve bu kutunun bölümlerini aritmetikle ele alır.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.