Ders 06 / 26
Sözde Sınıflar ve Sözde Elemanlar
Belgede yazılı olmayan durumları seçen sözde sınıflar, nth-child aritmetiği, mantıksal seçiciler ve ağaçta bulunmayan içerik üreten sözde elemanlar.
İçindekiler
Şimdiye kadarki bütün seçiciler belgede yazılı olan bir şeye baktı: öge adı, sınıf, kimlik, öznitelik, ağaçtaki konum. Belgede yazılı olmayan bilgiler de vardır. Bir bağlantının üzerinde durulup durulmadığı, bir form alanının odakta olup olmadığı, bir satırın kaçıncı sırada bulunduğu — bunların hiçbiri işaretlemede geçmez, çünkü hiçbiri belgenin bir özelliği değildir.
Bu ders iki mekanizmayı tanımlar: belgede yazılı olmayan durumları seçen sözde sınıfları ve belge ağacında hiç bulunmayan parçaları hedefleyen sözde elemanları. İkisi farklı işler görür ve yazımdaki tek fark iki nokta üst üstenin sayısıdır.
Sözde Sınıf Bir Durumu Seçer
Sözde sınıf (pseudo-class) tek iki nokta üst üsteyle yazılır ve seçiciye, ögenin o andaki durumuna ilişkin bir koşul ekler. İki aileye ayrılır.
Birinci aile etkileşim durumunu sorar: :hover işaretleyici ögenin üzerindeyken,
:focus öge klavye odağını taşırken, :active öge etkinleştirilirken, :disabled bir
denetim devre dışıyken, :checked bir seçenek işaretliyken, :invalid bir alanın değeri
kısıtları sağlamıyorken eşleşir. Bu durumların hiçbiri belgede yazılı değildir; kullanıcı
etkileşimi ya da doğrulama sonucudur.
İkinci aile ağaçtaki konumu sorar: :first-child, :last-child, :only-child,
:empty, :root ve sayılı bir ailenin başı olan :nth-child().
nth-child Bir Aritmetik İfadedir
:nth-child() bir sayı değil, bir formül alır: an+b. Burada n sıfırdan başlayarak
artan bir tam sayıdır; formülün ürettiği ve 1 ile kardeş sayısı arasında kalan her değer
bir sıraya karşılık gelir.
Aşağıdaki program bu formülü çözer ve dokuz satırlık bir ölçüm çizelgesinde hangi sıraların eşleştiğini listeler.
// nth-hesap.mjs — :nth-child(an+b) formulunu cozer ve eslesen siralari listeler function ayristir(ifade) { const s = ifade.replace(/\s+/g, "").toLowerCase(); if (s === "odd") return { a: 2, b: 1 }; if (s === "even") return { a: 2, b: 0 }; const m = s.match(/^([+-]?\d*)n([+-]\d+)?$/); if (!m) return { a: 0, b: Number(s) }; const aMetin = m[1]; const a = aMetin === "" || aMetin === "+" ? 1 : aMetin === "-" ? -1 : Number(aMetin); return { a, b: m[2] ? Number(m[2]) : 0 }; } // n = 0,1,2,... icin an+b degeri; 1 <= sira <= toplam olanlar eslesir function eslesenler(ifade, toplam) { const { a, b } = ayristir(ifade); const c = []; for (let sira = 1; sira <= toplam; sira++) { if (a === 0) { if (sira === b) c.push(sira); continue; } const n = (sira - b) / a; if (Number.isInteger(n) && n >= 0) c.push(sira); } return { a, b, eslesen: c }; } const TOPLAM = 9; // olcum cizelgesinde dokuz satir for (const ifade of ["odd", "even", "3", "2n+1", "3n", "3n+1", "-n+3", "n+4", "5n-2"]) { const { a, b, eslesen } = eslesenler(ifade, TOPLAM); const formul = `${a}n${b >= 0 ? "+" : ""}${b}`; console.log(`:nth-child(${ifade.padEnd(5)}) = ${formul.padEnd(7)} -> ${eslesen.join(" ") || "(bos)"}`); }
:nth-child(odd ) = 2n+1 -> 1 3 5 7 9 :nth-child(even ) = 2n+0 -> 2 4 6 8 :nth-child(3 ) = 0n+3 -> 3 :nth-child(2n+1 ) = 2n+1 -> 1 3 5 7 9 :nth-child(3n ) = 3n+0 -> 3 6 9 :nth-child(3n+1 ) = 3n+1 -> 1 4 7 :nth-child(-n+3 ) = -1n+3 -> 1 2 3 :nth-child(n+4 ) = 1n+4 -> 4 5 6 7 8 9 :nth-child(5n-2 ) = 5n-2 -> 3 8
Üç satır ayrıca okunmalıdır. odd ve even anahtar sözcükleri 2n+1 ve 2n formüllerinin
adlarıdır; ayrı bir mekanizma değildir. Negatif katsayılı -n+3 “ilk üç” anlamına gelir:
n büyüdükçe değer küçülür ve 1’in altına düştüğünde eşleşme biter. Karşıtı olan n+4
ise “dördüncüden sonuna kadar” demektir. Bu ikisi, bir aralığı seçmenin yoludur.
Bir uyarı: :nth-child() bütün kardeşleri sayar, türe bakmaz. Bir bölümde bir başlık
ve ardından paragraflar varsa, ilk paragraf p:nth-child(1) ile eşleşmez — o sırada başlık
durur. Türe göre saymak gerekiyorsa :nth-of-type() yazılır; bu, yalnızca aynı öge adını
taşıyan kardeşleri sayar.
Mantıksal Seçiciler
Dört sözde sınıf, seçici listesi alır ve mantıksal işlem yapar.
:is() içindeki listeden herhangi biriyle eşleşen ögeleri döndürür; uzun seçicileri
kısaltır. :where() aynı eşlemeyi yapar ama özgüllüğe sıfır katkı verir — bu ayrımın
neden önemli olduğunu bir sonraki derste hesapla göreceğiz.
:is(h1, h2, h3) + p { margin-block-start: 0.5em; }
Bu kural, üç ayrı kural yazmakla aynı ögeleri seçer.
:not() listedeki hiçbiriyle eşleşmeyen ögeleri döndürür:
.olcum-cizelgesi td:not(.ad) { text-align: right; }
:has() ise yönü tersine çevirir: bir ögeyi, içeriğine göre seçer. tr:has(td.eksik)
seçicisi, içinde eksik hücre bulunan satırları döndürür. Bu, birleştiricilerle
yapılamayan bir şeydir; birleştiriciler yalnızca sağdaki ögeyi seçebiliyordu.
Bir seçicinin gerçekleştirimlerce tanınıp tanınmadığı sınanabilir. Önceki derslerde tanınmayan bir seçicinin kuralın tamamını düşürdüğünü görmüştük; bu, sınamanın da yolunu verir:
@supports selector(:has(*)) { tr:has(td.eksik) { background-color: #fbf4f4; } }
@supports bloğu, içindeki koşul sağlanmazsa bloğun tamamını yok sayar. Özellik saptama
yazmak, bir özelliğin desteklendiğini varsaymaktan farklıdır: koşul sağlanmadığında
sayfanın hangi hâlde kalacağı yazar tarafından belirlenmiş olur.
Sözde Eleman Bir Parçayı Hedefler
Sözde eleman (pseudo-element) çift iki nokta üst üsteyle yazılır ve belge ağacında bulunmayan bir parçayı hedefler.
::first-line bir paragrafın ilk satırını, ::first-letter ilk harfini seçer. Bu ikisi
belgede öge olarak yoktur; satır bölünmesi yerleşim sonucunda oluşur ve kutunun genişliği
değişince ilk satırın kapsamı da değişir.
::marker liste madde işaretini, ::placeholder bir form alanının yer tutucu metnini,
::selection kullanıcının seçtiği metin aralığını hedefler.
::before ve ::after ise farklıdır: bir parçayı seçmezler, üretirler. İkisi de
content özelliği yazılmadan var olmaz.
td.eksik::after { content: " —"; }
Bu kural, eksik ölçüm hücrelerinin içeriğinin sonuna bir tire ekler. Üretilen içerik ögenin
içindedir, dışında değil: ::before ögenin ilk çocuğu, ::after son çocuğu gibi davranır.
Üretilmiş içeriğin iki sınırı vardır ve ikisi de tasarım gereğidir.
Birincisi, belgede yoktur. Metin olarak seçilip kopyalanması, arama motoru tarafından dizinlenmesi ya da yardımcı teknolojiye aktarılması güvence altında değildir. Bu yüzden anlam taşıyan hiçbir metin buraya yazılmaz. “Eksik” bilgisi belgede bir sınıf ve gerekiyorsa görünür bir metinle bildirilmeli; sözde eleman yalnızca görsel işaret eklemelidir.
İkincisi, seçilemez. Bir sözde elemanın içinde başka bir seçici çalışmaz; üretilen içeriğin kendi alt yapısı yoktur.
Yazım kuralına ilişkin bir not: çift iki nokta yazımı sözde elemanı sözde sınıftan ayırmak
için tanımlanmıştır. Eski gerçekleştirimlerle uyum için :before yazımı da kabul edilir;
ayrımı korumak adına bu kursta çift iki nokta kullanılır.
İstasyon Sayfasının Durum Biçemleri
/* istasyon.css — 5. adım: durumlar ve sıralar */ .olcum-cizelgesi tbody tr:nth-child(odd) { background-color: #f5f7f8; } .olcum-cizelgesi tbody tr:last-child { border-block-end: none; } .olcum-cizelgesi td:not(.ad) { text-align: right; } .olcum-cizelgesi td.eksik::after { content: " —"; color: #8a5b00; } a:hover { text-decoration-thickness: 2px; } a:focus-visible { outline: 3px solid #143a52; outline-offset: 2px; } input:invalid { border-color: #8a1c1c; } input:disabled { color: #6b767f; }
İkinci grubun ilk iki kuralı bir ayrımı taşır. :hover yalnızca işaretleyici aygıtlarda
oluşan bir durumdur; klavyeyle gezen bir kullanıcı hiçbir zaman ona ulaşmaz. Bu yüzden
:hover ile verilen her ipucunun bir odak karşılığı olmalıdır.
:focus-visible, :focus yerine kullanılır çünkü ikisi farklı kümeler döndürür: :focus
bir alana işaretleyiciyle tıklandığında da eşleşir, :focus-visible odak göstergesinin
gerekli olduğu durumlarda eşleşir. Odak çerçevesini büsbütün kaldırmak
(outline: none yazmak) klavyeyle gezinmeyi olanaksızlaştırır; çerçeve kaldırılacaksa
yerine görünür bir başkası konmalıdır.
Özet
- Sözde sınıf tek iki nokta üst üsteyle yazılır ve belgede yazılı olmayan bir durumu seçer; iki aileye ayrılır — etkileşim durumu ve ağaçtaki konum.
:nth-child()biran+bformülü alır;nsıfırdan başlar ve formülün ürettiği geçerli sıralar eşleşir.oddveevenbu formülün adlandırılmış hâlleridir.:nth-child()bütün kardeşleri sayar,:nth-of-type()yalnızca aynı türdekileri; aradaki fark başlık gibi araya giren ögelerde ortaya çıkar.:is(),:where(),:not()ve:has()seçici listesi alır;:has()bir ögeyi içeriğine göre seçer ve birleştiricilerin ters yönünü sağlar.- Sözde eleman çift iki nokta ile yazılır;
::beforeve::afterbelgede bulunmayan içerik üretir. Bu içerik metin olarak güvenilir biçimde erişilebilir değildir, bu yüzden yalnızca görsel işaret taşır.
Sonraki Adım
Artık aynı ögeye birden çok kural uyabiliyor: td bir kuralla, .eksik başka bir kuralla,
.olcum-cizelgesi td:not(.ad) bir üçüncüsüyle eşleşiyor. Üçü de text-align özelliğine
yazarsa hangisi kazanır? Sonraki ders bu soruyu bir sezgiyle değil, sayılabilir bir
sıralamayla yanıtlar: özgüllük üçlüsünü hesaplar ve basamaklamanın adımlarını sırayla
uygular.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.