CSS'iniz çalışmıyorsa, nedeni çoğu zaman şu üç gruptan birindedir: tarayıcı bildirimi geçersiz sayıp sessizce attı (yazım hatası, eksik noktalı virgül, yanlış değer türü), bildirim geçerli ama cascade'de başka bir kurala yenildi (özgüllük, kaynak sırası, katman, !important) ya da kural uygulandı ama bir düzen kuralı beklediğiniz sonucu engelliyor (stacking context, margin çökmesi gibi). CSS, JavaScript gibi hata fırlatmaz; MDN'in ifadesiyle tarayıcılar CSS hataları için uyarı göstermez, geçersiz içeriği atar ve sonraki geçerli stilleri ayrıştırmaya devam eder.
Bu yazıda önce tarayıcının hatalı CSS'i nasıl ele aldığını, yani neyin ne kadarının atıldığını, MDN'in hata işleme rehberine dayanarak anlatıyoruz. Ardından en sık karşılaşılan "çalışmıyor" durumlarını belirtiye göre teşhis etmeyi gösteriyoruz. Ayrıntılı konular için seri içindeki ilgili yazılara bağlantı veriyoruz.
Tarayıcı hatalı CSS ile ne yapar?

MDN'e göre ayrıştırıcı bir hatayla karşılaştığında, hatayı içeren kısmı yok sayar ve olabildiğince az kodu atarak normal ayrıştırmaya döner. Bu bir eksiklik değil, CSS'in bilinçli bir özelliğidir: eski bir tarayıcı yeni bir özelliği tanımasa bile sayfa bozulmaz. Ne kadar kodun atılacağı ise hatanın türüne bağlıdır:
| Hata türü | Atılan kısım |
|---|---|
| Bilinmeyen özellik adı veya geçersiz değer | Yalnızca o bildirim |
| Eksik noktalı virgül | Hatalı bildirim ve ardından gelen bildirim |
| Seçici listesinde geçersiz bir seçici | Bütün kural bloğu |
| At-rule içinde hata | At-rule ve hatanın türüne göre tek satır ya da bütün kural |
| Kapanmamış süslü parantez | İç içe yazım olarak ne kadar ayrıştırılabildiğine bağlı |
Eksik noktalı virgül: iki bildirim birden gider
p {
/* noktalı virgül eksik */
border-color: red
background-color: green;
/* geçerli ama büyük olasılıkla mantık hatası */
border-width: 100vh;
}
/* sonuç: border-color ve background-color ikisi de atılır;
border-width: 100vh uygulanır */Neden iki bildirim birden gidiyor? Ayrıştırıcı bir bildirimi noktalı virgüle ya da kapanış süslü parantezine kadar okur. Noktalı virgül eksik olduğu için border-color değeri red background-color: green olarak okunur; bu geçerli bir <color> değildir ve bildirim atılır. Ayrıştırıcı bir sonraki noktalı virgülden devam ettiği için background-color da kaybolur. Son satırdaki 100vh kenarlık kalınlığı muhtemelen bir hatadır ama sözdizimi geçerlidir; CSS bunu hata saymaz ve uygular. Yani "geçerli" ile "istediğiniz" aynı şey değildir.
Geçersiz seçici bütün bloğu öldürür
Var olmayan bir sınıfı, kimliği ya da öğe adını seçmek mantık hatasıdır ama sözdizimi hatası değildir; kural yalnızca hiçbir şeyle eşleşmez. Buna karşılık bir sözde sınıfın ya da sözde öğenin adındaki yazım hatası geçersiz bir seçici oluşturabilir. Seçici listesindeki tek geçersiz seçici, listenin ve kural bloğunun tamamını geçersiz kılar:
h1, h2:hovr, .baslik {
color: darkblue;
}
/* sonuç: :hovr geçersiz olduğu için h1 ve .baslik de renk almaz */
:is(h1, h2:hovr, .baslik) {
color: darkblue;
}
/* sonuç: :is() bağışlayıcı liste kabul eder; yalnızca h2:hovr
yok sayılır, h1 ve .baslik renk alır */İki istisna vardır. :is() ve :where() bağışlayıcı (forgiving) seçici listesi kabul eder; içlerindeki geçersiz seçici yalnızca hiçbir şeyle eşleşmez. İkinci istisna tarihsel bir nedenden gelir: -webkit- önekiyle başlayan ve parantezle bitmeyen sözde öğeler, tarayıcı onları tanımasa bile geçerli sayılır ve listeyi bozmaz. ::-webkit-hayali-fonksiyon() gibi parantezli bir önekli sözde öğe ise bütün listeyi geçersiz kılar. Bu sözde sınıfların kullanım desenleri için :has(), :is(), :where(), :not() yazısına bakabilirsiniz.
At-rule hataları
At-rule'larda neyin atılacağı kuralın kendi dilbilgisine bağlıdır. MDN'den birkaç önemli örnek:
- @import yeri:
@import,@charset,@layerve diğer@importifadeleri dışındaki herhangi bir CSS'ten sonra gelirse yok sayılır. İçe aktardığınız dosyanın hiç yüklenmiyormuş gibi görünmesinin sık nedenidir. - @font-face zorunlu tanımlayıcıları:
font-familyvesrczorunludur; biri eksik ya da geçersizse bütün@font-facekuralı geçersiz olur. Diğer geçersiz tanımlayıcılar ise yalnızca kendileri atılır. - @keyframes: Anahtar kare içindeki
!importantbildirimler ve canlandırılamayan özellikler yok sayılır ama aynı karedeki diğer stilleri etkilemez.0%'dan küçük,100%'den büyük ya da%işareti unutulmuş bir anahtar kare seçicisi yalnızca o karenin bloğunu atar. İki anahtar kare bloğu arasına stil yazmak ise bütün@keyframeskuralını geçersiz kılar. - @layer kapanış parantezi: Unutulmuş bir kapanış parantezi sözdizimi hatası değil, mantık hatasıdır; sonraki bütün stiller o katmanın içinde sayılır ve hiçbir şey atılmaz.
Yazı tipi tanımlarının ayrıntısı için @font-face ve yazı tipi özellikleri, animasyon kuralları için animation ve @keyframes, katmanlar için @layer yazılarına bakabilirsiniz.
Kapanmamış yapılar ve yorumlar
Stil dosyası bir kural, bildirim, fonksiyon, metin ya da yorum açıkken biterse ayrıştırıcı açık kalan her şeyi otomatik olarak kapatır. Son noktalı virgülden sonraki içerik eksik de olsa geçerliyse normal biçimde ayrıştırılır. MDN yine de bu bağışlayıcılığa güvenmemenizi, her bloğu açıkça kapatmanızı önerir.
Kapanmamış yorum ise daha sinsi bir sorundur. /* ile başlayıp kapanmayan bir yorum, sonraki bir yorumun kapanış işaretine (*/) ya da stil dosyasının sonuna kadar her şeyi yorumun parçası yapar. CSS geçersiz olmaz, ama açılış işaretinden sonraki kodun tamamı yok sayılır. Dosyanın yarısından sonrası birden çalışmayı bıraktıysa ilk bakacağınız yer burasıdır. Yorum sözdizimi için CSS sözdizimi yazısına bakabilirsiniz.
Yanlış tür ve var() tuzağı
Her bildirim, ayrıştırıldıktan sonra o özelliğin dilbilgisine göre denetlenir. background-color: 45deg yazarsanız değer bir açıdır, renk değildir; bildirim geçersizdir ve atılır, özellik daha önceki geçerli değerinde kalır. Özel özelliklerde ise durum farklıdır ve çok sık karıştırılır:
.kart {
background-color: lightyellow;
background-color: var(--theme-color);
}
:root {
--theme-color: 45deg;
}
/* sonuç: zemin lightyellow kalmaz, transparent olur */Adım adım: --theme-color: 45deg bildirimi geçerlidir, çünkü özel özellikler hemen her değeri kabul eder. var(--theme-color) içeren bildirim de ayrıştırma sırasında geçerli görünür; tarayıcı değişkenin hangi değeri taşıyacağını henüz bilmez. Değer hesaplanırken 45deg yerine konduğunda dilbilgisi bozulur. MDN'e göre bu durumda bildirim atılmaz; özellik kalıtılan bir özellikse üst öğeden kalıtılan değeri, değilse başlangıç değerini alır. background-color kalıtılmadığı için başlangıç değeri transparent kullanılır ve önceki satırdaki lightyellow yedeği işe yaramaz.
Bu tuzaktan kaçınmanın yolu değişkeni @property ile türlendirmek ya da var() ile yedek değer vermektir. Ayrıntılar @property ve CSS değişkenleri yazılarında.
Yedekleri doğru sırayla yazın
Geçersiz bildirimlerin atılması, eski ve yeni sözdizimini aynı kuralda bir arada kullanmanıza olanak tanır. Şart, eski sözdiziminin önce, yenisinin sonra yazılmasıdır:
div {
display: inline-flex;
display: inline flex;
}
/* yeni çok anahtar sözcüklü sözdizimini tanıyan tarayıcı ikinci
satırı uygular; tanımayan tarayıcı onu atar ve ilk satırda kalır */Sıra tersine çevrilirse yeni sözdizimini tanıyan tarayıcı da eski değeri uygular, çünkü cascade'de son gelen geçerli bildirim kazanır. Aynı mantık satıcı önekleri (vendor prefix) için de geçerlidir: MDN, önekli özelliklerden mümkün olduğunca kaçınmanızı, kullanmak zorundaysanız önekli sürümleri öneksiz sürümden önce yazmanızı önerir. display değerlerinin ayrıntısı için display değerleri, özellik desteğine göre kural yazmak için @supports yazısına bakabilirsiniz.
Kural geçerli ama uygulanmıyor: cascade

Bildiriminiz geçerliyse ve yine de etkisini görmüyorsanız büyük olasılıkla başka bir bildirime yeniliyordur. Cascade, çakışan bildirimleri şu sırayla karşılaştırır: köken ve önem (!important), katmanlar, özgüllük, @scope yakınlığı ve en son kaynaktaki sıra. Özgüllük yalnızca önceki ölçütler eşitse dikkate alınır; bu yüzden daha özgül bir seçici, daha öncelikli bir katmandaki kurala yine de yenilebilir.
- Özgüllük:
#menu a(1-0-1),.nav a(0-1-1) kuralını kaynak sırası ne olursa olsun yener. Hesap için özgüllük hesaplama. - !important: Önemli bildirimler normal bildirimlerden ayrı bir öncelikle değerlendirilir; katmanlarla birlikte kullanıldığında sıra tersine döner. Ayrıntı cascade ve kalıtım ve @layer yazılarında.
- Kalıtım beklentisi: Her özellik kalıtılmaz. Üst öğeye verdiğiniz
borderçocuklara geçmez,colorgeçer.
z-index çalışmıyor
z-index, konumlandırılmış öğelerde (position değeri static dışında olanlar) ve flex ile grid öğelerinde çalışır. Normal akıştaki position: static bir öğeye z-index: 9999 vermek bir şey değiştirmez. İkinci ve daha sık neden stacking context'tir: bir öğenin z-index değeri yalnızca kendi stacking context'i içinde anlam taşır ve o bağlam üst bağlamda tek bir birim olarak sıralanır.
.kart {
transform: translateX(0);
}
.kart .acilir-menu {
position: absolute;
z-index: 1000;
}
.sonraki-bolum {
position: relative;
z-index: 1;
}
/* sonuç: transform değeri none olmadığı için .kart yeni bir stacking
context oluşturur. Menünün 1000 değeri yalnızca kartın içinde
geçerlidir; kart sonraki bölümün altında kalıyorsa menü de kalır */MDN'deki listeye göre stacking context oluşturan durumların bazıları şunlardır: position değeri absolute ya da relative olup z-index değeri auto olmayan öğeler, fixed ve sticky öğeler, opacity değeri 1'den küçük öğeler, transform, filter, backdrop-filter gibi özelliklerden biri none dışında olan öğeler, isolation: isolate ve container-type değeri size ya da inline-size olan öğeler. Tam liste ve örnekler için z-index ve stacking context yazısına bakın.
Margin beklenmedik yerde: margin çökmesi
Blokların üst ve alt marginleri bazı durumlarda birleşir ve tek bir margin oluşur; boyutu marginlerin en büyüğüdür. Bu davranış genellikle iki biçimde "hata" gibi görünür: alt alta iki paragrafın marginleri toplanmaz, büyük olanı kalır; ya da ilk çocuğa verdiğiniz margin-top, üst öğenin içinde değil dışında, üst öğeyi aşağı iterek görünür. İkinci durum, üst öğenin border-top, padding-top veya satır içi içeriği olmadığında olur.
.kapsayici {
background: lightgray;
}
.kapsayici h2 {
margin-top: 2rem;
}
/* sonuç: boşluk gri zeminin içinde değil üstünde oluşur;
başlığın marginini kapsayıcının margini ile çöker */
.kapsayici-duzeltilmis {
background: lightgray;
padding-top: 1px;
}
/* padding (ya da border) marginleri ayırır; flex veya grid
kapsayıcıda da marginler çökmez */MDN'e göre marginler yalnızca dikey yönde çöker; yüzen (float) ve mutlak konumlu öğelerin marginleri hiç çökmez; display değeri flex veya grid olan bir kapsayıcıda da çökme olmaz. Üst öğede yeni bir blok biçimlendirme bağlamı (BFC) oluşturmak da üst-çocuk çökmesini engeller. Bütün kurallar margin çökmesi yazısında.
Belirtiden nedene: hızlı teşhis tablosu

| Belirti | Olası neden | İlk kontrol |
|---|---|---|
| Kuraldaki hiçbir stil uygulanmıyor | Seçici listesinde geçersiz seçici | Sözde sınıf ve sözde öğe adları |
| Arka arkaya iki özellik kayboldu | Eksik noktalı virgül | İlk kaybolan bildirimin sonu |
| Dosyanın bir noktasından sonrası çalışmıyor | Kapanmamış yorum veya parantez | Son çalışan kuraldan sonraki satırlar |
| İçe aktarılan dosya etkisiz | @import yanlış yerde | Dosyanın başında mı |
| Değişkenli renk saydam çıkıyor | var() ile yanlış türde değer | Değişkenin değeri ve türü |
| Stil başka kurala yeniliyor | Özgüllük, katman, !important | Kazanan kuralın seçicisi |
| z-index etkisiz | Konumlandırma yok veya stacking context | Üst öğelerde transform, opacity |
| Üstte beklenmedik boşluk | Margin çökmesi | Üst öğede padding veya border |
Sistemli hata ayıklama adımları
- 1. Kural eşleşiyor mu? Seçicinin hedeflediğiniz öğeyle gerçekten eşleştiğinden emin olun. Var olmayan bir sınıf adı hata üretmez, yalnızca hiçbir şeyle eşleşmez.
- 2. Bildirim geçerli mi? Özellik adını, değer türünü ve noktalı virgülleri kontrol edin. MDN'deki "Formal syntax" bölümü özelliğin hangi değerleri kabul ettiğini gösterir.
- 3. Bildirim kazanıyor mu? Aynı özelliği ayarlayan diğer kuralları bulun; köken, katman, özgüllük ve sırayı karşılaştırın.
- 4. Değer beklediğiniz gibi hesaplanıyor mu?
var(), yüzdeler veemgibi göreli değerler başka değerlere bağlıdır. - 5. Düzen kuralı engelliyor mu? Stacking context, margin çökmesi, taşma (overflow) ve kapsayıcı blok gibi kavramları gözden geçirin.
Taşma ve kırpılma sorunları için overflow, konumlandırma referansının neresi olduğu için position yazılarına bakabilirsiniz.
Sık Sorulan Sorular
Tarayıcı CSS hatalarını neden göstermiyor?
MDN'e göre bu CSS'in tasarımının bir parçasıdır: tarayıcılar hata bildirmek yerine geçersiz içeriği atar ve devam eder. Bu sayede yeni özellikler, onları tanımayan eski tarayıcıları bozmadan kullanılabilir.
Geçersiz bir değer önceki geçerli değeri siler mi?
Normal bir bildirimde hayır; geçersiz bildirim atılır ve önceki geçerli değer kalır. Ancak var() ile oluşan geçersizlik hesaplama anında fark edildiği için özellik kalıtılan ya da başlangıç değerine döner; önceki değer kullanılmaz.
Bir seçici yanlışsa bütün dosya mı bozulur?
Hayır. Yalnızca o seçicinin bulunduğu kural bloğu atılır; ayrıştırıcı kapanış süslü parantezini bulup sonraki kurallardan devam eder. Dosyanın geri kalanı etkileniyorsa kapanmamış bir yorum ya da parantez arayın.
!important ile her sorunu çözebilir miyim?
Sorunu gizleyebilir ama cascade'i daha karmaşık hâle getirir; sonraki bir değişiklikte onu ezmek için yine !important gerekir. Önce neden yenildiğini bulun: özgüllük mü, katman mı, kaynak sırası mı? Çoğu zaman seçiciyi sadeleştirmek ya da katman kullanmak daha kalıcı bir çözümdür.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: CSS öğrenme rehberi · CSS sözdizimi · Özgüllük · z-index · Margin çökmesi