CSS pseudo-element (sözde öğe), bir seçiciye çift iki nokta (::) ile eklenen ve seçilen öğenin belirli bir parçasına stil vermenizi sağlayan anahtar kelimedir. ::before ve ::after öğenin içine, başına ve sonuna HTML'de olmayan yeni içerik ekler; ::first-line paragrafın ilk satırını, ::first-letter ilk harfini, ::marker liste işaretini, ::placeholder yer tutucu metni, ::selection ise kullanıcının seçtiği metni hedefler. Böylece işaretlemeye fazladan span eklemeden süsleme, simge, alıntı işareti ya da büyük ilk harf gibi efektler oluşturabilirsiniz.
Bu yazıda pseudo-element sözdizimini, ::before ve ::after ile content özelliğinin nasıl çalıştığını, tipografik ve form pseudo-element'lerinde hangi özelliklerin kullanılabildiğini ve erişilebilirlik açısından nelere dikkat etmeniz gerektiğini MDN belgelerine dayanarak anlatıyoruz. Öğenin bir durumunu seçen :hover ve :nth-child() gibi yapılar için pseudo-class yazısına bakabilirsiniz.
Sözdizimi: neden iki iki nokta?
Pseudo-element'ler seçici::ad biçiminde yazılır. MDN'ye göre çift iki nokta, pseudo-element'leri tek iki noktalı pseudo-class'lardan ayırmak için Selectors Level 3 belirtimiyle getirildi. Geriye dönük uyumluluk için tarayıcılar ilk dört pseudo-element'in, yani ::before, ::after, ::first-line ve ::first-letter için CSS2'den kalma tek iki noktalı yazımı da kabul eder. Yeni yazılan kodda her zaman çift iki nokta kullanmak, kodu okuyan kişiye neyin pseudo-class neyin pseudo-element olduğunu hemen gösterir.
Pseudo-element'ler bağımsız var olamaz; bir parçası oldukları öğeye köken öğe (originating element) denir. MDN iki kural koyar. Birincisi, pseudo-element bileşik ya da karmaşık seçicide diğer bütün bileşenlerden sonra gelmelidir; seçicideki son öğe, pseudo-element'in köken öğesidir. Bu yüzden p::first-line > * geçersizdir, çünkü ilk satırın çocuklarını seçemezsiniz. İkincisi, pseudo-element köken öğenin durumuna göre seçilebilir: p:hover::first-line, paragrafın üzerine gelindiğinde paragrafın ilk satırını seçer.
/* geçerli: önce durum, sonra parça */
p:hover::first-line {
color: blue;
}
/* geçersiz: pseudo-element sonda olmalı */
/* p::first-line > span { ... } */::before ve ::after: içerik eklemek

::before, seçilen öğenin ilk çocuğu olarak bir pseudo-element oluşturur; ::after ise son çocuğu olarak. MDN'ye göre ikisi de varsayılan olarak satır içi (inline) bir kutudur ve genellikle content özelliğiyle simge, alıntı işareti ya da başka süslemeler eklemek için kullanılır. Bu iki pseudo-element'in çalışması için bilmeniz gereken en önemli kural şudur: content özelliği belirtilmemişse, geçersiz bir değer almışsa ya da değeri normal veya none ise pseudo-element çizilmez ve display: none verilmiş gibi davranır.
q::before {
content: "«";
color: blue;
}
q::after {
content: "»";
color: red;
}
/* sonuç: alıntının başında mavi «, sonunda kırmızı » görünür */İkinci önemli kural değiştirilmiş öğelerle (replaced elements) ilgilidir. MDN, <img> gibi içeriği dış bir kaynak tarafından belirlenen ve belgenin stillerinden etkilenmeyen öğelere ::before ve ::after uygulanamayacağını belirtir. Bir görselin üzerine etiket koymak istiyorsanız görseli bir kapsayıcıya alıp pseudo-element'i kapsayıcıya vermeniz gerekir.
Katmanlama konusunda da bir ayrıntı var: ::before ve ::after varsayılan olarak ebeveynleriyle aynı yığın bağlamını paylaşır. z-index açıkça verilmemişse ::after içeriği, akışta daha sonra çizildiği için ::before içeriğinin üzerinde görünür. İki süsleme üst üste biniyorsa sıralamayı z-index ve stacking context yazısında anlatılan kurallarla yönetebilirsiniz.
content özelliğinin değerleri
content, pseudo-element'in içine ne konacağını belirler. MDN'ye göre başlangıç değeri normal değeridir ve ::before ile ::after için none olarak hesaplanır; bu da yukarıdaki "content yoksa çizilmez" kuralının kaynağıdır. Kullanabileceğiniz başlıca değerler şunlardır:
- Metin (
<string>): Tek ya da çift tırnak içinde karakterler. Birden çok metin değeri yan yana yazılırsa birleştirilir; CSS'te ayrı bir birleştirme operatörü yoktur. - Görsel:
url(),image-set()ya da bir gradyan. - Sayaç:
counter()vecounters()fonksiyonlarıylacounter-resetvecounter-incrementile yönetilen sayaçların değeri. - attr(): Köken öğenin bir özniteliğinin değeri. Öznitelik yoksa boş metin döner.
- Alıntı anahtar kelimeleri:
open-quoteveclose-quote,quotesözelliğindeki uygun işaretlerle değiştirilir. - Alternatif metin: Değerin sonuna eğik çizgi ve bir metin eklenerek ekran okuyucular için alternatif metin verilebilir:
content: url("ikon.svg") / "Uyarı";.
a.dis-baglanti::after {
content: " (" attr(href) ")";
/* bağlantı metninin ardından adresi parantez içinde gösterir */
}
.yeni::after {
content: " Yeni!";
/* baştaki boşluk, öğe metniyle eklenen metin arasında ayrım yaratır */
color: red;
}
.uyari::before {
content: "⚠ " / "Uyarı";
/* ekran okuyucu için alternatif metin: Uyarı */
}Yalnızca görsel bir süsleme (bir çizgi, bir kutu, bir üçgen) çizmek istediğinizde content değerine boş bir metin verirsiniz: content: "";. Boş metin none ya da normal olmadığı için pseudo-element oluşturulur; boyutunu ve görünümünü diğer özelliklerle belirlersiniz. Varsayılan olarak satır içi olduğu için genişlik ve yükseklik vermeden önce display: block ya da display: inline-block vermeniz gerekir; satır içi kutulardaki boyut davranışı display yazısında anlatılıyor.
.baslik::after {
content: "";
display: block;
width: 3rem;
height: 4px;
margin-top: 0.5rem;
background-color: #1166ff;
/* başlığın altında kısa mavi bir çizgi */
}Tipografik pseudo-element'ler: ::first-line ve ::first-letter

::first-line, bir blok kapsayıcının ilk satırına stil verir. İlk satırın uzunluğu sabit değildir: öğenin genişliğine, belgenin genişliğine ve yazı boyutuna bağlıdır. Pencere daraldıkça ilk satırda kalan kelimeler değişir ve stil kendiliğinden yeni ilk satıra uygulanır. MDN'ye göre öğenin ilk çocuğu satır içi bir tablo gibi satır içi blok düzeyinde bir öğeyse ::first-line etkisizdir. Arka plan açısından da satır içi bir öğe gibi davrandığı için sola hizalı bir ilk satırda arka plan sağ kenara kadar uzanmayabilir.
::first-line içinde yalnızca küçük bir özellik alt kümesi kullanılabilir: bütün yazı tipi özellikleri, bütün arka plan özellikleri, color, word-spacing, letter-spacing, text-decoration, text-transform, line-height, text-shadow ve vertical-align. MDN'nin örneği özellikle uyarır: margin-left ve text-indent gibi özellikler ::first-line içinde geçersizdir.
::first-letter, blok kapsayıcının ilk satırındaki ilk harfe stil verir, ancak önünde görsel ya da satır içi tablo gibi başka içerik yoksa. İlk harfin ne olduğu her zaman basit değildir. MDN üç durumu sayar: İlk harften hemen önce ya da sonra gelen noktalama işaretleri eşleşmeye dahildir; Felemenkçedeki IJ gibi her zaman birlikte büyük yazılan çift harfler ikisi birden eşleşmelidir (MDN bunun desteğinin zayıf olduğunu da not eder); ve ::before ile öğenin başına içerik eklenmişse ::first-letter bu eklenen içeriğin ilk harfiyle eşleşir.
::first-letter içinde kullanılabilen özellikler ::first-line listesinden daha geniştir: Yazı tipi ve arka plan özelliklerine ek olarak bütün margin, padding ve kenarlık özellikleri, box-shadow ve float da kullanılabilir. vertical-align ise yalnızca float değeri none ise geçerlidir. Bu genişlik, gazete ve dergilerdeki büyük ilk harf (drop cap) efektini mümkün kılar.
h2 + p::first-letter {
float: left;
font-size: 3em;
line-height: 1;
padding: 0.1em 0.15em;
margin-right: 0.1em;
color: white;
background-color: black;
/* başlıktan hemen sonraki paragrafın ilk harfi büyük, siyah zeminli ve metnin soluna yaslanır */
}
article p::first-line {
font-weight: bold;
/* paragrafın ekranda ilk satırına düşen kelimeler kalın */
}Liste ve form parçaları: ::marker ve ::placeholder
::marker, bir liste öğesinin işaret kutusunu, yani genellikle madde imini ya da numarayı seçer. display: list-item olan her öğe ya da pseudo-element üzerinde çalışır; <li> ve <summary> bunun tipik örnekleridir. MDN'ye göre bir ::before ya da ::after pseudo-element'ine display: list-item verirseniz o da bir ::marker üretebilir. ::marker içinde kullanılabilen özellikler sınırlıdır: bütün animasyon ve geçiş özellikleri, bütün yazı tipi özellikleri, color, content, sayaç özellikleri, quotes, direction, unicode-bidi, text-combine-upright ve white-space.
li::marker {
color: crimson;
font-size: 1.2em;
}
ul.ozel li::marker {
content: "✓ ";
/* madde imi yerine onay işareti */
}::placeholder, bir <input> ya da <textarea> öğesindeki yer tutucu metni temsil eder. Bu pseudo-element'te yalnızca ::first-line için geçerli olan özellik alt kümesi kullanılabilir. MDN, tarayıcıların çoğunda yer tutucu metnin varsayılan olarak yarı saydam ya da açık gri göründüğünü belirtir ve iki erişilebilirlik riskine dikkat çeker: Yer tutucu rengi çok soluk olursa az gören kullanıcılar okuyamaz; çok koyu olursa kullanıcı onu girilmiş bir değer sanabilir. MDN ayrıca yer tutucunun <label> öğesinin yerini tutmadığını vurgular.
input::placeholder {
color: #6b6b6b;
font-style: italic;
}Yer tutucunun gösterilip gösterilmediğine göre alanın kendisine stil vermek istiyorsanız pseudo-element değil, :placeholder-shown pseudo-class'ı gerekir. Bu ikisi sık karıştırılır: ::placeholder metnin kendisini, :placeholder-shown ise metni gösteren alanı seçer.
::selection ve diğer vurgulama pseudo-element'leri
::selection, kullanıcının fareyle sürükleyerek ya da başka bir yolla vurguladığı metin parçasına stil verir. Kullanılabilen özellikler çok azdır: color, background-color, text-decoration ve ilgili özellikleri, text-shadow ve birkaç -webkit-text-stroke özelliği. MDN, background-image değerinin özellikle yok sayıldığını not eder. ::selection, MDN'nin "vurgulama pseudo-element'leri" adını verdiği bir gruba aittir ve bu grubun kendine özgü bir kalıtım modeli vardır; aynı grupta ::spelling-error, ::grammar-error, ::target-text ve ::highlight() gibi pseudo-element'ler de yer alır.
::selection {
color: white;
background-color: #1166ff;
}MDN bu konuda da erişilebilirlik uyarısı yapar: Seçili metin stillerini yalnızca estetik nedenlerle değiştirmeyin, çünkü kullanıcılar bunları kendi ihtiyaçlarına göre ayarlamış olabilir. Değiştirirseniz seçili metin ile seçim arka planı arasındaki kontrastın yeterli olduğundan emin olun; WCAG normal metin için 4.5:1, büyük metin için 3:1 oranını ister.
Erişilebilirlik: eklenen içerik DOM'da değildir
Pseudo-element'lerle ilgili en önemli uyarı içerikle ilgilidir. MDN'ye göre CSS ile oluşturulan içerik DOM'a dahil edilmez; bu yüzden erişilebilirlik ağacında temsil edilmez ve bazı yardımcı teknoloji ile tarayıcı birleşimleri onu seslendirmez. ::before ve ::after sayfalarında da bu yöntemle içerik eklemenin ekran okuyucular için güvenilir biçimde erişilebilir olmadığı, bu yüzden önerilmediği yazılıdır.
Pratikteki kural basittir: Sayfanın anlaşılması için gereken bilgiyi (bir fiyatı, bir uyarıyı, bir durumu) HTML'e yazın. Pseudo-element'leri süsleme, simge ve tipografik ayrıntılar için kullanın. Simge bir anlam taşıyorsa en azından content değerine eğik çizgiyle alternatif metin ekleyin ve bilginin CSS kapalıyken de erişilebilir olduğunu kontrol edin.
Uygulamalı mini örnek: bağlantı türüne göre simge
Bir makalede dış bağlantıların yanına küçük bir ok simgesi, PDF bağlantılarının yanına da dosya türünü gösteren bir etiket eklemek istediğinizi düşünün. Öznitelik seçicileri ve ::after ile bunu HTML'e dokunmadan yapabilirsiniz.
<p>
Ayrıntılar için <a href="https://developer.mozilla.org/">MDN</a> ve
<a href="rapor.pdf">yıllık rapor</a> sayfalarına bakın.
</p>a[href^="https://"]::after {
content: " ↗" / "dış bağlantı";
}
a[href$=".pdf"]::after {
content: " (PDF)";
font-size: 0.8em;
color: #6b6b6b;
}
/* sonuç: MDN bağlantısının sonunda ↗, rapor bağlantısının sonunda küçük gri (PDF) */Burada [href^="https://"] adresi https ile başlayan bağlantıları, [href$=".pdf"] ise .pdf ile biten bağlantıları seçer; bu öznitelik seçicilerinin ayrıntıları CSS seçiciler yazısında. Simgede eğik çizgiden sonraki alternatif metin, ekran okuyucusu destekleyen ortamlarda okunabilir. "(PDF)" etiketi ise bir süsleme değil, bağlantının ne açacağını anlatan bir bilgi olduğu için gerçek bir projede bu bilgiyi bağlantı metnine de yazmak daha doğrudur.
Sık yapılan hatalar

contentyazmayı unutmak:::beforeve::afteriçincontentyoksa hiçbir şey çizilmez. Yalnızca süsleme içincontent: ""yazın.- Görsel ya da form alanına
::aftervermek:<img>gibi değiştirilmiş öğelerde bu pseudo-element'ler oluşturulmaz. - Satır içi kutuya boyut vermek:
::beforevarsayılan olarak satır içidir;widthveheightiçindisplaydeğerini değiştirin. - Pseudo-element'i
:is()içine koymak: MDN'ye göre:is()pseudo-element'lerle eşleşmez;oge:is(::before, ::after)yerine iki seçiciyi virgülle yazın. - Pseudo-element'ten sonra seçici yazmak: Pseudo-element seçicinin sonunda olmalıdır.
::first-lineiçinde margin ya da text-indent kullanmak: Bu özellikler izin verilen listede yoktur ve uygulanmaz.- Önemli bilgiyi
contentile eklemek: Oluşturulan içerik DOM'da olmadığı için yardımcı teknolojilere ulaşmayabilir.
| Pseudo-element | Neyi seçer | Önemli kısıt |
|---|---|---|
| ::before / ::after | Öğenin ilk / son çocuğu olarak eklenen kutu | content gerekir, img üzerinde çalışmaz |
| ::first-line | Blok kapsayıcının ilk satırı | Yalnızca yazı tipi, arka plan, renk ve bazı metin özellikleri |
| ::first-letter | İlk satırın ilk harfi | float, margin, padding ve kenarlık da kullanılabilir |
| ::marker | Liste öğesinin işareti | Sınırlı özellik listesi |
| ::placeholder | Yer tutucu metin | ::first-line ile aynı özellik alt kümesi |
| ::selection | Kullanıcının seçtiği metin | Renk, arka plan rengi, metin süslemesi, gölge |
Sık Sorulan Sorular
:before ile ::before arasında fark var mı?
Davranış açısından yok. Tek iki noktalı yazım CSS2'den kalmadır ve tarayıcılar ilk dört pseudo-element için geriye dönük uyumluluk amacıyla bunu hâlâ kabul eder. Çift iki nokta, pseudo-element'leri pseudo-class'lardan ayırmak için getirilen güncel yazımdır; yeni kodda onu kullanın.
::after neden görünmüyor?
En sık üç neden vardır: content tanımlı değildir ya da none veya normal değerindedir; öğe <img> gibi değiştirilmiş bir öğedir; ya da pseudo-element satır içi olduğu ve içeriği boş olduğu için görünür bir boyutu yoktur. Boş içerikli süslemelerde display ile birlikte genişlik ve yükseklik verin.
::first-letter neden ilk harfi seçmiyor?
MDN üç koşul sayar. ::first-letter yalnızca blok kapsayıcılarda çalışır; satır içi bir span üzerinde etkisizdir. İlk harften önce görsel ya da satır içi tablo gibi başka bir içerik varsa eşleşme olmaz. Öğeye ::before ile içerik eklediyseniz ::first-letter o eklenen içeriğin ilk harfini seçer. Ayrıca ilk harfin hemen önündeki ya da arkasındaki noktalama işaretleri de eşleşmeye dahildir.
Liste madde imlerinin rengini nasıl değiştiririm?
li::marker { color: ...; } ile. ::marker renk ve yazı tipi özelliklerini ve content özelliğini destekler; böylece madde iminin rengini, boyutunu ya da karakterini liste metnini etkilemeden değiştirebilirsiniz.
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 pseudo-class: :hover, :focus, :nth-child() · CSS seçiciler · CSS :has(), :is(), :where(), :not() · CSS display değerleri · CSS view transitions · HTML entity ve özel karakterler