İçeriğe geç
academia.sh

Ders 20 / 24

Öğe ve Biçem İnceleme

Öge denetçisinin yanıtladığı soru; canlı ağaç ile kaynak metin farkı, bildirilen–hesaplanan–kullanılan değer ayrımı, basamaklama sırasının okunması, kalıtımın izlenmesi ve kutu ölçülerinin yorumlanması.

İçindekiler

Buraya kadar kurulan katmanlar birlikte çalıştığında görünmez olurlar. Bir şey ters gittiğinde ise sorunun hangi katmandan geldiği kaynağa bakarak anlaşılmaz: ölçüm rozetinin rengi yanlış olabilir çünkü bir biçem kuralı beklenmedik biçimde kazanmıştır, ya da gösterdiği sayı eski olabilir çünkü istek önbellekten karşılanmıştır.

Bu konu, tarayıcının sunduğu tanı araçlarını sordukları sorular üzerinden ele alır. Her aracın yanıtladığı belirli bir soru, okunan belirli bir ölçü ve o ölçünün yorumlanma biçimi vardır. İlk araç en yakınındakidir: bir ögenin gerçekte hangi değerlerle çizildiğini gösteren öge denetçisi.

Denetçinin Gösterdiği Ağaç

Denetçideki ağaç, sunucudan gelen metnin bir görüntüsü değildir. DOM API’si dersinde kurulan ayrım burada araca yansır: gösterilen şey, ayrıştırmanın ve o ana kadar çalışmış bütün betiklerin sonucundaki canlı ağaçtır.

Aradaki farkı üreten dört kaynak vardır. Ayrıştırıcının kurtarma kuralları eksik kapanış etiketlerini tamamlar ve yanlış yerdeki ögeleri taşır; kaynakta olmayan bir yapı ağaçta belirir. Betikler düğüm ekler ve siler. Gölge ağaçları ayrı alt ağaçlar olarak gösterilir ve belge ağacında bulunmazlar. Sözde ögeler ağaçta düğüm değildir, ama çizildikleri için denetçide ayrı satırlar olarak işaretlenir.

Buradan doğrudan bir tanı kuralı çıkar: denetçide gördüğü yapıyı kaynakta bulamayan kişi, iki farklı şeye bakıyordur. Sunucunun gerçekte ne gönderdiğini görmek ayrı bir sorudur ve ağ panelinin konusudur.

Üç Değer: Bildirilen, Hesaplanan, Kullanılan

Biçem incelemesindeki en sık karışıklık, aynı özelliğin farklı yerlerde farklı biçimde görünmesidir. Nedeni, bir değerin çizime kadar üç aşamadan geçmesidir.

Bildirilen değer biçem dosyasında yazıldığı gibidir: 1.5rem, 50%, inherit, auto. Basamaklamayı kazanan bildirim bu biçimiyle listelenir.

Hesaplanan değer, kalıtım ve göreli birimler çözüldükten sonraki değerdir. Yazı boyutuna göre tanımlı bir birim burada saltık uzunluğa iner; anahtar sözcükler kendi karşılıklarına çevrilir. Kalıtım bu aşamadaki değeri aktarır.

Kullanılan değer, yerleşim hesabı bittikten sonra ortaya çıkan sayıdır. Yüzdeler kapsayıcının gerçek genişliğine göre çözülür, auto bir sayıya iner, esneme ve ızgara dağıtımı sonucunu burada verir.

Ayrım tanıda belirleyicidir. Genişliği yüzde olarak yazılmış bir öge beklenenden dar çizildiğinde hesaplanan değer hâlâ yüzde gösterebilir; sorun kapsayıcının genişliğindedir ve yalnızca kullanılan değere bakarak görülür. Tersine, bir renk bildiriminin hiç uygulanmadığı durumda kullanılan değere bakmak yanıltır; oraya bakılması gereken yer basamaklama sırasıdır.

Sıralamanın Kuralı ve Üstü Çizilenler

Biçem listesi, bir ögeye eşleşen bütün bildirimleri kazanandan kaybedene doğru sıralar ve kaybedenlerin üstünü çizer. Üstü çizili satırlar gürültü değil, tanının kendisidir: bir kuralın neden uygulanmadığı, onu geçen kuralın listedeki yerinden okunur.

Sıralamayı üreten hesap üç ölçüte dayanır.

// basamaklama.mjs — bicem listesinin siralamasini ve kazanan bildirimi ureten hesap
// Ozgulluk uclusu: (kimlik, sinif/oznitelik/sozde-sinif, tur/sozde-oge)
function ozgulluk(secici) {
  const parcalar = secici.split(/\s+/);
  let a = 0, b = 0, c = 0;
  for (const p of parcalar) {
    a += (p.match(/#[\w-]+/g) ?? []).length;
    b += (p.match(/\.[\w-]+|\[[^\]]+\]|:(?!:)[\w-]+/g) ?? []).length;
    c += (p.match(/::[\w-]+/g) ?? []).length;
    if (/^[a-zA-Z][\w-]*/.test(p)) c += 1;
  }
  return [a, b, c];
}

// Katman agirligi: buyuk olan kazanir.
const AGIRLIK = { "tarayici": 0, "yazar": 1, "yazar!": 2, "tarayici!": 3 };
const agirlik = (b) => AGIRLIK[b.kaynak + (b.onemli ? "!" : "")];

function sirala(bildirimler) {
  return [...bildirimler].sort((x, y) => {
    if (agirlik(x) !== agirlik(y)) return agirlik(y) - agirlik(x);
    const ox = ozgulluk(x.secici), oy = ozgulluk(y.secici);
    for (let i = 0; i < 3; i++) if (ox[i] !== oy[i]) return oy[i] - ox[i];
    return y.sira - x.sira; // sonra yazilan kazanir
  });
}

// span.deger ogesine uygulanan renk bildirimleri
const bildirimler = [
  { sira: 1, kaynak: "tarayici", secici: "span", deger: "canvastext", onemli: false },
  { sira: 2, kaynak: "yazar", secici: ".deger", deger: "#333", onemli: false },
  { sira: 3, kaynak: "yazar", secici: "#pano .deger", deger: "#0a5", onemli: false },
  { sira: 4, kaynak: "yazar", secici: "span.deger", deger: "#b23", onemli: false },
  { sira: 5, kaynak: "yazar", secici: ".deger", deger: "#07c", onemli: false },
  { sira: 6, kaynak: "yazar", secici: ".uyari .deger", deger: "#c30", onemli: true },
];

console.log("color bildirimleri (kazanan en ustte):");
for (const [i, b] of sirala(bildirimler).entries()) {
  const [a, s, t] = ozgulluk(b.secici);
  console.log(
    `  ${i === 0 ? "→" : " "} ${b.secici.padEnd(16)} ${b.deger.padEnd(12)}` +
    `ozgulluk ${a}-${s}-${t}  ${b.kaynak}${b.onemli ? " !important" : ""}` +
    `${i === 0 ? "" : "   (ustu cizili)"}`);
}

// Kalitim: yalnizca hicbir bildirim eslesmediginde devreye girer.
const kazanan = (liste) => (liste.length ? sirala(liste)[0].deger : null);
const ebeveynRengi = kazanan(bildirimler);
const cocukBildirimleri = []; // strong ogesine hicbir renk kurali eslesmiyor

console.log("\nspan.deger  → hesaplanan color:", ebeveynRengi);
console.log("strong      → hesaplanan color:",
  kazanan(cocukBildirimleri) ?? `${ebeveynRengi} (kalitim)`);
color bildirimleri (kazanan en ustte):
  → .uyari .deger    #c30        ozgulluk 0-2-0  yazar !important
    #pano .deger     #0a5        ozgulluk 1-1-0  yazar   (ustu cizili)
    span.deger       #b23        ozgulluk 0-1-1  yazar   (ustu cizili)
    .deger           #07c        ozgulluk 0-1-0  yazar   (ustu cizili)
    .deger           #333        ozgulluk 0-1-0  yazar   (ustu cizili)
    span             canvastext  ozgulluk 0-0-1  tarayici   (ustu cizili)

span.deger  → hesaplanan color: #c30
strong      → hesaplanan color: #c30 (kalitim)

Listede üç ayrı ölçüt iş başındadır ve hangisinin devreye girdiği satırlar karşılaştırılarak okunur.

Birinci satır ağırlığın özgüllüğü yendiğini gösterir: özgüllüğü daha düşük olan bildirim yalnızca önemli işaretlendiği için en üstte durur. Bir kuralın neden kazandığı sorusuna “daha özgül olduğu için” yanıtı verilmeden önce ağırlık sütununa bakılır.

İkinci ve üçüncü satırlar özgüllük karşılaştırmasının basamaklı olduğunu gösterir: kimlik sayısı eşit değilse geri kalan hiç hesaba katılmaz. Bir kimlik, kaç sınıf yazılırsa yazılsın onları geçer.

Dördüncü ve beşinci satırlar kaynak sırasının son ölçüt olduğunu gösterir: aynı seçicinin iki bildirimi arasında sonra yazılan kazanır. Bu, aynı sınıfın iki ayrı dosyada tanımlandığı durumlarda dosya yükleme sırasının tanıya girdiği yerdir.

Son satır tarayıcının kendi varsayılan biçeminin listede göründüğünü ve her zaman en altta kaldığını gösterir. Yazarın hiçbir kuralı olmayan bir özellik için bu satır kazanan olur; beklenmedik bir kenar boşluğunun kaynağı çoğunlukla buradadır.

Kalıtımın Okunması

Çıktının son iki satırı kalıtımın koşulunu gösterir: bir öge için hiçbir bildirim eşleşmediğinde ve özellik kalıtılan bir özellikse, değer ebeveynin hesaplanan değerinden alınır.

Denetçide bu, kaynağı ögenin kendi kurallarında bulunamayan bir değer olarak görünür ve listede ait olduğu ata gösterilir. Tanı kuralı şudur: kalıtılan bir değeri değiştirmek için ögenin kendisine kural yazmak gerekir; ataya yazılmış kural, arada eşleşen başka bir bildirim varsa hiç görünmez. Kalıtım basamaklamanın bir parçası değil, basamaklama sonuçsuz kaldığında devreye giren yedeğidir.

Kutu Ölçülerini Okumak

Kutu ölçüleri görünümü, ögenin içerik alanını, iç boşluğunu, kenarlığını ve dış boşluğunu sayılarla gösterir. Buradaki bütün sayılar kullanılan değerlerdir: yüzdeler çözülmüş, auto bir sayıya inmiş, çakışan dış boşluklar birleştirilmiştir.

Üç okuma sık gerekir. İçerik genişliğinin yazılandan farklı olması, kutu boyutlandırma modelinin iç boşluk ile kenarlığı genişliğe dahil ettiğini gösterir. Dış boşluğun yazılanın yarısı çıkması, komşu kutuyla çakışmanın gerçekleştiğini gösterir. Sıfır yükseklik, ögenin akışta yer kaplamadığını — çocuklarının kayan ya da mutlak konumlu olduğunu — gösterir.

Bir ögenin hiç çizilmemesi ayrı bir durumdur ve kutu ölçülerinde değil hesaplanan değerlerde okunur: görüntüleme türü, görünürlük, saydamlık ve kırpma özelliklerinin hangisinin devrede olduğu ayrı ayrı sınanır. Dördü de ögeyi gözden kaldırır, ama üçü yerini korur, biri kaldırmaz.

Durumları Zorlamak

Fare üzerindeyken ya da odaktayken uygulanan kurallar, incelenmek istendiğinde çoğunlukla kaybolur: inceleme için imleç ögeden ayrılır, odak denetçiye geçer. Bu yüzden denetçiler ögenin durumunu zorlamaya izin verir; öge gerçekten o durumda olmasa da ilgili sözde sınıf kuralları uygulanır ve listede görünür.

Aynı yol erişilebilirlik denetiminde de kullanılır: odak göstergesinin gerçekten görünür olup olmadığı, odak durumu zorlanarak sınanır. Odak Sırası ve Klavye Etkileşimi dersinde kurulan gereklilik burada ölçülebilir hâle gelir.

Sözde ögeler ayrı satırlarda listelenir çünkü kendi kural kümeleri vardır ve ana ögenin listesinde görünmezler. Üretilmiş içeriğin neden görünmediği sorusunun yanıtı çoğunlukla o ayrı listede durur.

Özet

  • Denetçideki ağaç canlı ağaçtır: ayrıştırıcı kurtarmaları, betik değişiklikleri, gölge ağaçları ve sözde ögeler kaynak metinden ayrışır.
  • Bir değer bildirilen, hesaplanan ve kullanılan aşamalarından geçer; hangi aşamaya bakılacağı sorunun türüne bağlıdır.
  • Biçem listesi bildirimleri ağırlık, özgüllük ve kaynak sırası ölçütleriyle sıralar; üstü çizili satırlar bir kuralın neden kaybettiğini söyler.
  • Özgüllük karşılaştırması basamaklıdır: üstteki basamak eşit değilse alttakiler hiç hesaba katılmaz.
  • Kutu ölçülerindeki sayılar kullanılan değerlerdir; yazılan değerden sapmaları kutu modeli, çakışma ve akış davranışıyla açıklanır.
  • Etkileşim durumları zorlanarak incelenir; sözde ögelerin kuralları ayrı listelenir.

Sonraki Adım

Bu ders bir ögenin neden öyle göründüğünü yanıtladı, ama içeriğinin neden o içerik olduğunu yanıtlamadı. Rozetteki sayı eskiyse sorun biçemde değildir: ya istek hiç yapılmamıştır, ya önbellekten karşılanmıştır, ya sunucu eski veriyi döndürmüştür, ya da yanıt beklenenden çok geç gelmiştir. Dördü ayrı ölçülerle ayrılır ve hepsi tek bir yerde okunur: isteğin ne zaman başladığı, hangi aşamada ne kadar beklediği ve hangi başlıklarla döndüğü. Sonraki ders bu ölçüleri ve aralarındaki nedensellikleri ele alı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