Skip to content

Bölüm 7 / 20

CSS temelleri

Seçiciler, özellikler, cascade, specificity.

16 dakikalık okuma

CSS'i "renk ve boşluk ayarlama" sanan biriyle CSS'i bilen biri arasındaki fark tek bir soruda ortaya çıkar: iki kural aynı ögeye farklı değer veriyorsa hangisi kazanır? Bu sorunun cevabı — kaskad, özgüllük, kalıtım ve katmanlar — CSS'in tamamının çalışma mantığıdır. Bilmeyen, işe yaramayan kuralın üstüne !important yazarak ilerler ve altı ay sonra kimsenin dokunamadığı bir stil dosyası bırakır. Bu ders sıfırdan başlar ama asıl hedefi hangi kuralın neden kazandığını tarayıcıda okuyabilmendir.

01Ne öğreneceksin

  • CSS'in belgeye üç bağlanma yolu ve hangisinin ne zaman doğru olduğu
  • @import'un neden performans sorunu olduğu
  • Seçici türleri: tip, sınıf, id, öznitelik, birleştirici, sözde sınıf/eleman
  • Modern seçiciler: :is(), :where(), :has(), :not()
  • Kaskad: köken ve önem sıralaması; !important'ın ters çevirdiği düzen
  • Özgüllük hesabı ve :where() ile sıfırlama
  • @layer ile kaskad katmanları ve üçüncü parti CSS yönetimi
  • Kalıtım: hangi özellikler kalıtılır; inherit, initial, unset, revert
  • Geçersiz değerlerin sessizce atılması ve bunun hata ayıklamadaki anlamı
  • Sınıf isimlendirme disiplini (BEM) ve neden id ile stil verilmediği
  • DevTools'ta "hangi kural kazandı" sorusunu okumak

02CSS nedir, belgeye nasıl bağlanır

CSS (Cascading Style Sheets) HTML ögelerine görsel kurallar uygular. En küçük birimi kuraldır:

h1.baslik {          /* seçici */
  color: #0f766e;    /* bildirim: özellik + değer */
  font-size: 2rem;
}
YolYazımNe zaman
Dış dosya<link rel="stylesheet" href="styles.css">Varsayılan. Önbelleğe alınır, tüm sayfalarda paylaşılır
Belge içi<style>…</style>Yalnız o sayfaya özel kritik stil; ilk boyamayı hızlandırmak için
Satır içi<div style="color:red">JavaScript'in hesapladığı dinamik değerler; elle yazılmaz

Satır içi stilden kaçınmanın sebebi estetik değil kaskaddır: özgüllüğü çok yüksektir ve yalnız !important ile ezilebilir; ayrıca önbelleğe alınmaz, tekrar kullanılamaz ve İçerik Güvenlik Politikası (CSP) uygulayan projelerde engellenir (13. hat).

1. derste gördüğün gibi CSS render engelleyicidir: tarayıcı CSSOM'u tamamlamadan hiçbir şey boyamaz. Bunun iki pratik sonucu vardır:

<!-- Yalnız yazdırmada gerekli — render'ı engellemez -->
<link rel="stylesheet" href="print.css" media="print">

<!-- Yalnız geniş ekranda gerekli — dar ekranda düşük öncelikle indirilir -->
<link rel="stylesheet" href="genis.css" media="(min-width: 900px)">

Ve @import kullanılmaz:

/* styles.css içinde */
@import url("renkler.css");   /* KÖTÜ: tarayıcı önce styles.css'i indirip
                                 ayrıştırmalı, ANCAK SONRA renkler.css'i
                                 keşfeder — istekler zincirlenir, paralel gitmez */

Doğrusu her dosya için ayrı <link> yazmaktır; ön yükleme tarayıcısı hepsini aynı anda görür ve paralel indirir. @import'un tek meşru kullanımı, derleme aşamasında birleştirilen kaynak dosyalardır (SCSS — 12. derste).

Stil dosyası da sonuçta bir statik dosyadır: 5. hatta ASP.NET Core'da UseStaticFiles ile sunulduğunu ve Cache-Control başlığının oradan geldiğini görmüştün. Uzun ömürlü önbellek + içerik damgalı dosya adı kuralı burada da geçerlidir; bu sitenin styles.css?v=6 yazımı aynı fikrin elle yürütülen hâlidir.

03Seçiciler

SeçiciSeçtiğiNot
pTüm <p> ögeleriTip seçici
.kartclass="kart" olanlarAna araç
#anaid="ana" olanStil için kullanılmaz — özgüllüğü çok yüksek
[data-durum="acik"]Özniteliğe göreDurum stilleri için çok kullanışlı
*Her şeySıfırlamada kullanılır
a, buttonHer ikisiGruplama — birinde sözdizimi hatası varsa tüm liste düşer

Birleştiriciler ögeler arasındaki ilişkiyi kurar:

.kart p        { }   /* soy:      .kart içindeki her p, ne kadar derinde olursa olsun */
.kart > p      { }   /* çocuk:    yalnız doğrudan çocuk olan p */
h2 + p         { }   /* bitişik:  h2'den hemen SONRA gelen kardeş p */
h2 ~ p         { }   /* genel:    h2'den sonraki tüm kardeş p'ler */

Çocuk birleştiricisi (>) tablolarda ısırır — 4. derste gördüğün gibi table > tr hiçbir şey seçmez, çünkü DOM'da arada <tbody> vardır.

Sözde sınıflar ve sözde ögeler

a:hover              /* fare üstünde */
a:focus-visible      /* KLAVYE ile odaklanınca — :focus'un doğru hâli */
input:disabled       /* durum */
input:user-invalid   /* kullanıcı etkileşiminden SONRA geçersiz */
li:nth-child(odd)    /* tek sıradaki kardeşler */
li:first-child       /* ilk kardeş */
tr:nth-child(2n+1)   /* formülle */

p::first-line        /* sözde ÖGE — var olmayan bir parçayı hedefler */
p::before            /* içeriğin başına kutu ekler */
.zorunlu::after { content: " *"; }

İki nokta üst üste sayısı ayrımı taşır: tek (:) sözde sınıf — mevcut bir ögenin durumu; çift (::) sözde öge — var olmayan bir parça. ::before/::after, content özelliği olmadan hiç oluşmaz (boş dize de olur: content: "") ve içine yazılan metin genellikle ekran okuyucular tarafından okunur — bu yüzden anlamlı içerik oraya konmaz.

:nth-child() ile :nth-of-type() farkı klasik bir tuzaktır: p:nth-child(2) "ikinci kardeş, üstelik p ise" demektir; p:nth-of-type(2) "ikinci p" demektir. Aralarına bir başlık girince birincisi çalışmayı bırakır.

Modern seçiciler

/* Tekrarı azaltır — özgüllüğü EN YÜKSEK argümanı alır */
:is(h1, h2, h3) > code { font-size: 0.9em; }

/* Aynı işi yapar ama ÖZGÜLLÜĞÜ SIFIRDIR — kolayca ezilebilir */
:where(h1, h2, h3) > code { font-size: 0.9em; }

/* Ebeveyn seçici: "içinde geçersiz alan bulunan form grubu" */
.alan-grup:has(input:user-invalid) { border-color: #dc2626; }

/* Boş girdisi olan bir formun gönder düğmesini soluklaştır */
form:has(input:placeholder-shown) button[type="submit"] { opacity: 0.6; }

:not(.gizli)                    /* olumsuzlama */

:where() bir kütüphane ya da tasarım sistemi yazarken önemlidir: varsayılan stillerini :where() içine koyarsan kullanıcı onları tek sınıfla ezebilir, !important savaşı çıkmaz. :has() ise CSS'e uzun süredir olmayan "ebeveyn seçiciyi" getirdi ve daha önce JavaScript gerektiren birçok durumu saf CSS ile çözülebilir hâle getirdi.

Seçici performansı efsanesi: "seçicileri sağdan sola okur, bu yüzden kısa tut" tavsiyesi teknik olarak doğrudur ama modern tarayıcılarda ölçülebilir bir fark üretmez — stil hesaplaması tipik bir sayfada milisaniyeler alır. Seçicileri okunabilirlik ve özgüllük için sadeleştir, performans için değil. Gerçek CSS performans sorunları başkadır: çok sayıda ögede yeniden düzen tetikleyen animasyonlar, aşırı büyük stil dosyaları ve pahalı gölge/filtre efektleri.

04Kaskad: hangi kural kazanır

CSS'in adındaki "cascading" budur. Bir ögeye aynı özelliği veren birden çok bildirim varsa, tarayıcı şu sırayla karar verir:

  1. Köken ve önem. Aşağıdaki tablo.
  2. Kaskad katmanı (@layer) — sonra tanımlanan katman kazanır.
  3. Özgüllük. Aşağıda.
  4. Kaynak sırası. Eşitlik bozulmazsa sonra yazılan kazanır.
Sıra (zayıftan güçlüye)Köken
1Tarayıcının varsayılan stilleri (user agent)
2Kullanıcı stilleri (erişilebilirlik ayarları)
3Senin CSS'in (author)
4Senin !important bildirimlerin
5Kullanıcının !important bildirimleri
6Tarayıcının !important bildirimleri

Dikkat: !important devreye girdiğinde sıralama tersine döner — kullanıcının !important'ı seninkini ezer. Bunun sebebi bir erişilebilirlik kararıdır: görme güçlüğü olan bir kullanıcı kendi yazı boyutunu ya da kontrastını dayatabilsin diye. Yani !important sadece bir "kazanma hilesi" değil, kaskadın planlı bir parçasıdır.

Buna karşılık kendi kodunda !important bir borçtur. Bir kez yazdığında, o kuralı ezmek isteyen bir sonraki geliştirici de !important yazmak zorunda kalır ve dosya birkaç ay içinde kaskadın işlemediği bir yığına döner. Meşru kullanımları azdır: (1) değiştiremediğin üçüncü parti CSS'i ezmek, (2) her koşulda geçerli olması gereken yardımcı sınıflar (.gizli { display: none !important; }), (3) hata ayıklarken geçici deneme.

Kaskad katmanları — @layer

/* Öncelik sırası BURADA belirlenir; sonraki katman öncekini ezer */
@layer sifirlama, kutuphane, bilesenler, yardimcilar;

@layer sifirlama   { * { margin: 0; } }
@layer kutuphane   { .btn { padding: 1rem; } }          /* 3. parti */
@layer bilesenler  { .btn { padding: .5rem 1rem; } }    /* seninki KAZANIR */
@layer yardimcilar { .p-0 { padding: 0; } }

Kritik nokta: katman, özgüllükten önce gelir. Yani bilesenler katmanındaki tek sınıflı bir seçici, kutuphane katmanındaki üç sınıflı bir seçiciyi !important'sız ezer. Bu, üçüncü parti bir CSS kütüphanesiyle uğraşmanın en temiz yoludur ve !important savaşını kökten bitirir. Katmansız yazılan CSS, tüm katmanlardan daha güçlüdür — geçiş dönemi için pratik bir davranıştır.

05Özgüllük (specificity)

Aynı köken ve katmandaki iki kural çakışırsa daha özgül olan kazanır. Özgüllük üç haneli bir sayı gibi hesaplanır:

SütunNe sayılırÖrnek
A (id)#ana1-0-0
B (sınıf).kart, [type="text"], :hover0-1-0
C (öge)div, ::before0-0-1
p                         → 0-0-1
.kart p                   → 0-1-1
.kart .baslik             → 0-2-0
#ana .kart p              → 1-1-1
a:hover                   → 0-1-1
[data-durum="acik"] span  → 0-1-1
style="…"                 → satır içi: her seçiciden güçlü
* ve :where(...)          → 0-0-0
:not(.a) / :is(.a, #b)    → argümanın EN YÜKSEĞİ sayılır (:not/:is kendisi sayılmaz)

Karşılaştırma soldan sağa ve mutlaktır: 1-0-0, 0-99-0'dan büyüktür. Yani tek bir id, doksan dokuz sınıftan güçlüdür. Bu, id ile stil vermemenin asıl gerekçesidir — bir kez #ana .baslik yazdığında, o başlığı başka bir yerde ezmek için ya id kullanmak ya da !important yazmak zorunda kalırsın.

Özgüllük tuzağının klasik görünümü şudur:

/* Bileşen kütüphanesinde */
.menu .baglanti { color: gray; }        /* 0-2-0 */

/* Sayfanda */
.aktif { color: teal; }                 /* 0-1-0 → KAYBEDER, çalışmıyor sanırsın */

/* Yanlış çözüm */
.aktif { color: teal !important; }

/* Doğru çözümler */
.menu .aktif { color: teal; }           /* 0-2-0, sonra yazıldığı için kazanır */
@layer bilesenler, sayfa;               /* ya da katmanla, özgüllükten bağımsız */

Pratik disiplin: özgüllüğü düz tut. Tek sınıflı seçicilerle çalış, iç içe uzun zincirler kurma, id kullanma. Böylece kaskadın son adımı olan kaynak sırası devreye girer ve "sonra yazılan kazanır" gibi tahmin edilebilir bir dünyada yaşarsın. SCSS'te iç içe yazmanın (12. ders) en büyük riski tam olarak budur: dört seviye iç içe yazmak farkında olmadan 0-4-0 özgüllüğünde seçiciler üretir.

06Kalıtım ve değer anahtar kelimeleri

Bazı özellikler çocuklara kendiliğinden geçer, bazıları geçmez:

KalıtılırKalıtılmaz
color, font-*, line-height, text-align, letter-spacing, visibility, cursor, list-stylemargin, padding, border, background, width, height, display, position

Kural kabaca şudur: tipografi kalıtılır, kutu özellikleri kalıtılmaz. Bu yüzden body'ye bir kez font-family yazmak tüm sayfayı etkiler ama padding yazmak yalnız gövdeyi etkiler.

Form ögeleri bir istisnadır: <input>, <button>, <select> ve <textarea> yazı tipini kalıtmaz, işletim sisteminin varsayılanını kullanır. Neredeyse her projede yazılan şu satırın sebebi budur:

input, button, select, textarea { font: inherit; }

Dört değer anahtar kelimesi karıştırılır:

AnahtarNe yapar
inheritEbeveynin hesaplanmış değerini zorla al
initialÖzelliğin CSS spesifikasyonundaki başlangıç değerine dön (tarayıcının varsayılanı değil!)
unsetKalıtılan özellikte inherit, diğerlerinde initial gibi
revertTarayıcının varsayılan stiline dön — genelde aradığın budur

Fark somuttur: bir <a> ögesine display: initial yazarsan inline olur (spesifikasyon başlangıcı), display: revert yazarsan tarayıcının <a> için tanımladığı değere döner. initial'ın "varsayılana dön" demek olduğunu sanmak yaygın bir yanlıştır.

Geçersiz değer sessizce atılır

CSS'in en önemli hata ayıklama gerçeği budur: tarayıcı anlamadığı bildirimi yok sayar ve devam eder. Hata mesajı vermez.

.kart {
  color: bulanik-mavi;      /* geçersiz değer — bu satır atılır */
  padding: 10;              /* birim yok — atılır (0 hariç birim zorunludur) */
  colour: red;              /* özellik adı yanlış — atılır */
  background: red           /* noktalı virgül yok — SONRAKİ bildirimi de yutar */
  border: 1px solid;
}

Bu davranış bir kusur değil, ileri uyumluluk tasarımıdır: yeni bir CSS özelliği kullandığında eski tarayıcı onu atlar, sayfa çökmez. Kademeli geliştirmenin (progressive enhancement) temeli budur:

.kutu {
  background: #0f766e;                       /* her tarayıcı anlar */
  background: color-mix(in oklab, #0f766e 70%, white);  /* anlayan üzerine yazar */
}

Ama aynı davranış hata ayıklamayı zorlaştırır: bir kural "çalışmıyorsa" üç ihtimal vardır — (1) seçici tutmuyor, (2) bildirim geçersiz olduğu için atıldı, (3) başka bir kural kaskadda kazandı. DevTools üçünü de gösterir ve tahmin etmeye gerek bırakmaz.

07Yazma disiplini

CSS'in teknik zorluğu düşüktür; ölçek zorluğu yüksektir. Beş bin satırlık bir stil dosyasında bir kuralı değiştirmenin nereyi bozacağını kestirmek zordur. Disiplin bunun içindir.

BEM (Block–Element–Modifier) en yaygın isimlendirme sözleşmesidir:

.kart            { }   /* blok:     bağımsız bileşen */
.kart__baslik    { }   /* öge:      bloğa ait parça */
.kart--vurgulu   { }   /* değiştirici: bloğun bir varyantı */

<article class="kart kart--vurgulu">
  <h2 class="kart__baslik">…</h2>
</article>

BEM'in amacı güzel görünmek değil, her seçiciyi tek sınıf düzeyinde tutmaktır: .kart .baslik yerine .kart__baslik yazarsan özgüllük 0-1-0'da kalır ve kaskad tahmin edilebilir olur. Ayrıca sınıf adı, ögenin hangi bileşene ait olduğunu söylediği için sayfa yapısından bağımsızlaşır.

Diğer temel disiplinler:

  • Sıfırlama/normalize. Tarayıcı varsayılanları farklıdır. Küçük bir sıfırlama bloğu neredeyse her projede bulunur: box-sizing: border-box (8. derste), margin: 0, img { max-width: 100% }, input, button { font: inherit }.
  • Sınıfla stil ver, ögeyle değil. Tip seçicilerini (h2 { }) yalnız genel tipografi için kullan; bileşenler sınıfla stillenir.
  • Değerleri değişkende tut. Renk, boşluk ve yarıçap gibi tekrar eden değerler özel özelliklerde (--vurgu) toplanır; tema desteği bunun üzerine kurulur (12. ders). Bu sitenin koyu/açık teması da böyle çalışır.
  • Bileşen sınırı çiz. Bir bileşenin CSS'i, dışarıdaki ögelere kural yazmamalıdır; dış boşluğu (margin) bileşenin kendisi değil onu yerleştiren düzen belirlemelidir.
  • Ölü kod birikir. CSS silmek eklemekten zordur, çünkü hangi kuralın hâlâ kullanıldığını bilmek zordur. DevTools'un Coverage sekmesi kullanılmayan CSS'i gösterir — kesin değildir (koşullu durumları göremez) ama iyi bir başlangıç noktasıdır.

DevTools: hangi kural kazandı

Bu dersin en pratik aracı Elements panelinin sağ tarafıdır:

  • Styles sekmesi kuralları kazanan en üstte olacak şekilde sıralar. Üstü çizili bildirimler ezilmiş olanlardır — üzerine gelince hangi kuralın ezdiğini gösterir.
  • Computed sekmesi her özelliğin son değerini verir; yanındaki oka basınca o değerin hangi kuraldan geldiğini ve dosya/satır numarasını gösterir.
  • Geçersiz bildirimler uyarı simgesiyle işaretlenir — "neden çalışmıyor" sorusunun cevabı çoğu zaman buradadır.
  • :hov düğmesiyle :hover, :focus, :active durumlarını zorlayabilirsin; fareyi çekince kaybolan stilleri incelemenin tek pratik yolu budur.
  • Sol alttaki kutu modeli diyagramı, ögenin gerçek geometrisini gösterir — 8. dersin konusu.

Kural: CSS'te tahmin etme, oku. "Neden çalışmıyor" sorusunun cevabı üç yerden birindedir — seçici tutmuyor (Elements'te öge seçili mi, kural listede görünüyor mu), bildirim geçersiz (uyarı simgesi), ya da kaskadda kaybetti (üstü çizili).

08Mini alıştırma — Kaskadı kendi elinle kır

Yaklaşık 20 dakika · tek HTML dosyası + <style>

  1. Kur: bir kart bileşeni yaz (article.kart içinde başlık, metin, bağlantı). Stilini dış dosyada tanımla.
  2. Üç yol: aynı başlığa dış dosyadan, <style>'dan ve style="" özniteliğinden farklı renkler ver. Hangisi kazandı? DevTools'ta üstü çizili olanları oku.
  3. Özgüllük yarışı: sırasıyla p, .kart p, .kart .metin, #ana .metin seçicileriyle dört farklı renk yaz. Her adımda hangisinin kazandığını tahmin et, sonra doğrula.
  4. Kaynak sırası: aynı özgüllükte iki kural yaz ve sıralarını değiştir. Sonuç değişti mi?
  5. !important: kaybeden kurala !important ekle; sonra kazanan kurala da ekle. Şimdi hangisi kazanıyor, neden?
  6. Katman: @layer kutuphane, sayfa; tanımla ve iki kuralı bu katmanlara koy. kutuphane katmanındaki seçiciyi daha özgül yap — yine de kaybediyor mu?
  7. :where: aynı kuralı bir kez :is(), bir kez :where() ile yaz ve tek sınıfla ezmeyi dene.
  8. Kalıtım: body'ye color ve border ver. Hangisi çocuklara geçti? Sonra bir <input> koy — yazı tipi kalıttı mı? font: inherit ekleyip tekrarla.
  9. Anahtar kelimeler: bir bağlantıya sırayla display: initial, unset, revert yaz ve Computed sekmesinde hesaplanan değeri karşılaştır.
  10. Sessiz hata: padding: 10 ve colour: red yaz. DevTools ne gösteriyor? Bir bildirimin sonundaki noktalı virgülü sil ve kaç bildirimin düştüğünü gör.
  11. Grup seçici: h1, h2:: , h3 { color: red } gibi içinde bozuk bir parça olan grup yaz. Kaçı stillendi?
  12. :has(): içinde geçersiz bir input bulunan alan grubunun çerçevesini kırmızıya çevir. Klasik yöntemle (JavaScript ile sınıf ekleyerek) karşılaştır.
  13. Durum zorlama: :hov düğmesiyle :focus-visible durumunu zorla ve odak stilini incele.
  14. Coverage: DevTools → Coverage sekmesini çalıştır. Stil dosyanın yüzde kaçı kullanılmıyor?

09Kendini sına

İki CSS kuralı aynı ögeye farklı değer veriyorsa hangisi uygulanır?

Tarayıcı sırayla bakar. (1) Köken ve önem: tarayıcı varsayılanı < kullanıcı stili < yazar (senin) stilin < senin !important'ın < kullanıcının !important'ı < tarayıcının !important'ı. Dikkat: !important devreye girince sıra tersine döner — bu, kullanıcının erişilebilirlik ayarlarını dayatabilmesi için bilinçli bir tasarımdır. (2) Kaskad katmanı: @layer ile tanımlanmış katmanlarda sonra gelen katman kazanır ve bu, özgüllükten önce gelir; katmansız yazılan CSS tüm katmanlardan güçlüdür. (3) Özgüllük: id–sınıf–öge sayımı, soldan sağa mutlak karşılaştırmayla; satır içi stil bunların hepsinden güçlüdür. (4) Kaynak sırası: her şey eşitse sonra yazılan kazanır. Pratik sonuç: özgüllüğü düz tutarsan (tek sınıflı seçiciler, id yok) kaskad çoğu zaman dördüncü adıma düşer ve davranış tahmin edilebilir olur. DevTools'un Styles sekmesi kazananı en üstte gösterir, ezilenleri üstü çizili yazar.

Özgüllük nasıl hesaplanır? #ana .kart p ile .kart .baslik .metin hangisi kazanır?

Özgüllük üç sütunda sayılır: A id sayısı, B sınıf + öznitelik + sözde sınıf sayısı, C öge + sözde öge sayısı. #ana .kart p = 1-1-1; .kart .baslik .metin = 0-3-0. Karşılaştırma soldan sağa ve mutlaktır: A sütunundaki 1, B sütunundaki 3'ten büyüktür, dolayısıyla #ana .kart p kazanır. Tek bir id, doksan dokuz sınıftan güçlüdür — id ile stil vermemenin asıl gerekçesi budur, çünkü bir kez id kullandığında onu ezmek için ya başka bir id ya da !important gerekir. Özel durumlar: * ve :where() özgüllüğe hiç katkı yapmaz; :is() ve :not() kendileri sayılmaz ama argümanlarının en yükseğini alır (:is(.a, #b) → 1-0-0); satır içi style özniteliği her seçiciden güçlüdür ve yalnız !important ile ezilir.

!important ne zaman kullanılır, kullanılmamalıdır? Alternatifi nedir?

Kendi kodunda neredeyse hiç. Bir kez yazıldığında, o kuralı ezmek isteyen bir sonraki geliştirici de !important yazmak zorunda kalır; birkaç ay sonra kaskadın hiç işlemediği, her değişikliğin başka bir yeri bozduğu bir stil dosyası kalır. Meşru kullanımlar sınırlıdır: (1) değiştiremediğin üçüncü parti CSS'i ezmek, (2) her koşulda geçerli olması gereken tek amaçlı yardımcı sınıflar (.gizli { display: none !important }), (3) hata ayıklarken geçici deneme. Alternatifler: @layer — katman sırası özgüllükten önce geldiği için kütüphane katmanındaki en özgül kuralı bile kendi katmanındaki tek sınıfla ezersin; özgüllüğü eşitlemek — kaybeden kuralı aynı özgüllüğe getirip sonra yazmak; :where() — kendi varsayılan stillerini sıfır özgüllükle yazmak, ki kullanıcıları !important'a mecbur kalmasın. Son not: kullanıcı stillerindeki !important seninkini ezer — bu bir hata değil, erişilebilirlik için tasarlanmış davranıştır.

Yazdığın bir CSS kuralı çalışmıyor. Nasıl teşhis edersin?

Üç ihtimal vardır ve DevTools üçünü de gösterir. (1) Seçici tutmuyor: Elements panelinde ögeyi seç ve kuralın Styles listesinde görünüp görünmediğine bak; görünmüyorsa seçici eşleşmiyordur — sınıf adında yazım hatası, > ile arada beklenmedik bir öge (table > tr tuzağı), :nth-child ile :nth-of-type karışıklığı, ya da JavaScript'in sınıfı henüz eklememesi. (2) Bildirim geçersiz: CSS anlamadığı bildirimi sessizce atar — birimsiz uzunluk (padding: 10), yanlış özellik adı, tanımsız renk, ya da bir önceki satırda unutulan noktalı virgül (o durumda iki bildirim birden düşer). DevTools bunları uyarı simgesiyle işaretler. (3) Kaskadda kaybetti: kural listede var ama üstü çizili; üzerine gelince onu ezen kural gösterilir. Bu durumda özgüllüğü, katmanı ve kaynak sırasını karşılaştırırsın. Computed sekmesi ise özelliğin son değerinin hangi dosyanın hangi satırından geldiğini doğrudan söyler. Ek ipuçları: fareyle kaybolan durumlar için :hov ile durumu zorla; stil dosyasının güncel olduğundan emin olmak için önbelleği devre dışı bırakıp yenile.

10Sınav köşesi

Yazılıda nasıl sorulur

(1) CSS nedir, HTML'e kaç yolla bağlanır? (2) Seçici türlerini yazınız. (3) id ile class seçicilerinin farkı; hangisi tercih edilir? (4) Kaskad nedir? (5) Özgüllük nasıl hesaplanır — genelde bir örnek verilip "hangi renk uygulanır" diye sorulur. (6) !important ne yapar, ne zaman kullanılmalıdır? (7) Kalıtılan ve kalıtılmayan özelliklere örnek veriniz. (8) :hover, :focus, ::before nedir; sözde sınıf ile sözde öge farkı. (9) Birleştiriciler: >, +, ~, boşluk. (10) inherit, initial, unset, revert farkı. (11) @import neden önerilmez?

Sözlüde nasıl anlatılır — 2 dakikalık taslak

Düzen: (1) Tanım — "CSS seçici ve bildirimlerden oluşur; adındaki 'cascading', çakışan kurallar arasında karar verme düzenidir." (2) Karar sırası — "önce köken ve önem, sonra kaskad katmanı, sonra özgüllük, en son kaynak sırası. !important devreye girince köken sırası tersine döner; bu kullanıcının erişilebilirlik ayarını dayatabilmesi için bilinçli bir tasarımdır." (3) Özgüllük — "id–sınıf–öge olarak sayılır ve karşılaştırma mutlaktır: bir id, doksan dokuz sınıftan güçlüdür. Bu yüzden stil için id kullanmam, özgüllüğü tek sınıf düzeyinde tutarım." (4) Kıdem vuruşu — "üçüncü parti CSS'i ezmek için !important yerine @layer kullanırım; katman sırası özgüllükten önce geldiği için kendi tek sınıflı kuralım kütüphanenin en özgül kuralını ezer." (5) Hata ayıklama — "CSS geçersiz bildirimi sessizce atar; bir kural çalışmıyorsa seçici mi tutmuyor, bildirim mi geçersiz, kaskadda mı kaybetti diye DevTools'ta Styles ve Computed sekmelerinden okurum — tahmin etmem."