Görsel Algı ve Estetik

Pseudo-Sınıflar (Pseudo-Classes)

HTML elementlerinin "kim olduklarına" değil, "hangi durumda olduklarına" göre stil verilmesini sağlayan dinamik seçicilerdir.
Aşağıda pseudo-sınıfları inceleyeceğiz.

Ana Konu
Seviye 4

Pseudo-Sınıfların Ne İşe Yaradığı Durumlar, Etkileşimler ve Sanal Parçalar

"Görünmez Sınıf" Mantığı

Web geliştirme dünyasında standart bir CSS sınıfı (.class), bir öğeye geliştirici tarafından kalıcı olarak yapıştırılan bir etiket gibidir.

Ancak web, statik bir poster değildir; yaşayan, nefes alan ve sürekli değişen bir ortamdır.

Sözde Sınıflar, adından da anlaşılacağı gibi, tarayıcının belirli koşullar sağlandığında bir öğeye otomatik ve geçici olarak eklediği "hayalet sınıflardır".

Örneğin: Kullanıcı bir butona tıkladığı anda, tarayıcı o butona sanal bir "Tıklanıyor" etiketi yapıştırır ve tıklama bittiğinde bu etiketi söker alır.

Sizin JavaScript ile "Eğer tıklanırsa şu sınıfı ekle, bırakılırsa sil" demenize gerek kalmadan, bu işlemi CSS motoru milisaniyeler içinde halleder.

Neyi Hedeflerler? (Kapsam) Sözde sınıflar, bir öğenin sadece görünümünü değil, onun zaman içindeki yolculuğunu ve konumunu hedefler:

Söz Dizimi (Tek Nokta Kuralı) Bir seçicinin Sözde Sınıf olduğunu anlamanın en kolay yolu, başındaki tek iki nokta ( : ) işaretidir.

Bu, tarayıcıya "Ben bir elementin parçasını değil, onun durumunu değiştirmek istiyorum" mesajını verir.

Selector Kombinasyonu ve Zincirleme (Chaining)

Sözde sınıflar tek başına kullanılabildiği gibi, aynı seçici üzerinde birden fazla pseudo-class zincirlenerek (chaining) çok daha spesifik durumlar hedeflenebilir.

Örneğin: button:hover:active seçicisi, yalnızca hem üzerine gelinmiş hem de tıklanmakta olan butonları hedefler.

Bu yaklaşım, kullanıcı etkileşimlerini katmanlı durumlar olarak ele almayı sağlar ve UI davranışlarını çok daha hassas hale getirir.

Önemli Not: Zincirlenen pseudo-class'lar soldan sağa okunur ve her biri bir önceki koşulu daraltır.

Specificity (Özgüllük) Etkisi Sözde sınıflar, CSS specificity (özgüllük) hesaplamasında class seviyesinde değerlendirilir.

Bu şu anlama gelir: a:hover ile .btn aynı özgüllük seviyesindedir, ancak daha spesifik bir zincir (örn: .nav a:hover) diğerlerini geçersiz kılabilir.

Bu nedenle pseudo-class kullanırken, kuralların çakışmaması için seçici yapısının dikkatli kurulması gerekir.

:is(), :not() ve :where() ile Gelişmiş Seçim

Modern CSS ile birlikte gelen bazı pseudo-class'lar, seçici yazımını daha güçlü ve esnek hale getirir.

:is() → Birden fazla seçiciyi tek satırda gruplayarak tekrarları azaltır.

:not() → Belirli durumları hariç tutarak ters seçim yapmayı sağlar.

:where() → :is() gibi çalışır ancak specificity eklemez.

Özellikle büyük projelerde bu yapılar, CSS kodunun hem daha okunabilir hem de daha sürdürülebilir olmasını sağlar.

Pseudo-Class vs Pseudo-Element Ayrımı

Sözde sınıflar (:) ile sözde elementler (::) sıklıkla karıştırılır, ancak tamamen farklı kavramlardır.

Pseudo-class, bir öğenin durumunu hedeflerken; pseudo-element, o öğenin bir parçasını hedefler.

Örneğin: a:hover → linkin durumu p::first-line → paragrafın ilk satırı

Bu ayrım, doğru seçiciyi doğru problemde kullanmak için kritik öneme sahiptir.

Pseudo-Class Kategorileri Etkileşim, Durum ve Yapısal Seçicilerin Sınıflandırılması
Kategori
Açıklama
Etkileşim Anı

Fare üzerinde mi? Tıklanıyor mu? Odaklanıldı mı?

Tarihçe

Bu link daha önce ziyaret edildi mi?

Ağaç Yapısı

Bu öğe, ebeveyninin 3. çocuğu mu? Tek çocuğu mu?

Form Durumu

Onay kutusu işaretli mi? İnput alanı boş mu? Veri geçerli mi?

Şuana Kadar Ne Öğrendik?

Bu bölümde
  • Kategori tablosu
  • Seçici örnekleri (metin içi)
Öğrendiklerimiz
  • Kapsam: „Pseudo-Sınıfların Ne İşe Yaradığı” ana başlığı altındaki metin ve hemen üstteki kategori tablosu
  • Sözde sınıf mantığı ve : ile söz dizimi
  • Zincirleme (ör. button:hover:active) ve specificity (özgüllük)
  • :is(), :not(), :where() ile gelişmiş seçim
  • Sözde sınıf (:) ile sözde element (::) ayrımı
  • “Pseudo-Class Kategorileri” tablosu: etkileşim, tarihçe, ağaç yapısı, form durumu
Sırada Ne Var?
  • Sonraki bölüm: Dinamik Etkileşim Sınıfları — imleç, dokunuş, klavye ve bağlantı durumları
  • Anlık etkileşim: :hover, :active, :focus, :focus-visible, :focus-within
  • Bağlantılar ve gezinme: :visited, :link, :any-link (LVHA sırası)
  • Sayfa içi hedef: :target
  • Her alt konuda HTML + CSS kod editörü örnekleri; mobil hover, erişilebilirlik ve ziyaret geçmişi kısıtları gibi notlar
Seviye 4

Dinamik Etkileşim Sınıfları Kullanıcı Eylemlerine Yanıt Vermek

Giriş İçeriği

Dinamik etkileşim sınıfları, web tasarımında "statik görüntü" ile "işlevsel arayüz" arasındaki köprüdür.

Teknik olarak CSS içinde tanımlanan bu yapılar, bir HTML öğesinin sadece nasıl göründüğünü değil, kullanıcının o öğeyle nasıl bir ilişki kurduğunu belirler.

Web sitelerini sadece "okunan" bir dergi sayfasından, "kullanılan" bir araca dönüştüren temel mekanizma budur.

Arayüzün Vücut Dili

Gerçek hayattaki iletişimi düşünün: Birine seslendiğinizde size bakar, elini sıktığınızda karşılık verir.

Dijital dünyada ise bu tepkileri Pseudo-Classes sağlar.

Bu sınıflar, arayüze bir "vücut dili" kazandırır.

Kullanıcı bir eylemde bulunduğunda ( imleci hareket ettirdiğinde, tıkladığında veya klavyeye dokunduğunda ), arayüz bu eylemi algıladığını göstermek zorundadır.

Eğer arayüz tepki vermezse, kullanıcı sistemin donduğunu, bozuk olduğunu veya eyleminin geçersiz olduğunu düşünür.

Durum (State) Kavramı

Geleneksel grafik tasarımda ( poster, broşür ) bir görselin tek bir hali vardır.

Ancak web tasarımında her bir etkileşimli öğe (buton, link, input) birden fazla "duruma" sahiptir.

Bu sınıflar şu soruyu yanıtlar: "Bu öğe ŞU AN ne yapıyor?"

Beklemede mi? (Normal/Default)

İnceleniyor mu? (Hover)

Seçildi mi? (Focus)

İşlem mi görüyor? (Active)

Tasarımcı, öğenin her bir durumu için farklı görsel kurallar ( renk, boyut, gölge ) belirleyerek arayüzün akışkan olmasını sağlar.

Güven ve Kontrol Hissi

Kullanıcılar, kontrolün kendilerinde olduğunu hissetmek isterler.

Dinamik sınıflar, sağladıkları Görsel Geri Bildirim sayesinde bu güveni inşa eder.

Öngörülebilirlik Sağlar: Bir öğenin üzerine gelince renk değiştirmesi, kullanıcıya "Buna tıklarsan bir şeyler olacak" mesajını verir.

Hata Oranını Düşürür: Hangi kutucuğa yazı yazdığını (Focus) net gören kullanıcı, yanlış yere veri girmekten kurtulur.

Tatmin Duygusu Yaratır: Tıklama anındaki (Active) ufak bir hareketlenme, işlemin başarılı olduğuna dair bilinçaltına sinyal gönderir.

Mikro Etkileşimlerin Temeli

Modern web tasarımının en popüler konularından biri olan "Mikro Etkileşimler", tamamen bu sınıfların üzerine kuruludur.

Bir "Beğen" butonuna basıldığında kalbin büyümesi veya bir menünün üzerine gelindiğinde yavaşça açılması, bu sınıfların CSS animasyonları ile birleşmesiyle oluşur.

Bu detaylar, ürünü sadece "kullanılabilir" olmaktan çıkarıp "keyifli" hale getirir.

Keşif ve Niyet Aşaması :hover Pseudo-Sınıfı

Giriş İçeriği

Web arayüzlerinde kullanıcı ile sistem arasındaki flörtün başladığı yer burasıdır.

Kullanıcı, faresiyle bir öğenin üzerine geldiğinde aslında sisteme sessiz bir soru sorar: "Bu nedir ve bununla ne yapabilirim?"

Hover durumu, sistemin bu soruya verdiği nazik cevaptır.

Henüz bir karar verilmemiştir; sadece bir niyet veya merak söz konusudur.

Bu yüzden bu aşama, etkileşimin en "kırılgan" ama en "davetkar" anıdır.

Psikolojik Etkileşim: "Affordance" (İşlevsel Çağrışım)

Tasarım dünyasında "Affordance" denilen kavram, bir nesnenin şeklinin onun nasıl kullanılacağını belli etmesidir

(bir kapı kolunun şeklinin "beni aşağı bastır" demesi gibi).

Dijital dünyada ekran düzdür; bu yüzden derinlik ve işlevsellik hissini :hover yaratır.

Güvenli Bölge: Kullanıcılar genellikle tıklamadan önce farelerini sayfada gezdirerek içeriği tararlar.

Hover efektleri, kullanıcının yanlış bir şeye tıklama korkusunu azaltır.

"Merak etme, şu an sadece bakıyorsun, tıklarsan işlem yapacağım" mesajını verir.

Odak Yönetimi: Kalabalık bir sayfada kullanıcının gözü, farenin hareketiyle eşleşen görsel tepkileri takip eder.

Hover, kullanıcının dikkatini yönetmek için bir spot ışığı görevi görür.

Görsel Uygulama Stratejileri

Bir öğenin "hover" durumuna geçtiğini göstermek için kullanılan yöntemler, markanın karakterine göre değişse de temel amaç "farklılaşmaktır".

Renk Manipülasyonu: En yaygın yöntemdir.

Butonun mevcut renginin "parlaklık" değeriyle oynanır.

Rengi hafifçe açmak ( aydınlatmak ) genellikle "yaklaşma/yükselme" hissi verirken, koyulaştırmak "ciddiyet/hazırlık" hissi verir.

Derinlik ve Yükselme (Elevation): Material Design felsefesinde sıkça görülür.

Öğenin üzerine gelindiğinde gölgesi (shadow) büyür ve dağılır.

Bu, öğenin ekrandan kullanıcıya doğru fiziksel olarak yükseldiği illüzyonunu yaratır.

"Bana daha yakınsın, bana dokunabilirsin" demektir.

Hareket (Translation): Öğe, olduğu yerden 2-3 piksel yukarı kayabilir.

Bu basit hareket, arayüzü canlandırır ve statiklikten kurtarır.

İmleç Değişimi: Görsel bir stil olmasa da, fare imlecinin standart ok şeklinden "işaret parmağı" ( pointer ) şekline dönüşmesi, hover deneyiminin ayrılmaz bir parçasıdır.

Mobil Cihaz Paradoksu (Hover Tuzağı)

Web tasarımcılarının en sık düştüğü tuzaklardan biri, masaüstü deneyimine odaklanıp mobil gerçeğini unutmaktır.

Dokunmatik Ekran Doğası: Telefonlarda "parmağı havada gezdirme" diye bir eylem yoktur.

Ekrana dokunduğunuz an, teknik olarak "tıklama" gerçekleşir.

Bu yüzden hover efektleri mobilde ya hiç görünmez ya da tıklama anında bir anlığına yanıp söner.

"Sticky Hover" Sorunu: Bazı mobil tarayıcılarda, bir butona dokunduğunuzda o butonun hover stili ( arka plan rengi gibi ) "takılı" kalır.

Başka bir yere dokunana kadar o renk gitmez.

Bu, kullanıcıda "Acaba butona basılı mı kaldı?" kafa karışıklığına yol açar.

Kritik İçerik Uyarısı: Eğer bir web sitesinde "Hakkımızda" menüsünün alt seçenekleri sadece fare üzerine gelince açılıyorsa, mobil kullanıcılar bu alt menülere asla ulaşamaz.

Bu nedenle, hover sadece "görsel bir süsleme" veya "ekstra ipucu" olarak kalmalı, temel navigasyonun tek anahtarı olmamalıdır.

Tasarım İpucu: Geçiş Yumuşaklığı (Transition)

İyi bir hover efekti "pat" diye belirmez.

Renk değişiminin veya hareketin 0.2 veya 0.3 saniyelik bir sürede, yumuşakça gerçekleşmesi gerekir.

Bu, arayüzün daha modern ve profesyonel algılanmasını sağlar.

Aniden değişen renkler gözü yorar ve dijital bir hata gibi hissettirebilir.

</>
Etkileşim Tabanlı Sözde Sınıflar :hover Basit Örnek (+)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Hover Pseudo Sınıf Örnek</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>

    <div class="container">
        <h2>Hover Etkileşimi</h2>
        <button class="btn-hover">Üzerime Gel</button>
    </div>

</body>

</html>

body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background: #ececec;
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    margin: 0;
}

.container {
    background: linear-gradient(145deg, #ffffff, #dcdcdc);
    padding: 40px;
    border-radius: 14px;
    width: 300px;
    text-align: center;
    border: 2px solid rgba(0, 0, 0, 0.1);
    box-shadow:
        inset 0 1px 4px rgba(255, 255, 255, 0.7),
        0 6px 18px rgba(0, 0, 0, 0.2);
}

h2 {
    font-size: 22px;
    margin-bottom: 20px;
    color: #333;
    text-transform: uppercase;
    font-weight: 600;
}

.btn-hover {
    padding: 14px 30px;
    background: linear-gradient(135deg, #6a5af9, #4d3be6);
    color: white;
    border: 1px solid rgba(0, 0, 0, 0.15);
    border-radius: 8px;
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
    transition: 0.25s
}

.btn-hover:hover {
    background: linear-gradient(135deg, #7e6cfb, #5949f2);
    transform: translateY(-2px) scale(1.05);
}
                            

Eylem ve Dokunsal Geri Bildirim :active Pseudo-Sınıfı

Giriş İçeriği

Bu durum, dijital etkileşimin "gerçekleşme" anıdır.

Kullanıcının niyeti ( hover ) ve odaklanması ( focus ) artık eyleme dönüşmüştür.

Teknik olarak farenin sol tuşuna basıldığı o milisaniyelik zaman dilimini kapsar, ancak yarattığı his tüm deneyimi mühürler.

Eğer :hover bir davetiyeyse, :active el sıkışmadır.

Dijital Dünyada Fiziksel His (Tactile Feedback)

İnsan beyni, fiziksel dünyadaki etki-tepki prensiplerine göre evrimleşmiştir.

Bir kapı kolunu bastırdığınızda direnç hissedersiniz, bir piyano tuşuna bastırdığınızda tuş aşağı iner.

Ancak dokunmatik ekranlar ve fareler düz cam yüzeylerdir; fiziksel bir geri bildirim vermezler.

İşte :active durumu, bu eksikliği görsel bir illüzyonla tamamlar.

Skeuomorphism Mirası: Eski arayüz tasarımlarında butonlar gerçek hayattaki gibi 3 boyutlu ve kabarık çizilirdi.

Günümüzün "Flat" ( Düz ) tasarım dünyasında bile bu hisse ihtiyacımız var.

:active durumu, butonu bir anlığına ezilmiş veya içeri göçmüş gibi göstererek beynimize "Evet, fiziksel bir temas gerçekleşti" sinyalini gönderir.

Canlılık Hissi: Tepki vermeyen bir buton, kullanıcıya "donmuş" veya "bozuk" bir sistem hissi verir.

Tepki veren buton ise arayüzün canlı olduğunu, dinlediğini ve işlediğini hissettirir.

"Öfke Tıklaması"nı (Rage Clicking) Önlemek

Hiç bir butona bastığınızda çalışmadığını sanıp, sinirle arka arkaya 5-6 kere tıkladığınız oldu mu?

UX dünyasında buna "Rage Clicking" denir.

Belirsizliğin Giderilmesi: Kullanıcı tıkladığı anda ekranda hiçbir görsel değişiklik olmazsa ( buton rengi değişmezse veya kımıldamazsa ), kullanıcı sistemin komutu algılamadığını düşünür.

Bu şüphe, kullanıcının defalarca tıklamasına neden olur.

Sonuçları: Bu durum e-ticaret sitelerinde aynı ürünü yanlışlıkla iki kez satın almaya, formlarda aynı verinin mükerrer gönderilmesine veya sunucuların gereksiz yere yorulmasına yol açabilir.

:active efekti, "Tamam, sakin ol, tıkladığını duydum" diyen görsel bir onaylamadır.

Uygulama Teknikleri: Nasıl Hissettirmeli?

Bu aşamadaki tasarımın sırrı "incelik"tir.

Çok büyük değişimler gözü yorar, çok küçük değişimler fark edilmez.

Basınç İllüzyonu (Scale): En popüler modern yöntemdir.

Buton tıklandığı an %95 veya %98 oranında küçültülür ( transform: scale(0.98) ).

Bu, butona parmağınızla bastırıp onu sıkıştırmışsınız hissi yaratır.

Derinlik Hareketi (Translation): Eğer butonun altında bir gölge varsa, tıklama anında gölge kaldırılır ve buton 2-3 piksel aşağı kaydırılır

(transform: translateY).

Bu, butonun yüzeye gömüldüğü hissini verir.

Ripple (Dalga) Efekti: Özellikle Android ekosisteminde görülen, tıklanan noktadan dışarıya doğru yayılan su dalgası benzeri efekttir.

Dokunulan noktanın tam koordinatını vurguladığı için en tatmin edici geri bildirimlerden biridir.

Linkler İçin Bir Not Genellikle butonlardan bahsedilse de metin linkleri de bu durumdan nasibini almalıdır.

Tıklanan bir linkin renginin bir anlığına kırmızıya veya daha koyu bir tona dönmesi, özellikle mobil cihazlarda parmağın doğru kelimeye dokunup dokunmadığını teyit eder.

</>
Etkileşim Tabanlı Sözde Sınıflar :active Basit Örnek (+)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Active PSeudo Örneği</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>
    <div class="container">
        <h3>Active Pseudo</h3>
        <button class="btn-active">Bana Tıkla</button>
    </div>
</body>

</html>
body {
    font-family: 'Segoe UI', sans-serif;
    background: linear-gradient(160deg, #e6e9f0, #eef1f5);
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    margin: 0;
}

.container {
    background: rgba(255, 255, 255, 0.35);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    padding: 40px;
    border-radius: 18px;
    width: 300px;
    text-align: center;
    border: 2px solid rgba(255, 255, 255, 0.4);
    box-shadow:
        0 8px 25px rgba(0, 0, 0, 0.12),
        inset 0 1px 3px rgba(255, 255, 255, .5);
}

.container h3 {
    text-align: center;
    font-weight: 600;
    letter-spacing: 1px;
    margin-bottom: 20px;
    color: #2b2b2b;
    text-transform: uppercase;
}

.btn-active {
    position: relative;
    padding: 16px 35px;
    background: linear-gradient(135deg, #4b9bff, #1e6bff);
    color: white;
    border: none;
    border-radius: 10px;
    font-size: 17px;
    font-weight: 600;
    cursor: pointer;
    transition: .25s ease;
    letter-spacing: 0.6px;
    box-shadow:
        0 6px 18px rgba(50, 120, 255, 0.35),
        inset 0 1px 4px rgba(255, 255, 255, 0.4);
}

.btn-active:hover {
    background: linear-gradient(135deg, #5ca8ff, #2b7dff);
    transform: translateY(-5px) scale(1.06);
    box-shadow:
        0 14px 32px rgba(30, 80, 255, 0.4),
        inset 0 2px 8px rgba(255, 255, 255, 0.25);
}

.btn-active:active {
    transform: scale(0.95) translateY(2px);
    background: linear-gradient(135deg, #2d6cff, #184fde);
    box-shadow:
        inset 0 5px 15px rgba(0, 0, 0, 0.25),
        0 4px 8px rgba(0, 0, 0, 0.1);
}

Keşif ve Niyet Aşaması :focus Pseudo-Sınıfı

Giriş İçeriği

Bir web sayfasında gezinmek, karanlık bir odada el feneriyle yolunu bulmaya benzer.

Fare kullananlar için imleç o fenerdir; nereye bakarlarsa orayı görürler.

Ancak klavye kullananlar için o "fenerin ışığı" :focus durumudur.

Bu durum, kullanıcının o an sayfanın tam olarak neresinde olduğunu, hangi öğeyle etkileşime girmek üzere olduğunu gösteren dijital bir pusuladır.

Klavye Navigasyonu ve "Sıralı Erişim"

Web kullanıcılarının önemli bir kısmı fare kullanmaz veya kullanamaz.

Motor becerileri kısıtlı bireyler, güç kullanıcıları veya sadece formu hızlı doldurmak isteyenler, sayfada gezinmek için TAB tuşunu kullanır.

Dijital Seksek: TAB tuşuna her basıldığında, odaklanma durumu yapısındaki sıraya göre bir sonraki etkileşimli öğeye (link , input , buton) atlar.

Görsel Takip: Eğer :focus stili tanımlanmazsa, kullanıcı TAB tuşuna basar ama ekranda hiçbir değişiklik görmez.

Hangi linkte olduğunu, hangi butona basmak üzere olduğunu bilemez.

Bu, "gözleri bağlıyken araba kullanmaya çalışmak" gibidir.

Erişilebilirlik (Accessibility) Günahı: "Outline: None"

Web tasarımcılarının estetik kaygılarla yaptığı en büyük hatalardan biri, tarayıcının varsayılan odaklanma çerçevesini

(o mavi veya siyah çizgiyi) outline: none koduyla silmektir.

Görünmezlik Sorunu: Bu kodu yazdığınız an, klavye kullanan ziyaretçiyi sayfanızda kör etmiş olursunuz.

Ziyaretçi sayfadadır, tuşlara basar ama nerede olduğunu asla göremez.

WCAG Standartları: Web İçeriği Erişilebilirlik Yönergeleri'ne göre, odaklanan öğenin görsel olarak belirgin olması bir tercih değil, bir zorunluluktur.

Bu kurala uymamak, "fiziksel bir mağazaya tekerlekli sandalye rampası koymamakla eşdeğerdir"; belirli bir kullanıcı grubunu içeri almamak demektir.

Akıllı Tasarım Yaklaşımı

Tarayıcıların varsayılan odaklanma stilleri (genellikle tırtıklı veya kalın mavi çizgiler) bazen modern tasarımlarla uyumsuz görünebilir.

Doğru yaklaşım bu stili tamamen kaldırmak değil, markaya uygun şekilde yeniden tasarlamaktır.

Alternatif Çözümler: Varsayılan çerçeve yerine; butonun etrafında markanın ana renginde yumuşak bir parlama (glow effect), kalın ve zıt renkli bir kenarlık (border) veya arka plan renginde dramatik bir değişim kullanılabilir.

Çift Katmanlı Görünüm: Bazı gelişmiş tasarımlarda, hem renk değişimi hem de öğenin boyutunun büyümesi birleştirilerek odaklanma anı kaçırılmayacak kadar net hale getirilir.

Input (Giriş) Alanları: Bir form doldururken metin kutusuna tıklandığında beliren o renkli çerçeve, kullanıcıya "Klavye şu an buraya yazacak" mesajını verir.

Bu, kullanıcının yanlışlıkla boşluğa yazı yazmasını engeller ve odaklanmayı kolaylaştırır.

Mobil Deneyimdeki Yeri

Focus durumu genellikle masaüstü/klavye ile ilişkilendirilse de mobil formlarda da kritiktir.

Telefondan bir formu doldururken "İleri" tuşuna bastığınızda ekranın otomatik olarak bir sonraki kutucuğa kayması ve o kutucuğun parlaması, :focus mekanizmasının bir sonucudur.

Bu akışkanlık, mobil form doldurma çilesini azaltır.

</>
Etkileşim Tabanlı Sözde Sınıflar :focus Basit Örnek (+)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Active PSeudo Örneği</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>
    <div class="container">
        <h3>Focus Pseudo Örnek</h3>
        <button class="btn-focus">Odaklan</button>
    </div>

</body>

</html>
body {
    font-family: 'Segoe UI', sans-serif;
    background: linear-gradient(160deg, #e6e9f0, #eef1f5);
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    margin: 0;
}

.container {
    background: rgba(255, 255, 255, 0.35);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    padding: 40px;
    border-radius: 18px;
    width: 400px;
    text-align: center;
    border: 2px solid rgba(255, 255, 255, 0.4);
    box-shadow:
        0 8px 25px rgba(0, 0, 0, 0.12),
        inset 0 1px 3px rgba(255, 255, 255, .5);
}

h3 {
    text-align: center;
    font-weight: 600;
    letter-spacing: 1px;
    margin-bottom: 20px;
    color: #2b2b2b;
    text-transform: uppercase;
}

.btn-focus {
    padding: 14px 28px;
    background: #4a6cff;
    color: white;
    border: none;
    border-radius: 8px;
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
    transition: 0.25s;
    outline: none;
}

.btn-focus:hover {
    background: #5c7cff;
}

.btn-focus:focus {
    box-shadow: 0 0 0 4px rgba(76, 104, 255, 0.35);
    transform: translateY(-3px);
}

Akıllı Odaklanma ve Erişilebilirlik :focus-visible

Büyük Problem: "Mavi Çerçeve" Krizi

Bir öğe odaklandığında stili uygular, ancak yalnızca tarayıcının o odağın kullanıcıya görünür olması gerektiğine karar verdiği durumlarda devreye girer.

Bu seçici, modern web tasarımının en büyük ikilemlerinden biri olan "Estetik mi, Erişilebilirlik mi?" sorusuna verilen en zekice cevaptır.

Standart :focus sınıfı, bir butona tıklandığında da, klavyeyle (Tab tuşu) üzerine gelindiğinde de çalışır.

Fare kullanan bir ziyaretçi, şık bir butona tıkladığında etrafında beliren o kalın mavi/siyah çerçeveyi (outline) görmek istemez; bu, tasarımcılar için görsel bir kusurdur.

Bu yüzden tasarımcılar yıllarca outline: none yazarak bu çerçeveyi tamamen kapattılar. Ancak bu durum, klavye kullanan engelli bireylerin sayfada kaybolmasına neden oldu.

Çözüm: Tarayıcının Zekası (Heuristics) :focus-visible, bu iki durumu birbirinden ayırır.

Eğer kullanıcı fare ile tıklıyorsa, tarayıcı "Bu kullanıcının gözü zaten imleçte, ekstra bir çerçeveye ihtiyacı yok" der ve stili uygulamaz.

Ancak kullanıcı klavye ile geziyorsa, tarayıcı "Bu kullanıcının nerede olduğunu görmeye ihtiyacı var" der ve odak çerçevesini gösterir.

</>
Etkileşim Tabanlı Sözde Sınıflar :focus-visible Örnek 1 (+)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Focus-visible Pseudo Örneği</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>
    <div class="focus-panel">
        <input type="text" placeholder="Adınızı yazın">
        <button>Gönder</button>
    </div>

</body>

</html>
body {
    font-family: 'Segoe UI', sans-serif;
    background: #eef1f6;
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
    margin: 0;
}

.focus-panel {
    background: #fff;
    padding: 30px;
    border-radius: 16px;
    box-shadow:
        0 6px 18px rgba(0, 0, 0, 0.1),
        inset 0 1px 3px rgba(255, 255, 255, 0.6);
    border: 2px solid rgba(0, 0, 0, 0.07);
    max-width: 350px;
    width: 100%;
    text-align: center;
}

input,
button {
    width: 100%;
    padding: 14px;
    font-size: 16px;
    margin: 12px 0;
    border-radius: 10px;
    border: 1px solid #ccc;
    transition: .25s;
    outline: none;
    box-sizing: border-box;
}

input:focus,
button:focus {
    border-color: #4c8dff;
}

input:focus-visible,
button:focus-visible {
    box-shadow: 0 0 0 4px rgba(77, 130, 255, 0.35);
    transform: translateY(-2px);
    border-color: #4c8dff;
}

button:hover {
    cursor: pointer;
    background: #4c8dff;
    color: white;
}
</>
Etkileşim Tabanlı Sözde Sınıflar :focus-visible Örnek 2 (+)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Focus-Visible Örneği 2</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>
    <div class="focus-visible-demo">
        <h3>Focus vs Focus-Visible Karşılaştırması</h3>

        <div class="demo-buttons">
            <button class="btn btn-focus">
                :focus (Fare + Klavye)
            </button>
            <button class="btn btn-focus-visible">
                :focus-visible (Sadece Klavye)
            </button>
        </div>

        <div class="explanation">
            <p><strong>Nasıl test edilir:</strong></p>
            <p>• Fareyle tıklayın - sadece :focus çalışır</p>
            <p>• Tab tuşuyla gezin - her ikisi de çalışır</p>

            <div class="key-instruction">
                ↹ Tab tuşuyla butonlar arasında gezin!
            </div>
        </div>
    </div>

</body>

</html>
body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background: #f8f9fa;
    margin: 0;
    padding: 20px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 20px;
}

.focus-visible-demo {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    padding: 30px;
    border-radius: 12px;
    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
    text-align: center;
    max-width: 500px;
    width: 100%;
}

.focus-visible-demo h3 {
    color: white;
    margin-bottom: 25px;
}

.demo-buttons {
    display: flex;
    gap: 15px;
    justify-content: center;
    flex-wrap: wrap;
}

.btn {
    padding: 12px 20px;
    background: #fff;
    border: none;
    border-radius: 8px;
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.3s ease;
}

.btn-focus:focus {
    outline: 3px solid #ff3838;
    background: #ffcccc;
}

.btn-focus-visible:focus-visible {
    outline: 3px solid #17c0eb;
    background: #c7ecee;
    transform: scale(1.05);
}

.explanation {
    background: rgba(255, 255, 255, 0.1);
    padding: 15px;
    border-radius: 8px;
    margin-top: 20px;
    color: white;
}

.explanation p {
    margin: 5px 0;
    font-size: 14px;
}

.key-instruction {
    background: #ffeaa7;
    color: #2d3436;
    padding: 8px 12px;
    border-radius: 6px;
    font-weight: bold;
    margin-top: 10px;
    display: inline-block;
}

Hafıza ve Yön Bulma :visited Pseudo-Sınıfı

Giriş İçeriği

Bu durum, web sitesinin kullanıcının kişisel tarihçesine saygı duyduğu ve ona rehberlik ettiği alandır.

Teknik olarak, tarayıcının geçmişinde kayıtlı olan bir URL ile sayfadaki bir link eşleştiğinde devreye girer.

İnternet devasa bir ormandır ve :visited durumu, Hansel ve Gretel masalındaki gibi, kullanıcının geçtiği yollara bıraktığı

"ekmek kırıntılarıdır".

Bilişsel Yükü Azaltmak (Cognitive Load)

Kullanıcılar yoğun içerikli sitelerde ( haber portalları , forumlar , arama motorları ) gezinirken sürekli kararlar verirler:

"Bunu okumalı mıyım?", "Şuna bakmış mıydım?"

Harici Hafıza: İnsan beyni kısa süreli hafızada sınırlı bilgi tutabilir.

:visited durumu, bu hafıza yükünü kullanıcının zihninden alıp arayüze yükler.

Kullanıcı, linkin rengine bakarak saniyeden daha kısa sürede "Ben burayı zaten gördüm, tekrar tıklamama gerek yok" kararını verir.

Verimlilik: Özellikle Google arama sonuçlarını düşünün.

Eğer tıkladığınız sonuçların rengi değişmeseydi, aynı sayfaya defalarca girip çıkarak zaman kaybederdiniz.

Bu renk değişimi, kullanıcının yeni ve keşfedilmemiş içeriğe odaklanmasını sağlar.

Renk Kodları ve Tasarım Standartları

Web'in ilk günlerinden beri kabul görmüş, yazılı olmayan bir kural vardır: Mavi henüz gidilmemiş yerleri, Mor ise gidilmiş yerleri temsil eder.

Neden Soluk Renkler?: Modern tasarımda illa mor kullanmak zorunda değilsiniz.

Ancak temel prensip şudur: Ziyaret edilmiş linkler, ziyaret edilmemiş olanlara göre daha az dikkat çekici ( daha soluk , daha gri , daha koyu) olmalıdır.

Görsel Hiyerarşi: Canlı renkler "Beni Tıkla!" diye bağırırken, visited rengi "Ben artık pasifim, sıradakine geç" diyerek görsel gürültüyü azaltır.

Gizlilik ve "History Sniffing" Kısıtlaması

Bu durumu diğerlerinden (hover, focus, active) ayıran çok önemli bir teknik ve güvenlik detayı vardır.

Güvenlik Duvarı: Geçmişte kötü niyetli siteler, kullanıcının tarayıcı geçmişini okumak için bu özelliği kötüye kullanabiliyordu

Örneğin: Banka sitesinin linkini sayfaya gizleyip renginin değişip değişmediğini kontrol ederek kullanıcının o bankayı kullanıp kullanmadığını anlamak gibi

CSS Kısıtlamaları:

Bu "History Sniffing" açığını kapatmak için modern tarayıcılar :visited durumunda yapılabilecek stil değişikliklerini ciddi şekilde kısıtlamıştır.

:visited ile bir linkin boyutunu büyütemez, yazı tipini değiştiremez veya onu hareket ettiremezsiniz.

Sadece rengini değiştirebilirsiniz.

Bu, kullanıcının gizliliğini korumak için alınmış global bir önlemdir.

Nerede Kullanılmalı?

Her linkte :visited kullanmak zorunda değilsiniz.

Örneğin, ana menüdeki "Ana Sayfa" veya "İletişim" butonlarının renginin değişmesi anlamsız olabilir.

Ancak; Blog listeleri, Dokümantasyon sayfaları, Arama sonuçları, Sıkça Sorulan Sorular (SSS) gibi "tüketilen" içeriklerin listelendiği alanlarda bu durumu kullanmak, iyi bir kullanıcı deneyimi için şarttır.

</>
Etkileşim Tabanlı Sözde Sınıflar :visited Örnek 1 (+)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Visited Pseudo Örneği 1</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>
    <div class="visited-box">
        <a href="https://google.com" target="_blank" class="link-card">
            Google'a Git
        </a>
    </div>

</body>

</html>
body {
    font-family: 'Segoe UI', sans-serif;
    background: #f1f2f6;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
}

.visited-box {
    background: #ffffff;
    padding: 30px;
    border-radius: 16px;
    width: 250px;
    text-align: center;
    box-shadow:
        0 6px 18px rgba(0, 0, 0, 0.1),
        inset 0 1px 3px rgba(255, 255, 255, 0.6);
    border: 2px solid rgba(0, 0, 0, 0.06);
}

.link-card {
    text-decoration: none;
    background: #4c8dff;
    color: #fff;
    padding: 14px 20px;
    border-radius: 10px;
    display: inline-block;
    font-size: 17px;
    transition: .25s;
}

.link-card:hover {
    background: #5d9bff;
    transform: translateY(-3px);
    box-shadow: 0 8px 18px rgba(76, 141, 255, 0.35);
}

.link-card:visited {
    background: #8c00ff;
    box-shadow: none;
    transform: scale(0.98);
}
</>
Etkileşim Tabanlı Sözde Sınıflar :visited Örnek 2 (+)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Visited Pseudo Örneği 2</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>
    <div class="article-card">
        <a href="https://example.com" target="_blank" class="article-link">
            Modern CSS ile UI Tasarımı
        </a>

        <p class="sub-text">
            Bu yazıda modern UI teknikleri, shadow derinliği, gradient ipuçları ve tasarımsal davranışları öğreniyoruz.
        </p>
    </div>
</body>

</html>
body {
    font-family: 'Segoe UI', sans-serif;
    background: #f0f2f5;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
}

.article-card {
    background: #ffffff;
    padding: 24px;
    border-radius: 16px;
    max-width: 400px;
    box-shadow:
        0 6px 18px rgba(0, 0, 0, 0.1),
        inset 0 1px 4px rgba(255, 255, 255, 0.6);
    border: 2px solid rgba(0, 0, 0, 0.06);
}

.article-link {
    display: block;
    font-size: 19px;
    font-weight: 600;
    color: #2c59ff;
    text-decoration: none;
    margin-bottom: 8px;
    transition: .25s;
}

.article-link:hover {
    color: #4a76ff;
    text-shadow: 0 2px 6px rgba(76, 118, 255, 0.25);
}

.article-link:visited {
    color: #566172;
    text-decoration: underline dashed #a0aec0;
}

.sub-text {
    font-size: 14px;
    color: #6b6b6b;
    line-height: 1.5;
}

Ebeveynin Farkındalığı :focus-within

Kullanım Senaryosu: Gelişmiş Form Grupları

Sadece öğe odaklandığında değil, aynı zamanda öğenin içindeki herhangi bir alt öğe odaklandığında da tetiklenen çok güçlü bir seçicidir.

Bu seçici, CSS'e "Baloncuk Mantığı" ( Event Bubbling ) benzeri bir yetenek kazandırır: Çocuktan ebeveyne doğru stil akışı sağlar.

Modern tasarımlarda genellikle bir input ve onun icon'u aynı kapsayıcı içinde bulunur.

Kullanıcı input'a tıkladığında, sadece input'un değil, onu kapsayan tüm kutunun parlamasını veya renk değiştirmesini istersiniz.

Eskiden bunu yapmak için JavaScript gerekirdi. Şimdi .form-group:focus-within diyerek, "İçindeki input'a tıklanınca .form-group'un kenarlığını mavi yap" diyebilirsiniz.

Dropdown Menülerde Kalıcılık Açılır menülerde (Dropdown) yaşanan en büyük sorun, klavye ile menü linkleri arasında gezerken ana menünün kapanmasıdır.

:focus-within sayesinde, odak alt linklerde olduğu sürece, ana menü kapsayıcısı "Benim içimde hala birileri var" diyerek menüyü açık tutmaya devam eder.

Mantıksal Çeviri: :focus yapısı: "Bana bakıyorlar." / :focus-within "Bana VEYA ailemden birine bakıyorlar."

</>
Etkileşim Tabanlı Sözde Sınıflar :focus-within Örnek 1 (+)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>:focus-within Örneği</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>

    <h2>:focus-within Örneği</h2>
    <div class="search-box">
        <label>Arama Yap:</label>
        <input type="text" placeholder="Bir şey yaz...">
    </div>

</body>

</html>
body {
    font-family: Arial, Helvetica, sans-serif;
    padding: 20px;
}

h2 {
    font-size: 20px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 1px;
    color: #333;
    margin-bottom: 15px;
}

.search-box {
    width: 250px;
    padding: 15px;
    border: 2px solid #ccc;
    border-radius: 6px;
    transition: .3s;
}

.search-box label {
    font-size: 14px;
    font-weight: bold;
    color: #333;
    display: block;
    margin-bottom: 6px;
    letter-spacing: 0.5px;
}

.search-box input {
    width: 100%;
    padding: 10px;
    border: 2px solid #ccc;
    border-radius: 4px;
    outline: none;
    transition: .3s;
    box-sizing: border-box;
    font-size: 14px;
}

.search-box:focus-within {
    border-color: #007bff;
    background-color: #eef5ff;
}

.search-box input:focus {
    border-color: #007bff;
    background-color: #fff;
}
</>
Etkileşim Tabanlı Sözde Sınıflar :focus-within Örnek 2 (+)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Focus-Within Örneği</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>
    <div class="focus-within-demo">
        <h3>Focus-Within Efekti</h3>

        <div class="form-group">
            <label for="name">Adınız:</label>
            <input type="text" id="name" class="form-input" placeholder="Adınızı yazın...">
        </div>

        <div class="form-group">
            <label for="email">E-posta:</label>
            <input type="email" id="email" class="form-input" placeholder="E-posta adresiniz...">
        </div>

        <div class="form-group">
            <label for="message">Mesajınız:</label>
            <textarea id="message" class="form-input" placeholder="Mesajınızı yazın..." rows="4"></textarea>
        </div>

        <button class="submit-btn">Gönder</button>

        <div class="info-box">
            <p><strong>Nasıl çalışır:</strong></p>
            <p>• Form alanlarından <span class="highlight">herhangi birine</span> tıkla</p>
            <p>• <span class="highlight">Tüm container</span> yeşil renge dönüşür</p>
            <p>• Container içindeki herhangi bir öğe focus olduğunda çalışır</p>
        </div>
    </div>

</body>

</html>
body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background: #f8f9fa;
    margin: 0;
    padding: 20px;
}

.focus-within-demo {
    background: linear-gradient(135deg, #a29bfe 0%, #6c5ce7 100%);
    padding: 30px;
    border-radius: 12px;
    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
    max-width: 500px;
    margin: 20px auto;
    transition: all 0.3s ease;
}

.focus-within-demo:focus-within {
    background: linear-gradient(135deg, #00b894 0%, #55efc4 100%);
    transform: scale(1.02);
    box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
}

.focus-within-demo h3 {
    color: white;
    text-align: center;
    margin-bottom: 25px;
}

.form-group {
    margin-bottom: 20px;
}

.form-group label {
    display: block;
    color: white;
    margin-bottom: 8px;
    font-weight: 500;
}

.form-input {
    width: 100%;
    padding: 12px 16px;
    border: 2px solid rgba(255, 255, 255, 0.3);
    border-radius: 8px;
    font-size: 16px;
    background: rgba(255, 255, 255, 0.9);
    transition: all 0.3s ease;
    box-sizing: border-box;
}

.form-input:focus {
    outline: none;
    border-color: #0984e3;
    background: white;
}

.submit-btn {
    width: 100%;
    padding: 14px;
    background: #ffeaa7;
    color: #2d3436;
    border: none;
    border-radius: 8px;
    font-size: 16px;
    font-weight: bold;
    cursor: pointer;
    transition: all 0.3s ease;
}

.submit-btn:hover {
    background: #fdcb6e;
    transform: translateY(-2px);
}

.info-box {
    background: rgba(255, 255, 255, 0.1);
    padding: 15px;
    border-radius: 8px;
    margin-top: 20px;
    color: white;
}

.info-box p {
    margin: 5px 0;
    font-size: 14px;
}

.highlight {
    background: #ffeaa7;
    color: #2d3436;
    padding: 4px 8px;
    border-radius: 4px;
    font-weight: bold;
}

Sayfa İçi Hedefleme ve Vurgu :target

Kullanıcıyı Kaybolmaktan Kurtarmak

URL'deki fragment tanımlayıcısı ( #bolum-adi ) ile eşleşen HTML öğesine stil uygular.

Kullanıcı bir bağlantıya tıkladığında ve sayfa belirli bir bölüme kaydığında, o bölümün "hedef" olduğunu görsel olarak belirtmek için kullanılır.

Uzun bir makalede "Yorumlar" linkine tıkladığınızı düşünün.

Sayfa aşağı kayar ama hangi yorumun hedeflendiğini anlamak zor olabilir.

:target sayesinde, gidilen bölümün arka planını geçici olarak sarı yaparak ( highlight) "Aradığın şey tam olarak burası" mesajını verebilirsiniz.

CSS ile JavaScript'siz Modal (Pencere) Bu seçici, sadece vurgulama için değil, işlevsellik için de kullanılır.

Gizli bir modal penceresini (display: none), URL'deki ID ile eşleştiğinde (#modal:target { display: block; }) görünür yaparak, hiç JavaScript yazmadan çalışan açılır pencereler yapabilirsiniz.

</>
Form Doğrulama Sözde Sınıflar :target Pseudo Sınıf Örnek (+)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Target Pseudo Sınıf Örneği</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>
    <h2>:target Örneği</h2>

    <nav class="menu">
        <a href="#box1">Kutu 1</a>
        <a href="#box2">Kutu 2</a>
        <a href="#box3">Kutu 3</a>
    </nav>

    <div class="content">
        <div id="box1" class="panel">Bu Box 1 içeriğidir</div>
        <div id="box2" class="panel">Bu Box 2 içeriğidir</div>
        <div id="box3" class="panel">Bu Box 3 içeriğidir</div>
    </div>

</body>

</html>

                            
body {
    font-family: Arial, Helvetica, sans-serif;
    padding: 20px;
}

h2 {
    text-transform: uppercase;
    margin-bottom: 15px;
}

.menu {
    display: flex;
    gap: 10px;
    margin-bottom: 20px;
}

.menu a {
    text-decoration: none;
    padding: 8px 14px;
    background: #ddd;
    color: #333;
    border-radius: 6px;
    font-weight: 600;
    transition: .3s;
}

.menu a:hover {
    background: #bbb;
}

.panel {
    padding: 20px;
    border: 2px solid transparent;
    border-radius: 8px;
    background: #f2f2f2;
    font-size: 15px;
    margin-bottom: 12px;
    transition: .4s;
    opacity: .6;
}

.panel:target {
    border-color: #4caf50;
    background: #e9ffe9;
    transform: scale(1.05);
    opacity: 1;
}
</>
Form Doğrulama Sözde Sınıflar :target Pseudo Sınıf Örnek (+)
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Target Pseudo Sınıf Örneği 2</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>
    <div class="sss-kapsayici">
        <h2>Sıkça Sorulan Sorular</h2>

        <div class="sss-grup">
            <a href="#cevap1" class="soru">Üyelik kaydını nasıl yapabilirim?</a>
            <div id="cevap1" class="cevap-kutu">
                Üst menüdeki "Giriş Yap / Kaydol" bağlantısına tıklayın. Ardından "Yeni Hesap Oluştur" seçeneğini
                seçerek
                gerekli bilgileri doldurabilirsiniz.
            </div>
        </div>

        <div class="sss-grup">
            <a href="#cevap2" class="soru">Siparişimi iptal edebilir miyim?</a>
            <div id="cevap2" class="cevap-kutu">
                Siparişiniz kargoya verilmediyse, profilinizdeki "Siparişlerim" sayfasından iptal talebi
                oluşturabilirsiniz.
                Kargoya verilmiş siparişler için iade süreci başlar.
            </div>
        </div>

        <div class="sss-grup">
            <a href="#cevap3" class="soru">Ödeme seçenekleri nelerdir?</a>
            <div id="cevap3" class="cevap-kutu">
                Kredi/banka kartı, havale/EFT ve belirli ürünlerde kapıda ödeme seçeneklerimiz mevcuttur.
            </div>
        </div>

    </div>
</body>

</html>
/* CSS */
body {
    font-family: 'Roboto', sans-serif;
    background-color: #f7f9fc;
    padding: 40px 20px;
    display: flex;
    justify-content: center;
}

.sss-kapsayici {
    width: 90%;
    max-width: 700px;
    background-color: white;
    padding: 30px;
    border-radius: 10px;
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.08);
}

h2 {
    text-align: center;
    color: #1a237e;
    margin-bottom: 30px;
}

.sss-grup {
    margin-bottom: 15px;
    border-bottom: 1px solid #e0e0e0;
    padding-bottom: 15px;
}

.soru {
    display: block;
    text-decoration: none;
    color: #3f51b5;
    font-weight: bold;
    padding: 10px 15px;
    background-color: #e8eaf6;
    border-radius: 5px;
    cursor: pointer;
    transition: background-color 0.2s;
}

.soru:hover {
    background-color: #c5cae9;
}

.cevap-kutu {
    overflow: hidden;
    max-height: 0;
    padding: 0 15px;
    margin-top: 0;
    background-color: #ffffff;
    border-left: 3px solid #3f51b5;
    color: #455a64;
    transition: max-height 0.4s ease-out, padding 0.4s ease-out;
}

.cevap-kutu:target {
    max-height: 200px;
    padding: 15px;
    margin-top: 10px;
    border: 2px solid #2c97c9;
    border-radius: 6px;
    background-color: #fcfcfc;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
}

/* 
  ** Cevap açıldığında ilgili soruyu da vurgulayabiliriz    

  ** Bu, cevap kutusunun kendisi değil, onunla aynı seviyedeki
  soru linki olduğu için bu kullanım biraz zordur.

  ** Sadece cevap kutusunun kendisi `:target` olabilir.

  ** Ancak, açılan cevaba ait sorunun rengini değiştirmek için 
  genellikle bu yapıda CSS selector'ları yetersiz kalır ve JS gerekir.

  ** Ama biz bu örnekte :target'ı vurgulamak için bunu kullanıyoruz.
*/

Keşfedilmemiş Bağlantılar :link

Teknik Ayrım: "a" etiketi vs ":link"

:link sözde sınıfı, bir web sayfasındaki bağlantıların ( a ) henüz kullanıcı tarafından tıklanmamış, yani tarayıcı geçmişinde bulunmayan "saf" durumunu hedefler.

Web'in varsayılan mavi renkli ve altı çizili görünümü, aslında tarayıcının bu sınıfa uyguladığı varsayılan stildir.

Genellikle geliştiriciler doğrudan a { color: red; } yazarak tüm linkleri boyarlar.

Ancak :link kullanmak daha spesifiktir.

Sadece href özniteliğine sahip olan ( yani gerçekten bir yere giden ) ve henüz ziyaret edilmemiş bağlantıları seçer.

Bu ayrım, linklerinizi "gidilmiş" ve "gidilmemiş" olarak görselleştirmek istediğinizde hayati önem taşır.

Altın Kural: LVHA Sıralaması

CSS'te link durumlarını yazarken uymanız gereken evrensel bir sıralama kuralı vardır: Link, Visited, Hover, Active.

:link her zaman en başta tanımlanmalıdır.

Eğer :hover veya :active kurallarını :link'ten önce yazarsanız, CSS'in basamaklı yapısı ( Cascade ) nedeniyle hover efektleriniz çalışmayabilir ( ezilir ).

Tasarım Stratejisi

:link, sitenizin "Ana Tema Rengini" yansıtmalıdır.

Kullanıcıya "Burası tıklanabilir bir alan" mesajını en net veren durumdur.

Modern tasarımlarda genellikle altı çizili ( text-decoration: underline ) özelliği :link durumunda kapatılır ve sadece :hover durumunda açılır.

</>
Etkileşim Tabanlı Sözde Sınıflar :link Örnek 1 (+)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Link Örneği</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>
    <h2>:link Örneği</h2>

    <div class="link-container">
        <a href="#feature1" class="nav-link">⭐ Özellik 1</a>
        <a href="#feature2" class="nav-link">⭐ Özellik 2</a>
        <a href="#feature3" class="nav-link">⭐ Özellik 3</a>
    </div>

</body>

</html>
body {
    font-family: Arial, Helvetica, sans-serif;
    padding: 30px;
    background-color: #f5f7fa;
}
h2 {
    text-align: center;
    text-transform: uppercase;
    font-size: 22px;
    font-weight: 700;
    color: #2c3e50;
    margin-bottom: 20px;
}

.link-container {
    display: flex;
    flex-direction: column;
    gap: 10px;
    max-width: 250px;
    margin: 0 auto;
}

a:link {
    text-decoration: none;
    color: #4c84ff;
    font-weight: 600;
    padding: 10px 14px;
    border-radius: 6px;
    background-color: #eaf2ff;
    transition: 0.3s;
}

a:link:hover {
    background-color: #d0e1ff;
    transform: translateX(4px);
}   

Tüm Bağlantıların Birleştiricisi :any-link

Kritik Fark: :link vs :any-link

:any-link sözde sınıfı, bir elementin (genellikle a, area veya link) kaynak bağlantısı içerdiği her durumu kapsayan bir "süper küme"dir.

Basitçe ifade etmek gerekirse; bir linkin daha önce tıklanıp tıklanmadığına bakmaksızın, "Bu bir linktir" diyen her şeyi seçer.

Çoğu geliştirici :link seçicisini "tüm linkler" sanır ama bu büyük bir yanılgıdır.

:link sadece ve sadece ziyaret edilmemiş bağlantıları seçer , seçildikten sonra ziyaret edilenler kapsam dışı kalır.

:any-link ise hem :linkhem de :visited durumlarını tek çatı altında toplar.

Neden "a" Etiketi Yetmiyor? a { ... } yazmak tüm <a> etiketlerini seçer.

Ancak HTML'de href özelliği olmayan ( sadece sayfa içi çapa noktası olarak kullanılan name="...") a etiketleri de olabilir.

Bu "link olmayan a'ları" yanlışlıkla boyamamak için :any-link en güvenli yoldur ve sadece gerçekten tıklanabilir olanları hedefler.

Kod Temizliği (Refactoring) Eskiden tüm linklerin alt çizgisini kaldırmak için şöyle yazılırdı: a:link, a:visited { text-decoration: none; }.

Artık bunu tek bir hamlede yapabilirsiniz: :any-link { text-decoration: none; }.

Bu, özellikle CSS Reset dosyalarında kodu sadeleştirir.

Teknik Detay: Öncelik (Specificity) Artışı a etiketi bir Element Seçicidir ve öncelik puanı düşüktür ( 0-0-1 ).

Ancak :any-link bir Sözde Sınıftır ve öncelik puanı daha yüksektir ( 0-1-0 ).

Bu şu anlama gelir: Eğer :any-link kullanarak bir renk tanımlarsanız, bu kural, basit a etiketiyle yazılmış genel stilleri ezer. .

Bu özellik, global tema dosyalarında link stillerinin kazara bozulmasını önlemek için bir sigorta görevi görür

Geleceğe Hazırlık (Polyfill Mantığı) Web standartları değiştikçe, sadece <a> değil, bağlantı özelliği kazanan yeni elementler de ortaya çıkabilir.

:any-link, etiketin ismine değil, işlevine (bir yere bağlanıp bağlanmadığına) baktığı için kodunuzu gelecekteki HTML değişikliklerine karşı dayanıklı hale getirir.

</>
Uluslararasılaştırma ve Dil Duyarlılığı Sözde Sınıflar :any-link Pseudo Sınıf Örnek (+)
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>
    <div class="anylink-demo">
        <h2>:any-link Örneği</h2>

        <p>
            Aşağıdaki linkler ziyaret edilmiş olsun veya olmasın aynı temel stili alır
            çünkü <strong>:any-link</strong> hem <em>:link</em> hem <em>:visited</em> olanları hedefler.
        </p>

        <nav class="nav-links">
            <a href="#home">🏠 Ana Sayfa</a>
            <a href="#blog">📰 Blog</a>
            <a href="#services">🛠 Hizmetler</a>
            <a href="https://example.com" target="_blank">🌍 Harici Site</a>
        </nav>
    </div>

</body>

</html>
body {
    background: #111;
    color: #eee;
    font-family: Arial, sans-serif;
    padding: 40px;
}

.anylink-demo {
    background: #1e1e1e;
    padding: 25px;
    border-radius: 12px;
    max-width: 450px;
    margin: auto;
    box-shadow: 0 0 15px rgba(255, 255, 255, 0.1);
    border: 1px solid #fff;
}

.anylink-demo h2 {
    text-align: center;
    margin-bottom: 20px;
    color: #00e5ff;
}

.nav-links {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-top: 20px;
}

.nav-links a:any-link {
    text-decoration: none;
    color: #fff;
    padding: 14px;
    border: 2px solid #00eaff;
    border-radius: 8px;
    text-align: center;
    transition: 0.3s;
}

.nav-links a:hover {
    background: #00eaff;
    color: #111;
    transform: translateX(6px);
    box-shadow: 0px 0px 10px #00eaff;
}

.nav-links a:active {
    transform: scale(0.96);
}

Şuana Kadar Ne Öğrendik?

Bu bölümde
  • Alt konu başına tam HTML+CSS editörü; bazı başlıklarda iki örnek
  • Alt konu / not başlıkları
Öğrendiklerimiz
  • Kapsam: „Dinamik Etkileşim Sınıfları” (sayfadaki 2. ana konu başlığı) — kullanıcı eylemine bağlı durumlar
  • Durum kavramı; görsel geri bildirim, mikro etkileşim; öngörülebilirlik ve güven
  • Anlık etkileşim: :hover, :active, :focus, :focus-visible, :focus-within
  • Bağlantılar: :visited, :link, :any-link (LVHA); gezinme: :target
  • Mobil hover, sticky hover, outline / WCAG, ziyaret geçmişi kısıtları gibi bağlam notları
Sırada Ne Var?
  • Sonraki bölüm: Yapısal ve Mantıksal Sınıflar (3. ana konu) — kullanıcı eyleminden bağımsız, DOM üzerinde seçim
  • Ağaç yapısı: ebeveyn / çocuk / kardeş; sıra ve tür bazlı filtreleme
  • :first-child / :last-child, :nth-child()
  • :not(), :has(), :empty ve örnekler
  • Henüz değil: form durumları (:checked vb.) — sonraki 4. ana konuda
Seviye 4

Yapısal ve Mantıksal Sınıflar DOM Mimarisi: Sıralama, Filtreleme ve İlişkiler

Statik İşaretlemeden Algoritmik Seçime

Şimdiye kadar incelediğimiz sınıflar (:hover, :focus vb.) kullanıcının eylemlerine yanıt veriyordu.

Ancak Yapısal ve Mantıksal Sınıflar, kullanıcıdan bağımsız çalışır.

Onlar, sayfanın mimarisine, elementlerin diziliş sırasına ve birbirleriyle olan akrabalık ilişkilerine bakar.

Eski web geliştirme alışkanlıklarında, bir listenin son maddesinin alt çizgisini kaldırmak için HTML'e elle class="son-madde" yazılırdı.

Bu gruptaki seçiciler, bu manuel işçiliği ortadan kaldırır. Tarayıcıya "Bana bu listenin sonuncusunu bul" ( :last-child ) veya

"Sadece tek sayıları seç" ( :nth-child(odd) ) diyerek, tasarımı otomatize etmenizi sağlarlar.

DOM Ağacında Yön Bulma HTML bir soy ağacı gibidir ( Parent, Child, Sibling ). Bu seçiciler, CSS'in bu ağaç üzerinde gezinmesini sağlayan pusulalardır.

Bir elementin "kaçıncı kardeş" olduğunu hesaplayabilir, belirli bir türdeki elementleri filtreleyebilir veya bir ebeveyni

"içindeki çocuğa göre" ( :has ) şekillendirebilirsiniz.

Mantıksal Operatörler Bu bölüm, CSS'in programlama mantığına en çok yaklaştığı yerdir.

Sadece neyi seçeceğinizi değil; neyi seçmeyeceğinizi ( :not ) veya hangi koşullar altında seçeceğinizi belirleyerek "Akıllı Stil Sayfaları" oluşturmanıza olanak tanır.

Sınır Bekçileri: İlk ve Son :first-child ve :last-child

Giriş İçeriği

Bu iki seçici, bir ebeveyn elementin içerisindeki sıralamanın en başını ve en sonunu hedefleyen, CSS'in en temel yapı taşlarıdır.

Karmaşık formüllere ihtiyaç duymadan, bir grubun ilk ve son üyesini doğrudan seçmenizi sağlarlar.

:first-child (İlk Evlat) Bir ebeveynin içindeki ilk HTML öğesini temsil eder.

Örneğin, bir blog yazısındaki ilk paragrafı seçip yazı tipini büyütmek veya bir listenin en tepesindeki maddeyi vurgulamak için kullanılır.

:last-child (Son Evlat) Bir ebeveynin içindeki son HTML öğesini temsil eder.

Dinamik içeriklerde (örneğin veritabanından kaç tane geleceği belli olmayan yorumlar listesinde) listenin sonunu yakalamak ve stil vermek için kritiktir.

Kenar Düzeltmeleri ve Temizlik

Tasarım süreçlerinde en sık karşılaşılan estetik sorunlardan biri, tekrarlayan öğelerin ( listeler, menüler, kartlar ) başında veya sonunda oluşan gereksiz boşluklardır.

Örneğin: Yan yana dizilen bir menü tasarladığınızı ve her öğenin sağına ayırıcı bir çizgi ( border-right ) koyduğunuzu düşünün.

Bu kuralı tüm elemanlara uygularsanız, en sondaki elemanın sağında da anlamsız bir çizgi oluşur ve bu istenmeyen, hatalı bir görünümdür.

Çözüm Stratejisi:

İşte burada :last-child devreye girer. Grubun sadece son elemanını hedefleyip, ona özel olarak border: none diyerek o fazlalık çizgiyi kaldırırsınız.

Benzer bir mantıkla :first-child, grubun en başındaki elemanı hedefler.

Genellikle bir makalenin ilk paragrafının girintisini kaldırmak veya dikey bir listenin tepesindeki gereksiz margin-top değerini sıfırlamak için kullanılır.

</>
Yapısal ve Mantıksal Sınıflar :first and :last Child Örnek (+)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>First and Last Child Örneği</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>

    <h2>first-child & last-child Örneği</h2>

    <div class="card-list">
        <div class="card">Kart 1</div>
        <div class="card">Kart 2</div>
        <div class="card">Kart 3</div>
        <div class="card">Kart 4</div>
    </div>

</body>

</html>
body {
    font-family: Arial, Helvetica, sans-serif;
    padding: 20px;
}

h2 {
    font-size: 20px;
    font-weight: bold;
    margin-bottom: 20px;
    text-transform: uppercase;
}

.card-list {
    max-width: 260px;
}

.card {
    background: #f2f2f2;
    padding: 12px;
    margin: 10px 0;
    border-radius: 8px;
    transition: .3s ease;
}

.card:first-child {
    background: #d3f8d3;
    border-left: 4px solid #2ecc71;
    font-weight: bold;
}

.card:last-child {
    background: #ffe0da;
    border-right: 4px solid #e74c3c;
    font-style: italic;
}

.card:hover {
    transform: translateX(6px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
</>
Yapısal ve Mantıksal Sınıflar :first Child Örnek (+)
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>
    <div class="menu-kapsayici">
        <h2>Haftalık Menümüz</h2>
        <ul class="menu-liste">
            <li class="menu-item">
                <span class="baslik">Günün Özel Yemeği</span>
                <span class="aciklama">Izgara Somon, Kuşkonmaz ve Patates Püresi</span>
                <span class="fiyat">350 TL</span>
            </li>

            <li class="menu-item">
                <span class="baslik">Mercimek Çorbası</span>
                <span class="aciklama">Geleneksel Ev Yapımı</span>
                <span class="fiyat">80 TL</span>
            </li>

            <li class="menu-item">
                <span class="baslik">Tavuk Sote</span>
                <span class="aciklama">Pirinç pilavı eşliğinde</span>
                <span class="fiyat">220 TL</span>
            </li>

            <li class="menu-item">
                <span class="baslik">Meyveli Yoğurt</span>
                <span class="aciklama">Orman meyveleri ile hafif tatlı</span>
                <span class="fiyat">100 TL</span>
            </li>
        </ul>
    </div>
</body>

</html>
/* CSS */
body {
    font-family: Arial, sans-serif;
    background-color: #f4f7f9;
    padding: 20px;
}

.menu-kapsayici {
    width: 80%;
    max-width: 700px;
    margin: 50px auto;
    padding: 30px;
    background-color: white;
    box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
    border-radius: 12px;
}

h2 {
    color: #333;
    text-align: center;
    margin-bottom: 25px;
}

.menu-liste {
    list-style: none;
    padding: 0;
}

.menu-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 15px 0;
    border-bottom: 1px dashed #eee;
    color: #666;
    transition: background-color 0.3s;
}

.menu-item:last-child {
    border-bottom: none;
}

.menu-item:hover {
    background-color: #f9f9f9;
}

.baslik {
    font-weight: bold;
    color: #444;
    flex: 2;
}

.aciklama {
    flex: 3;
    font-size: 0.9em;
    color: #999;
}

.fiyat {
    font-weight: bold;
    color: #007bff;
    flex: 1;
    text-align: right;
}


.menu-item:first-child {
    padding: 20px;
    margin: 10px 0;
    background-color: #ffe0b2;
    border: 2px solid #ff9800;
    border-radius: 8px;
    box-shadow: 0 4px 10px rgba(255, 152, 0, 0.3);
    font-size: 1.1em;
}

.menu-item:first-child .fiyat {
    color: #e65100;
    font-size: 1.2em;
    transform: scale(1.05);
}

.menu-item:first-child .baslik {
    color: #333;
}
</>
Yapısal ve Mantıksal Sınıflar :last Child Örnek (+)
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>
    <div class="adim-kapsayici">
        <h3>Sipariş Tamamlama Adımları</h3>

        <ul class="adim-listesi">
            <li class="adim">
                <span class="numara">1</span>
                <span class="baslik">Teslimat Adresi</span>
                <span class="durum tamamlandi">Tamamlandı</span>
            </li>

            <li class="adim">
                <span class="numara">2</span>
                <span class="baslik">Ödeme Yöntemi Seçimi</span>
                <span class="durum aktif">Aktif</span>
            </li>

            <li class="adim">
                <span class="numara">3</span>
                <span class="baslik">Siparişi Onayla ve Bitir</span>
                <span class="durum bekleniyor">Bekleniyor</span>
            </li>
        </ul>

    </div>
</body>

</html>
/* CSS */
body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background-color: #e8eaf6;
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    margin: 0;
}

.adim-kapsayici {
    width: 90%;
    max-width: 500px;
    background-color: white;
    padding: 30px;
    border-radius: 15px;
    box-shadow: 0 12px 24px rgba(0, 0, 0, 0.1);
}

h3 {
    text-align: center;
    color: #3f51b5;
    margin-bottom: 30px;
}

.adim-listesi {
    list-style: none;
    padding: 0;
}

.adim {
    display: flex;
    align-items: center;
    padding: 15px;
    margin-bottom: 10px;
    border-radius: 8px;
    background-color: #f5f5f5;
    transition: transform 0.2s, box-shadow 0.2s;
    border-left: 5px solid #c5cae9;
}

.adim:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.05);
}

.numara {
    font-size: 1.2em;
    font-weight: bold;
    color: #3f51b5;
    background-color: white;
    border: 2px solid #3f51b5;
    border-radius: 50%;
    width: 30px;
    height: 30px;
    display: flex;
    justify-content: center;
    align-items: center;
    margin-right: 15px;
}

.baslik {
    flex-grow: 1;
    font-weight: 600;
    color: #444;
}

.durum {
    font-size: 0.85em;
    padding: 3px 8px;
    border-radius: 5px;
    font-weight: bold;
}

.tamamlandi {
    color: #2e7d32;
    background-color: #e8f5e9;
}

.aktif {
    color: #ff9800;
    background-color: #fff3e0;
}

.bekleniyor {
    color: #757575;
    background-color: #e0e0e0;
}

.adim:last-child {
    background-color: #3f51b5;
    color: white;
    border-left: 5px solid #ff4081;
    transform: scale(1.02);
    margin-top: 25px;
    box-shadow: 0 8px 15px rgba(63, 81, 181, 0.4);
    cursor: pointer;
}

.adim:last-child .numara {
    color: white;
    background-color: #ff4081;
    border-color: white;
}

.adim:last-child .baslik {
    color: white;
    font-size: 1.1em;
}

.adim:last-child .durum {
    color: white;
    background-color: #303f9f;
}

Matematiğin Gücü ve Döngüler :nth-child()

Manuel Sınıflara Son (Otomasyon)

Bu seçici, CSS dünyasının İsviçre Çakısı gibidir.

Bir ebeveynin içindeki çocukları, sadece isimlerine göre değil, bulundukları konuma, belirli bir formüle veya matematiksel döngüye göre hedeflemenizi sağlar.

Web tasarımının eski günlerinde, tablolarda veya listelerde "bir dolu, bir boş" ( zebra şerit ) görünümü elde etmek için HTML koduna müdahale edilirdi.

Geliştiriciler, her satıra elle odd ( tek ) ve even ( çift ) gibi sınıflar eklemek zorundaydı.

Bu yöntem, veri tabanından yeni bir satır geldiğinde tüm düzenin bozulmasına yol açardı.

:nth-child sayesinde, bu işlem artık dinamik ve otomatiktir.

İçerik ne kadar değişirse değişsin, CSS her zaman doğru satırı boyar.

Formül Yapısı: (an + b) Bu seçicinin kalbinde basit bir cebir formülü yatar.

Parantez içine yazılan değer, seçimin mantığını belirler.

Formüldeki n harfi, "0'dan başlayıp sonsuza giden bir sayaçtır" (0, 1, 2, 3...).

Tarayıcı bu formülü her bir öğe için çalıştırır.

a (Döngü Katsayısı): Döngünün büyüklüğünü belirler.

"Her 3 elemanda bir seç" veya "Her 5 elemanda bir seç" derken kullandığımız sayıdır.

b (Ofset / Başlangıç): Döngünün kaçıncı elemandan başlayacağını belirleyen öteleme değeridir.

Örneğin 2n + 1 formülü; "İkili döngülerle git ama 1. sıradan başla" demektir (yani tek sayıları seçer).

</>
Yapısal ve Mantıksal Sınıflar :nth-child Örnek 2 (+)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Nth Child Pseudo Sınıf Örneği</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>

    <h2>nth-child() Örneği</h2>

    <ul class="color-list">
        <li>Öğe 1</li>
        <li>Öğe 2</li>
        <li>Öğe 3</li>
        <li>Öğe 4</li>
        <li>Öğe 5</li>
    </ul>

</body>

</html>
body {
    font-family: Arial, Helvetica, sans-serif;
    padding: 20px;
}

h2 {
    font-size: 20px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 1px;
    margin-bottom: 15px;
}

.color-list {
    list-style: none;
    padding: 0;
    max-width: 220px;
}

.color-list li {
    background: #f2f2f2;
    padding: 10px;
    margin: 6px 0;
    border-radius: 6px;
    transition: .3s;
}

.color-list li:nth-child(2) {
    background: #bfe6ff;
}

.color-list li:nth-child(4) {
    background: #ffe1b8;
}

.color-list li:hover {
    transform: translateX(5px);
}
</>
Yapısal ve Mantıksal Sınıflar :nth-child Örnek 2 (+)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Nth Child Pseudo Sınıf Örnek</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>
    <div class="tablo-kapsayici">
        <h3>Kullanıcı Erişim Listesi</h3>

        <table>
            <thead>
                <tr>
                    <th>ID</th>
                    <th>Adı</th>
                    <th>E-posta</th>
                    <th>Durum</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>101</td>
                    <td>Ali Yılmaz</td>
                    <td>ali.y@email.com</td>
                    <td>Aktif</td>
                </tr>
                <tr>
                    <td>102</td>
                    <td>Berna Kaya</td>
                    <td>b.kaya@email.com</td>
                    <td>Aktif</td>
                </tr>
                <tr>
                    <td>103</td>
                    <td>Can Demir</td>
                    <td>can.d@email.com</td>
                    <td>Pasif</td>
                </tr>
                <tr>
                    <td>104</td>
                    <td>Deniz Ece</td>
                    <td>deniz.e@email.com</td>
                    <td>Aktif</td>
                </tr>
                <tr>
                    <td>105</td>
                    <td>Emre Fırat</td>
                    <td>emre.f@email.com</td>
                    <td>Beklemede</td>
                </tr>
                <tr>
                    <td>106</td>
                    <td>Gizem Han</td>
                    <td>gizem.h@email.com</td>
                    <td>Aktif</td>
                </tr>
            </tbody>
        </table>
    </div>
</body>

</html>
body {
    font-family: 'Arial', sans-serif;
    background-color: #e8f4f8;
    padding: 30px;
    display: flex;
    justify-content: center;
}

.tablo-kapsayici {
    width: 90%;
    max-width: 800px;
    background-color: white;
    padding: 20px;
    border-radius: 10px;
    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
}

h3 {
    color: #008cba;
    text-align: center;
    margin-bottom: 20px;
}

table {
    width: 100%;
    border-collapse: collapse;
}

th,
td {
    padding: 12px 15px;
    text-align: left;
    border-bottom: 1px solid #ddd;
}

thead th {
    background-color: #008cba;
    color: white;
    font-weight: bold;
    border-bottom: 2px solid #006687;
}

tbody tr:nth-child(even) {
    background-color: #f2f2f2;
}

tbody tr:nth-child(odd) {
    background-color: #ffffff;
    /* Beyaz */
}

tbody tr td:nth-child(1) {
    font-weight: bold;
    color: #005f78;


}

tbody tr:nth-child(5) {
    background-color: #ffcccc;
    color: #cc0000;
    font-weight: bold;
    box-shadow: 0 0 5px rgba(255, 0, 0, 0.3);
}
Nth Child Pseudo Sınıf Formülleri Sık Kullanılan Desenler ve Anlamları
Değer / Formül
Mantıksal İşlev ve Kullanım Alanı
:nth-child(2)

Sabit Seçim (Single Index): Bir döngü yaratmaz.
Ebeveynin içindeki sadece ve kesin olarak 2. sıradaki öğeyi seçer.
Genellikle bir listenin belirli bir maddesini vurgulamak için kullanılır.

:nth-child(odd)

Tek Sayılar (Odd Numbers): Matematiksel karşılığı 2n+1 değeridir.
1, 3, 5, 7... şeklinde ilerler.
Uzun tablolarda satırları ayırt etmek ve okunabilirliği artırmak için endüstri standardıdır.

:nth-child(even)

Çift Sayılar (Even Numbers): Matematiksel karşılığı 2n.
2, 4, 6, 8... şeklinde ilerler.
Genellikle odd ile zıt renkler kullanılarak desen oluşturmak için tamamlayıcı olarak kullanılır.

:nth-child(3n)

Üçlü Çarpım Döngüsü (Multiplier): 3'ün katlarını (3, 6, 9...) hedefler.
Özellikle 3 sütunlu grid yapılarında, satırın en sonundaki elemanın sağ kenar boşluğunu sıfırlamak için kritiktir.

:nth-child(3n+1)

Ofsetli Döngü (Offset Loop): 3'erli atlar ama saymaya 1'den başlar (1, 4, 7...).
Bu formül, 3 sütunlu bir düzende her yeni satırın ilk elemanını seçmek ( clear: both vermek ) için kullanılır.

Hariç Tutma Mantığı / Negation :not()

"Override" (Stil Ezme) Kültürüne Son

CSS doğası gereği genellikle "neyi seçeceğini" söyler; ancak bu sözde sınıf "neyi seçmeyeceğini" söyler.

Bir kural yazarken istisnaları sonradan düzeltmek yerine, istisnaları baştan hariç tutmanızı sağlar.

Geleneksel CSS yazımında, önce genel bir kural yazılır, ardından istisna olan öğe için bu kural geri alınırdı.

Örneğin, yan yana dizili bir menüde tüm öğelerin sağına çizgi çekip ( border-right ), sonra son öğeyi seçip

"Hayır, sen çizgi yapma" (border: none) demek bir "yama" işlemidir.

:not() sayesinde bu mantık tersine döner: "Sonuncu hariç hepsine çizgi çek."

Bu sayede tarayıcı, son öğeye hiç stil uygulamaz ve sizin de o stili sonradan iptal etmeniz gerekmez bu durumda kodunuz kısalır ve performansı artar.

Mantıksal Filtreleme ve Temiz Kod :not() içerisine sınıf, ID veya başka bir sözde sınıf yazarak, belirli bir kuralın dışında kalmasını istediğiniz öğeleri cerrah titizliğiyle filtreleyebilirsiniz.

Gerçek Hayat Senaryosu:

Bir formdaki butonları düşünün. Tüm butonlara hover efekti vermek istiyorsunuz, ancak "Devre Dışı" olan butonun rengi değişmemeli.

Bunu yapmak için: .btn:not(.disabled):hover yazmanız yeterlidir.

Bu kural şu anlama gelir: "Eğer bir buton .disabled sınıfına sahip DEĞİLSE, üzerine gelince rengini değiştir."

Böylece pasif butona tıklamaya çalışan kullanıcı, yanıltıcı bir renk değişimi görmez ve kullanıcı deneyimi iyileşir.

</>
Yapısal ve Mantıksal Sınıflar :not Pseudo Sınıf Örnek (+)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Not Pseudo Sınıf Örneği</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>

    <h2>:not() Örneği</h2>

    <div class="btn-group">
        <button class="btn">Varsayılan</button>
        <button class="btn">Kaydet</button>
        <button class="btn danger">Sil</button>
        <button class="btn">Paylaş</button>
    </div>

</body>

</html>

                            
body {
    font-family: Arial, Helvetica, sans-serif;
    padding: 20px;
}

h2 {
    font-size: 20px;
    margin-bottom: 15px;
    font-weight: bold;
    text-transform: uppercase;
}

.btn-group {
    display: flex;
    gap: 10px;
}

.btn {
    background: #e6e6e6;
    border: none;
    padding: 10px 18px;
    border-radius: 6px;
    cursor: pointer;
    transition: .3s;
    font-size: 14px;
}

.danger {
    background: #ff5c5c;
    color: white;
}

.btn:not(.danger):hover {
    background: #bcdcff;
    transform: translateY(-3px);
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
}

.danger:hover {
    background: #ff3b3b;
    transform: scale(1.05);
}

CSS'in Devrimi: Ebeveyn Seçicisi :has()

Kuralları Yıkmak: "Geriye Doğru Bakış"

Web geliştiricilerinin 20 yıldır hayalini kurduğu, yıllarca performans sorunları nedeniyle "imkansız" denilen özellik artık modern tarayıcıların kalbinde çalışıyor.

CSS, doğası gereği her zaman "yukarıdan aşağıya" akardı.

Bir ebeveyn ( parent ), çocuğunu ( child ) etkilerdi ama çocuk, ebeveyninin stilini asla değiştiremezdi.

:has() bu temel kuralı tersine çevirir ve şelalenin suyunu yukarı doğru pompalar.

Artık bir kutuyu, sadece kendi özelliklerine göre değil, içindeki içeriğin varlığına veya durumuna göre şekillendirebilirsiniz.

Bu seçicinin çalışma mantığı, programlamadaki "IF / THEN" koşul yapısına benzer:

"Eğer bu kutunun içinde bir resim varsa (IF), kutunun arka planını siyah yap (THEN)."

Kullanım Senaryosu: Akıllı ve Duyarlı Kartlar

Bir blog kartı tasarımınız olduğunu düşünün. İçerik yönetim sisteminden gelen bazı kartlarda görsel var, bazılarında ise sadece metin var.

Eskiden olsa, görseli olmayan kartlar için HTML'e ekstra bir sınıf ( .card--no-image ) eklemek için arka plan ( Backend ) kodu yazmanız gerekirdi.

Şimdi ise .card:has(img) yazarak, tarayıcıya "İçinde img etiketi barındıran kartları bul" diyebilirsiniz.

Bu sayede, görsel içeren kartlara özel bir ızgara düzeni uygularken, görsel olmayanları standart akışta bırakabilirsiniz.

Bu yöntem, JavaScript yazmadan "şartlı stil" yazmanın en güçlü ve performanslı yoludur.

Form Kontrolü ve UX İyileştirmesi:

Karmaşık formlarda kullanıcı deneyimini artırmak için, seçili alanların belirginleşmesi gerekir.

Geleneksel CSS ile bir input seçildiğinde sadece kendisini veya yanındaki kardeşini boyayabilirdiniz.

Ancak :has() ile input'u kapsayan ebeveyn elementi ( tüm satırı veya kartı ) hedefleyebilirsiniz.

.row:has(input:checked) kodu şu emri verir: "İçindeki kutucuk işaretlenmiş olan satırı bul ve o satırın tamamının arka plan rengini değiştir."

Bu, kullanıcının hangi seçeneği işaretlediğini uzaktan bile net bir şekilde görmesini sağlar.

Boşluk Durumu :empty

"Hayalet Kutulardan" Kurtulmak

Bu seçici, DOM ağacındaki en seçici filtrelerden biridir: İçerisinde hiçbir çocuk öğe, metin veya boşluk karakteri barındırmayan tamamen boş elementleri hedefler.

CSS'te bir kutuya padding veya border verdiğinizde, o kutu içi boş olsa bile ekranda yer kaplar ve görünür.

Bu durum, özellikle dinamik içeriklerde ( bir uyarı kutusu veya bildirim alanı ) "içi boş ama çerçevesi var" gibi hatalı, amatör bir görünüme yol açar. Buna tasarımda "Hayalet Kutu" denir.

Otomatik Gizleme: Eğer içerik gelmediyse, o kutunun ekranda gereksiz yer işgal etmesini istemezsiniz.

div:empty { display: none; } kuralı, adeta bir "çöp toplayıcı" gibi çalışır.

İçi boşalan kutuyu anında gizleyerek tasarımın bütünlüğünü korur.

Teknik Uyarı: Boşluk Karakteri Tuzağı Bu seçici çok hassastır, bir etiketin içinde görünmez bile olsa bir "boşluk" karakteri veya satır atlama varsa, tarayıcı onu "dolu" kabul eder.

Yani <div> </div> ( içinde boşluk var ) boş sayılmazken, <div></div> ( bitişik ) boş sayılır.

</>
Form Doğrulama Sözde Sınıflar :empty Pseudo Sınıf Örnek (+)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Empty Pseudo Sınıf Örneği</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>

    <h2>:empty Örneği</h2>

    <div class="box-container">
        <div class="box"></div>
        <div class="box">Merhaba</div>
        <div class="box"></div>
    </div>

</body>

</html>
body {
    font-family: Arial, Helvetica, sans-serif;
    padding: 20px;
}

h2 {
    text-transform: uppercase;
    margin-bottom: 20px;
}

.box-container {
    display: flex;
    gap: 12px;
}

.box {
    width: 120px;
    height: 80px;
    border: 2px solid #ccc;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    background: #ffffff;
    transition: .3s;
}

.box:empty {
    background: #eeeeee;
    border-color: #999;
    color: transparent;
}

.box:hover {
    transform: scale(1.05);
}
</>
Yapısal ve Mantıksal Sınıflar :has Pseudo Sınıf Örnek (+)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Has Pseudo Sınıf Örneği</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>

    <h2>:has() Örneği</h2>

    <div class="card">
        <p>Bu kartta checkbox yok.</p>
    </div>

    <div class="card">
        <p>Bu kartta checkbox var.</p>
        <input type="checkbox">
    </div>

    <div class="card">
        <p>Bu kartta yine checkbox var.</p>
        <input type="checkbox" checked>
    </div>

</body>

</html>
body {
    font-family: Arial, Helvetica, sans-serif;
    padding: 20px;
}

h2 {
    font-size: 20px;
    text-transform: uppercase;
    margin-bottom: 20px;
}

.card {
    border: 2px solid #ccc;
    padding: 15px;
    border-radius: 8px;
    margin-bottom: 12px;
    transition: .3s;
    background: #f7f7f7;
}

.card:has(input[type="checkbox"]) {
    border-color: #007bff;
    background: #eaf3ff;
}

.card:has(input[type="checkbox"]:checked) {
    background: #d6ffda;
    border-color: #28a745;
    transform: scale(1.02);
}

Şuana Kadar Ne Öğrendik?

Bu bölümde
  • Karşılaştırma tablosu
  • Tam editör örnekleri; bazı konularda birden fazla
  • Alt konu / not başlıkları
Öğrendiklerimiz
  • Kapsam: „Yapısal ve Mantıksal Sınıflar” (3. ana konu) — kullanıcıdan bağımsız DOM seçimleri
  • Ağaç yapısı: sıra ve tür; :first-child / :last-child, :nth-child()
  • :not(), :has(), :empty
  • Manuel sınıf işçiliği yerine algoritmik seçim; mantıksal operatörler
Sırada Ne Var?
  • Sonraki bölüm: Form ve Durum Sınıfları (4. ana konu) — canlı form diyaloğu
  • Konular: işaretleme ve etkinlik, okuma/yazma, zorunluluk ve placeholder; geçerlilik, aralık ve belirsiz kutucuk (:checked:indeterminate arası)
  • Henüz değil: dil/yön (:lang, :dir) — 5. ana konuda
Seviye 4

Form ve Durum Sınıfları Veri Girişi ve Kontrol Mekanizması

Kullanıcı ile Canlı Diyalog

Bir web sitesinin en kritik anı, kullanıcının sadece izleyici olmaktan çıkıp katılımcı olduğu, yani size bir şeyler yazdığı ( form doldurduğu ) andır.

Bu etkileşim sırasında arayüzün kullanıcıyla konuşması, ona rehberlik etmesi ve hatalarını nazikçe düzeltmesi gerekir.

Form durum sınıfları, bir input veya button öğesinin o anki biyolojik durumuna göre ( dolu mu, boş mu, seçili mi) stil vermenizi sağlar.

Geri Bildirim Psikolojisi: Kullanıcı bir butona neden tıklayamadığını ( :disabled ) veya girdiği e-postanın neden kabul edilmediğini ( :invalid ) anında görmelidir.

Bu sınıflar, "Gönder" butonuna basılmadan önceki erken uyarı sistemi olarak çalışır ve kullanıcı hatalarını minimize eder.

Form Durum Özellikleri (Attributes) Etkileşim Durumları ve CSS Karşılıkları
Sözde Sınıf
Detaylı Açıklama ve İşlev
:checked

Seçim Durumu: Radyo butonları ( radio ) ve onay kutularının ( checkbox ) aktif/seçili olduğu anı temsil eder.
Sadece kutucuk boyamak için değil; CSS ile "Toggle Switch" butonları yapmak veya JavaScript kullanmadan çalışan akordeon menüler oluşturmak için "mantıksal anahtar" görevi görür.

:disabled

Kısıtlama ve Pasiflik: Sistem tarafından geçici veya kalıcı olarak kapatılmış öğeleri hedefler.
HTML'de disabled özelliği varsa devreye girer.
Genellikle opaklığı düşürmek ( opacity: 0.5 ) ve imleci yasak işaretine ( cursor:not-allowed ) çevirmek için kullanılır.
Kullanıcıya "Şu an buna tıklayamazsın" mesajını verir.

:enabled

Varsayılan Aktiflik: Disabled olmayan, yani etkileşime açık tüm form elemanlarını temsil eder.
Genellikle varsayılan durum olduğu için nadiren elle yazılır, ancak özelleştirilmiş formlarda "aktif" alanları vurgulamak için kullanılabilir.

:read-only

Okunabilir ama Yazılamaz: Kullanıcının içeriği görebildiği, kopyalayabildiği ancak değiştiremediği inputları seçer.
:disabled'dan farkı; bu alanların verisi form gönderilirken sunucuya iletilir ve kullanıcı metni seçebilir.

:required

Zorunluluk Hali: Boş bırakılması yasak olan, HTML'de required özelliğine sahip alanları seçer.
Genellikle bu alanların yanına görsel bir yıldız ( * ) eklemek veya sağ kenarlığına renkli bir çizgi çekerek kullanıcının dikkatini çekmek için kullanılır.

Seçim ve Tetikleme Mekanizması :checked

Arayüzün "Mantıksal Anahtarı"

:checked sözde sınıfı, bir arayüzde "seçilmiş olma" durumunu temsil eder.

Teknik olarak; radyo butonları (input type="radio" ), onay kutuları ( input type="checkbox" ) ve açılır menü seçenekleri ( option ) bu duruma sahip olabilir.

Bu sınıfın gücü, sadece o küçük kutucuğu boyamakla sınırlı değildir , kutucuk, sayfanın geri kalanını kontrol eden bir "şalter" görevi görür.

Modern web geliştirmede "Checkbox Hack" olarak bilinen teknik sayesinde; JavaScript'e hiç dokunmadan çalışan akordeon menüler,

sekmeli yapılar, modal pencereler ve yan menüler yapılabilir.

Çalışma Prensibi: Kardeş Seçiciler Kullanıcı bir kutucuğu işaretlediğinde, CSS'in kardeş seçicileri ( + veya ~ ) kullanılarak, o kutucuğun hemen yanındaki veya altındaki elementlerin görünümü değiştirilir.

Örneğin: input:checked + .icerik { display: block; } diyerek, gizli bir içeriği görünür hale getirebilirsiniz.

Görsel Özgürlük: Toggle Switch

Tarayıcıların varsayılan "tik" işareti ve mavi kutucuğu genellikle tasarımcılar için yeterli değildir.

Bu durumda gerçek input gizlenir.

Ardından label etiketi ve ::before / ::after kullanılarak, o meşhur "iPhone tarzı" kayan açma/kapama butonları tasarlanır. :checked olduğunda yuvarlak buton sağa kaydırılır ve arka plan yeşil yapılır.

</>
Form Doğrulama Sözde Sınıflar :checked Pseudo Sınıf Örnek (+)
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>
    <h2>:checked Örneği</h2>

    <div class="form-group">
        <label>
            <input type="checkbox" name="newsletter">
            📰 Bülten aboneliği
        </label>

        <label>
            <input type="checkbox" name="updates">
            🔔 Güncellemeler
        </label>

        <p class="status">Seçilen seçenek yok</p>
    </div>

</body>

</html>
body {
    font-family: Arial, Helvetica, sans-serif;
    padding: 30px;
    background: #f4f6f9;
}

h2 {
    text-align: center;
    text-transform: uppercase;
    font-size: 22px;
    font-weight: 700;
    color: #2c3e50;
    margin-bottom: 25px;
}

.form-group {
    display: flex;
    flex-direction: column;
    gap: 12px;
    max-width: 300px;
    margin: 0 auto;
}

label {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 15px;
    font-weight: 500;
    cursor: pointer;
}

input[type="checkbox"] {
    width: 18px;
    height: 18px;
    cursor: pointer;
}

input[type="checkbox"]:checked {
    accent-color: #4caf50;
}

.status {
    font-size: 14px;
    color: #555;
    margin-top: 10px;
}

Etkileşime Kapalı / Pasif Durum :disabled

Teknik Kesinti: Veri Akışı Durur

:disabled sözde sınıfı, kullanıcının etkileşime girmesinin sistem tarafından engellendiği, "ölü" veya "donmuş" form elemanlarını hedefler.

HTML tarafında disabled özniteliği eklenmiş bir buton, input veya select kutusu, tarayıcı tarafından otomatik olarak bu duruma geçer.

Bu durumun sadece görsel değil, çok önemli bir teknik sonucu vardır:

Devre dışı bırakılan bir input alanının verisi, form gönderildiğinde sunucuya iletilmez.

Ayrıca bu elemanlar "Odaklanma Sırasından" çıkarılır, yani kullanıcı klavyedeki Tab tuşuna bastığında tarayıcı bu elemanların üzerinden atlar, onları görmezden gelir.

UX Stratejisi: Neden Gizlemiyoruz?

Bir butonu kullanılamaz hale getirmek için neden display: none ile gizlemiyoruz da :disabled yapıyoruz?

Çünkü kullanıcıya "Bu özellik burada var, ancak şu an kullanabilmek için gerekli şartları ( formu doldurmak gibi ) sağlamadın" mesajını vermek isteriz.

Görsel olarak genellikle opaklığı düşürülür ( opacity: 0.5 ), gri tonlamaya çevrilir ( filter: grayscale(100%) ) ve fare imleci "Giriş Yasak" işaretine ( cursor: not-allowed ) dönüştürülür.

Etkileşime Açık / Aktif Durum :enabled

Varsayılanın Gücü

Aktif durum için kullanılan :enabled, teknik olarak disabled özniteliğine sahip olmayan, yani sağlıklı, canlı ve etkileşime açık tüm form elemanlarını temsil eder.

Çoğu geliştirici "Zaten varsayılan durum bu, neden böyle bir seçici var?" diye düşünebilir.

Bu seçici, özellikle karmaşık formlarda "Tersine Mühendislik" yapmamak için kullanılır.

Pratik Kullanım Senaryosu

Bir formu tasarlarken genellikle şöyle yaparız: Önce genel input stilini yazarız, sonra input:disabled ile pasif olanları ezeriz (override).

:enabled kullanarak mantığı düzeltebiliriz: "Sadece aktif olanlara gölge ve renk ver."

input:enabled { box-shadow: ...; }

Böylece, disabled olan elemanlar için ekstra bir "gölgeyi sıfırla" (box-shadow: none) kodu yazmanıza gerek kalmaz. Tarayıcı zaten disabled olanlara bu stili hiç uygulamaz.

Kritik İpucu: Hover ve Focus Güvenliği

Web arayüzlerinde sıkça yapılan bir hata, pasif (:disabled) bir butona mouse ile gelindiğinde renginin değişmeye devam etmesidir.

Bu, kullanıcıda "Tıklayabilirim" algısı yaratır fakat bu hatayı önlemek için :hover efektlerini doğrudan elemente değil, sadece aktif haline tanımlamalısınız.

Yani; button:hover yerine button:enabled:hover yazarsanız, pasif butonların üzerine gelindiğinde renk değişimi otomatik olarak engellenir.

Dinamik Durum Yönetimi

Modern web uygulamalarında form alanları, kullanıcının seçimlerine göre anlık olarak açılıp kapanabilir.

Bir JavaScript kodu, bir input'un disabled özelliğini kaldırdığı anda, :enabled seçicisi devreye girer.

Ekstra bir "aktif" sınıfı ekleyip çıkarmaya gerek kalmadan, element "canlandığı" anda tanımladığınız canlı renkleri ve gölgeleri otomatik olarak kazanır.

</>
Form Doğrulama Sözde Sınıflar :enabled ve :disabled Pseudo Sınıf Örnek (+)
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>

    <div class="form-wrapper">
        <h2>:enabled / :disabled Örneği</h2>

        <div class="form-container">
            <label>
                Ad Soyad:
                <input type="text" placeholder="Yazabilirsiniz">
            </label>

            <label>
                E-posta:
                <input type="email" placeholder="Yazabilirsiniz">
            </label>

            <label>
                Şifre (devre dışı):
                <input type="password" placeholder="Şifre" disabled>
            </label>

            <button type="submit">Gönder</button>
        </div>
    </div>


</body>

</html>
body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background: #f4f6f9;
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    margin: 0;
}

.form-wrapper {
    background: #ffffff;
    padding: 30px 35px;
    border-radius: 14px;
    box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
    max-width: 400px;
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.form-wrapper h2 {
    font-size: 22px;
    font-weight: 700;
    text-align: center;
    color: #2c3e50;
    margin: 0;
}

.form-container {
    display: flex;
    flex-direction: column;
    gap: 15px;
}
label {
    display: flex;
    flex-direction: column;
    font-weight: 500;
    font-size: 14px;
    color: #333;
}

input {
    padding: 12px 14px;
    border: 2px solid #ccc;
    border-radius: 10px;
    font-size: 14px;
    outline: none;
    transition: 0.3s;
    background-color: #fafafa;
    box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.05);
}

input:enabled {
    border-color: #4688ff;
    background-color: #eef5ff;
}

input:disabled {
    background-color: #f0f0f0;
    border-color: #ccc;
    cursor: not-allowed;
}

input:focus {
    border-color: #2a6cff;
    box-shadow: 0 0 8px rgba(70, 136, 255, 0.4);
}

button {
    padding: 12px 20px;
    border: none;
    border-radius: 10px;
    background: #4caf50;
    color: #fff;
    font-weight: 600;
    cursor: pointer;
    transition: 0.3s;
}

button:hover {
    background: #45a049;
}

Salt Okunur Mod :read-only

Kritik Fark: Disabled vs Read-only

:read-only sözde sınıfı, kullanıcının içeriğini görebildiği, seçip kopyalayabildiği ancak değiştiremediği form alanlarını hedefler.

HTML tarafında readonly özniteliği eklenmiş bir input veya textarea, tarayıcı tarafından bu sınıfla işaretlenir.

Tasarımcıların en sık karıştırdığı iki kavramdır; ancak aralarında teknik bir uçurum vardır.

:disabled olan bir alan ölüdür; tıklanamaz, odaklanılamaz ve form gönderildiğinde verisi sunucuya gitmez.

:read-only olan bir alan ise canlıdır; kullanıcı içine tıklayabilir, metni seçip kopyalayabilir ve form gönderildiğinde bu veri sunucuya iletilir.

Kullanım Senaryosu: Sabit Veriler

Genellikle bir profil sayfasında "Kullanıcı Adı" veya "Üyelik Numarası" gibi değiştirilemeyen ama görünmesi gereken bilgileri sunmak için kullanılır.

Tasarımda bu alanlara genellikle hafif gri bir arka plan verilir veya kenarlıkları kaldırılarak ( border: none; ) "Bu bir form alanı değil, sadece metin" hissiyatı yaratılır.

</>
Form Doğrulama Sözde Sınıflar :read-only Pseudo Sınıf Örnek 1 (+)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>:read-only Örneği</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>
    <h2>:read-only Örneği</h2>

    <div class="form-group">
        <label>Ad Soyad</label>
        <input type="text" placeholder="Yazılabilir alan">

        <label>Ülke</label>
        <input type="text" value="Türkiye" readonly>

        <label>ID Numarası</label>
        <input type="text" value="User-98321" readonly>
    </div>

</body>

</html>
body {
    font-family: Arial, Helvetica, sans-serif;
    padding: 30px;
    background: #f4f6f9;
}

/* Başlık */
h2 {
    text-transform: uppercase;
    text-align: center;
    font-size: 22px;
    font-weight: 700;
    color: #2c3e50;
    margin-bottom: 25px;
}

/* Form container */
.form-group {
    display: flex;
    flex-direction: column;
    gap: 14px;
    max-width: 300px;
    margin: 0 auto;
}
label {
    font-size: 15px;
    font-weight: 600;
    color: #555;
}
input {
    padding: 12px;
    border: 2px solid #ccc;
    border-radius: 6px;
    font-size: 14px;
    outline: none;
    transition: .3s ease;
}
input:not([readonly]):hover {
    border-color: #4688ff;
}
input:read-only {
    background-color: #e9ecef;
    border-color: #bfbfbf;
    cursor: not-allowed;
    color: #555;
    font-style: italic;
}
input:focus {
    border-color: #3d8bfd;
    box-shadow: 0 0 5px rgba(61, 139, 253, .3);
}
</>
Form Doğrulama Sözde Sınıflar :read-only Pseudo Sınıf Örnek 2 (+)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <title>:read-only Örneği</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>

    <div class="form-kapsayici">
        <h3>Kullanıcı Profil Bilgileri</h3>
        <p class="aciklama">🔒 ile işaretli alanlar değiştirilemez.</p>

        <form>
            <div class="alan-grubu">
                <label for="kullaniciAdi">Kullanıcı Adı 🔒</label>
                <input type="text" id="kullaniciAdi" value="coder_ahmet_42" readonly>
            </div>

            <div class="alan-grubu">
                <label for="email">E-posta Adresi</label>
                <input type="email" id="email" value="ahmet.dev@example.com">
            </div>

            <div class="alan-grubu">
                <label for="kayitTarihi">Kayıt Tarihi 🔒</label>
                <input type="text" id="kayitTarihi" value="2023-01-15" readonly>
            </div>

            <div class="alan-grubu">
                <label for="telefon">Telefon Numarası</label>
                <input type="tel" id="telefon" value="+90 555 123 45 67">
            </div>

            <button type="submit">Bilgileri Güncelle</button>
        </form>
    </div>

</body>

</html>
/* CSS */
body {
    font-family: 'Verdana', sans-serif;
    background-color: #e6eefc;
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    margin: 0;
}

.form-kapsayici {
    width: 90%;
    max-width: 450px;
    background-color: white;
    padding: 30px;
    border-radius: 10px;
    box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1);
    border-top: 5px solid #007bff;
}

h3 {
    color: #333;
    text-align: center;
    margin-bottom: 5px;
}

.aciklama {
    text-align: center;
    color: #6c757d;
    font-size: 0.9em;
    margin-bottom: 25px;
}

.alan-grubu {
    margin-bottom: 20px;
}

label {
    display: block;
    font-weight: bold;
    color: #495057;
    margin-bottom: 5px;
    font-size: 0.9em;
}

input[type="text"],
input[type="email"],
input[type="tel"] {
    width: 100%;
    padding: 12px;
    border: 1px solid #ced4da;
    border-radius: 6px;
    box-sizing: border-box;
    font-size: 1em;
    background-color: #fff;
    transition: all 0.3s ease;
}

input:not([readonly]):focus {
    border-color: #007bff;
    box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
    background-color: #e9f5ff;
}



input:read-only {

    background-color: #f8f9fa;
    color: #6c757d;
    border-style: dashed;
    cursor: not-allowed;
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
    opacity: 0.9;
}

input:read-only:hover {
    border-color: #adb5bd;
}

button {
    width: 100%;
    padding: 12px;
    background-color: #28a745;
    color: white;
    border: none;
    border-radius: 6px;
    font-size: 1.1em;
    cursor: pointer;
    transition: background-color 0.3s;
    margin-top: 15px;
}

button:hover {
    background-color: #218838;
}

Yazılabilir ve Düzenlenebilir Alanlar :read-write

Kapsam Alanı: Standartlar ve Ötesi

Bu sözde sınıf, bir web sayfasındaki "tüketim" modu ile "üretim" modu arasındaki sınırı belirler.

Kullanıcının sisteme veri girmesine, mevcut içeriği değiştirmesine veya silmesine teknik olarak izin verilen tüm alanları temsil eder.

Varsayılan olarak, HTML'deki input ve textarea elementleri, eğer üzerlerinde readonly veya disabled kısıtlaması yoksa, doğal birer

:read-write öğesidir.

Ancak bu seçicinin gerçek gücü, standart form elemanlarının dışına çıktığında anlaşılır.

Modern Web: "Contenteditable" Devrimi

HTML5 ile gelen contenteditable="true" özelliği, sıradan bir div, p veya span etiketini bir anda "Microsoft Word" benzeri bir yazı editörüne dönüştürebilir.

:read-write seçicisi, bu tür "sonradan editör olmuş" elementleri de otomatik olarak tanır ve hedefler.

Bu, CMS panelleri, not alma uygulamaları veya yorum düzenleme alanları tasarlarken harici sınıflar (.is-editing vb.) ekleyip çıkarma zahmetinden sizi kurtarır.

UX İpucu: Yazılabilirliği Hissettirmek

Kullanıcı, bir metnin düzenlenebilir olduğunu ilk bakışta anlamalıdır.

Bu alanlar için genellikle arka plan rengini beyaz yapmak, hafif bir iç gölge eklemek veya odaklanıldığında ( :focus ile birlikte ) etrafında belirgin bir düzenleme çerçevesi oluşturmak en iyi pratiklerdir.

Ayrıca fare imlecinin (cursor) otomatik olarak "metin seçici" formuna dönüşmesi, bu durumun doğal bir sonucudur.

</>
Form Doğrulama Sözde Sınıflar :read-write Pseudo Sınıf Örnek (+)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>:read-write Örneği</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>
    <h2>:read-write Örneği</h2>

    <div class="form-group">
        <label>Ad Soyad</label>
        <input type="text" placeholder="Doldurabilirsiniz">

        <label>E-posta</label>
        <input type="email" placeholder="Doldurabilirsiniz">

        <label>ID (readonly)</label>
        <input type="text" value="USER-12345" readonly>
    </div>

</body>

</html>
body {
    font-family: Arial, Helvetica, sans-serif;
    padding: 30px;
    background: #f4f6f9;
}

h2 {
    text-align: center;
    text-transform: uppercase;
    font-size: 22px;
    font-weight: 700;
    color: #2c3e50;
    margin-bottom: 25px;
}

.form-group {
    display: flex;
    flex-direction: column;
    gap: 14px;
    max-width: 300px;
    margin: 0 auto;
}

label {
    font-size: 15px;
    font-weight: 600;
    color: #555;
}

input {
    padding: 12px;
    border: 2px solid #ccc;
    border-radius: 6px;
    font-size: 14px;
    outline: none;
    transition: 0.3s ease;
}

input:read-write {
    border-color: #4688ff;
    background-color: #ffffff;
    font-style: normal;
}

input:read-write:hover {
    box-shadow: 0 0 5px rgba(70, 136, 255, 0.3);
}

input:read-only {
    background-color: #e9ecef;
    border-color: #bfbfbf;
    cursor: not-allowed;
    font-style: italic;
}

input:focus {
    border-color: #3d8bfd;
    box-shadow: 0 0 5px rgba(61, 139, 253, 0.3);
}

Zorunlu Alan Yönetimi :required

Kullanıcı Beklentisini Yönetmek

:required sözde sınıfı, HTML tarafında required özelliği eklenmiş, özniteliği eklenmiş, yani boş bırakılmasına sistemsel olarak izin verilmeyen alanları seçer.

Kullanıcılar uzun bir formla karşılaştıklarında, enerjilerini korumak için genellikle sadece zorunlu alanları doldurma eğilimindedirler.

Bu seçici sayesinde, hangi alanların kritik, hangilerinin "olsa da olur" olduğunu bir bakışta göstererek bilişsel yükü azaltırsınız.

Görsel İşaretleme Stratejileri Endüstri standardı olarak, zorunlu alanların etiketinin yanına kırmızı bir yıldız ( * ) konulur.

Bunu CSS ile yapmak için genellikle input:required + label::after gibi bitişik kardeş seçicileri kullanılır.

Alternatif olarak, zorunlu alanların arka planına çok hafif bir sarı tonu vererek veya sol kenarlığına kalın bir çizgi çekerek dikkat çekicilik sağlanabilir.

Zıttı: :optional Zorunlu olmayan her alan, teknik olarak :optional durumundadır.

Modern tasarımlarda bazen zorunlu alanları işaretlemek yerine, sadece isteğe bağlı olanların yanına parantez içinde yazarak daha temiz bir görünüm elde edilir.

</>
Form Doğrulama Sözde Sınıflar :required Pseudo Sınıf Örnek (+)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Required Pseudo Sınıf Örneği</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>

    <h2>:required Örneği</h2>

    <form class="form-box">
        <label for="name">Ad Soyad <span>*</span></label>
        <input type="text" id="name" required placeholder="Zorunlu alan">

        <label for="email">E-posta</label>
        <input type="email" id="email" placeholder="Opsiyonel">

        <button type="submit">Gönder</button>
    </form>

</body>

</html>
body {
    font-family: Arial, Helvetica, sans-serif;
    padding: 20px;
}

h2 {
    font-size: 20px;
    margin-bottom: 20px;
    text-transform: uppercase;
}

.form-box {
    display: flex;
    flex-direction: column;
    gap: 12px;
    max-width: 300px;
}

label {
    font-size: 14px;
    font-weight: 600;
    display: flex;
    gap: 4px;
}

label span {
    color: #d10000;
}

input {
    padding: 10px;
    border: 2px solid #ccc;
    border-radius: 6px;
    transition: .3s;
    outline: none;
}

input:required {
    border-left: 4px solid #ff4747;
}

input:required:valid {
    border-left-color: #2ecc71;
}

input:hover {
    background: #f6f6f6;
}

button {
    padding: 10px;
    border: none;
    font-size: 15px;
    font-weight: bold;
    border-radius: 6px;
    background: #4c84ff;
    color: white;
    cursor: pointer;
    transition: .3s;
}

button:hover {
    background: #3568d4;
}
                            

Seçime Bağlı ve Serbest Alanlar :optional

Genel Bakış

:optional sözde sınıfı, üzerinde required özniteliği bulunmayan, yani kullanıcının doldurup doldurmamakta özgür bırakıldığı form alanlarını temsil eder.

Form doldurma süreci genellikle streslidir , bu sınıf, kullanıcının "nefes aldığı" ve baskı hissetmediği alanları tanımlar.

Tasarım Paradoksu: Hangisini İşaretlemeli?

Geleneksel tasarımda zorunlu alanlara kırmızı yıldız (*) konulur.

Ancak formdaki 10 alandan 9'u zorunluysa, ekran kırmızı yıldızlarla dolar ve bu durum kullanıcıda "bilişsel yük" oluşturur.

Modern UX yaklaşımlarında trend tersine dönmüştür: Varsayılan olarak her şeyin zorunlu olduğu kabul edilir ve sadece :optional olan alanların yanına yazılır.

Bu strateji, arayüzü görsel gürültüden arındırır ve daha temiz bir görünüm sağlar.

Görsel Farklılaştırma :optional alanlar, zorunlu alanlara göre daha "hafif" hissettirilmelidir.

Örneğin, zorunlu alanların kenarlığı koyu gri ise, opsiyonel alanların kenarlığı daha açık bir gri yapılabilir veya arka planlarına çok hafif bir renk verilerek "Burası o kadar da kritik değil" mesajı verilebilir.

Teknik Kapsam Bu sınıf sadece input için değil; select ve textarea elemanları için de geçerlidir.

Eğer bir input hem :optional hem de :valid durumundaysa ( boş bırakılsa bile geçerlidir ), yeşil onay işareti göstermek yerine "nötr" kalmak genellikle daha iyi bir kullanıcı deneyimi sağlar.

</>
Form Doğrulama Sözde Sınıflar :optional Pseudo Sınıf Örnek (+)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>:optional Pseudo Class Örneği</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>

    <div class="form-box">
        <h2>Form Validasyon Örneği</h2>

        <div class="form-group">
            <label>Ad (Zorunlu)</label>
            <input type="text" placeholder="Adınızı yazın..." required>
        </div>

        <div class="form-group">
            <label>Telefon (Opsiyonel)</label>
            <input type="tel" placeholder="Telefon numarası (isteğe bağlı)">
        </div>

        <div class="form-group">
            <label>Email (Zorunlu)</label>
            <input type="email" placeholder="Email adresiniz..." required>
        </div>

        <button>Gönder</button>
    </div>

</body>

</html>
body {
    font-family: Arial, sans-serif;
    background: #181818;
    color: #fff;
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 20px;
}

.form-box {
    background: #222;
    padding: 25px;
    border-radius: 15px;
    width: 330px;
    box-shadow: 0 8px 25px rgba(0, 0, 0, 0.4);
}

h2 {
    margin-bottom: 15px;
    font-size: 22px;
    text-align: center;
}

.form-group {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 18px;
}

input {
    padding: 12px;
    border-radius: 8px;
    border: 2px solid #3b3b3b;
    background: #101010;
    color: #fff;
    outline: none;
    transition: .3s ease;
    font-size: 15px;
}

input::placeholder {
    color: #777;
}

input:required {
    border-color: #ff6161;
}

input:required:focus {
    border-color: #ff3131;
    background: #2a0000;
}

input:optional {
    border-color: #4caf50;
}

input:optional:focus {
    border-color: #00e676;
    background: #003f1f;
}

button {
    width: 100%;
    padding: 12px;
    background: #00bcd4;
    border: none;
    border-radius: 8px;
    cursor: pointer;
    font-size: 16px;
    font-weight: bold;
    transition: .3s;
}

button:hover {
    background: #0097a7;
}

İçerik Varlığı ve Doluluk Kontrolü :placeholder-shown

JavaScript'siz "Dolu/Boş" Kontrolü

Bu sözde sınıf, bir input veya textarea alanının içinde yer tutucu metnin o an görünüp görünmediğini kontrol eden akıllı bir dedektördür.

Mantığı basittir: Eğer kullanıcı kutuya bir şeyler yazdıysa placeholder gizlenir; yazmadıysa görünür.

Eskiden bir input alanının içinin dolu olup olmadığını anlamak için JavaScript ile karakter sayısını ( value.length ) kontrol etmemiz gerekirdi.

Artık :placeholder-shown ile bunu CSS üzerinden yapabiliyoruz.

Eğer bu sınıf aktifse, kutu boş demektir. Eğer aktif değilse (:not(:placeholder-shown)), kullanıcı kutuya bir veri girmiş demektir.

Modern Tasarım: Uçan Etiketler (Floating Labels)

Bu sınıfın en popüler kullanım alanı, modern formların vazgeçilmezi olan "Floating Label" efektidir.

Normalde input'un içinde duran etiket, kullanıcı yazı yazmaya başladığı anda (:not(:placeholder-shown)) küçülerek input'un tepesine taşınır.

Bu sayede form alanından tasarruf edilirken, kullanıcı ne yazdığını unutmaz.

Önemli Bir Püf Noktası: Bu seçicinin çalışması için input elementinde mutlaka bir placeholder="..." özelliği tanımlı olmalıdır.

Eğer placeholder'ın görünmesini istemiyorsanız ama bu özelliği kullanmak istiyorsanız, placeholder içine bir boşluk karakteri ( " " ) koymanız yeterlidir.

</>
Form Doğrulama Sözde Sınıflar :placeholder-shown Pseudo Sınıf Örnek (+)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>:placeholder-shown Örneği</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>
    <h2>:placeholder-shown Örneği</h2>

    <div class="form-group">
        <label for="username">Kullanıcı Adı:</label>
        <input type="text" id="username" placeholder="Lütfen adınızı girin">
    </div>

</body>

</html>
body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    padding: 40px;
    background-color: #f5f7fa;
}

h2 {
    text-transform: uppercase;
    margin-bottom: 25px;
    font-size: 24px;
    font-weight: 700;
    letter-spacing: 1px;
    color: #333;
    text-align: center;
}

.form-group {
    display: flex;
    flex-direction: column;
    gap: 8px;
    max-width: 300px;
    margin: 0 auto;
}

label {
    font-size: 15px;
    font-weight: 600;
    color: #555;
    margin-bottom: 4px;
}

input {
    padding: 12px;
    border: 2px solid #ccc;
    border-radius: 8px;
    font-size: 15px;
    outline: none;
    transition: 0.3s ease, box-shadow 0.3s ease;
}

input:placeholder-shown {
    border-color: #999;
    background-color: #f2f2f2;
}

input:not(:placeholder-shown) {
    border-color: #4caf50;
    background-color: #e7ffe7;
}

/* Hover efekti */
input:hover {
    background-color: #eef6ff;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}

Veri Doğrulama ve Geri Bildirim :valid

Teknik Tetikleyiciler (Nasıl Çalışır?)

:valid sözde sınıfı, bir form elemanının içeriğinin, belirlenen tüm kurallara uyduğu "başarılı" anı temsil eder.

Kullanıcıya sessizce "Burası tamam, harika gidiyorsun" mesajını vermenin en teknik ve estetik yoludur.

Bu sınıfın devreye girmesi için HTML5 doğrulama kısıtlamalarının (Constraints) sağlanması gerekir.

Örneğin; type="email" olan bir alanda "@" işareti ve bir alan adı varsa veya min="5" olan bir sayı alanına 6 girildiyse, tarayıcı bu girişi geçerli kabul eder ve bu stili uygular.

Eğer bir alanda hiçbir kısıtlama ( required, pattern vb.) yoksa, o alan varsayılan olarak her zaman :valid durumundadır.

Görsel İletişim Stratejileri Tasarımda genellikle input alanının sağ kenarına yeşil bir çizgi çekmek veya background-image ile alanın sağına bir "Tik İşareti" ( ) ikonu yerleştirmek için kullanılır.

Bu görsel ipuçları, kullanıcının formu tamamlama motivasyonunu artırır ve belirsizliği ortadan kaldırır.

İleri Seviye: Zincirleme Tepkiler :valid sınıfını, kardeş seçicilerle (+ veya ~) birleştirerek daha kompleks etkileşimler yaratabilirsiniz.

Örneğin: input:valid + .error-message seçicisi ile, veri doğru girildiği anda hata mesajını gizleyebilir (display: none) veya başarı mesajını görünür kılabilirsiniz.

</>
Form Doğrulama Sözde Sınıflar :valid Pseudo Sınıf Örnek (+)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Valid Pseudo Sınıf Örneği</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>

    <h2>:valid Örneği</h2>

    <div class="form-group">
        <label for="email">E-posta adresi:</label>
        <input type="email" id="email" placeholder="example@mail.com" required>
        <small class="msg">Geçerli bir email giriniz.</small>
    </div>

</body>

</html>
body {
    font-family: Arial, Helvetica, sans-serif;
    padding: 20px;
}

h2 {
    font-size: 20px;
    text-transform: uppercase;
    margin-bottom: 20px;
}

.form-group {
    display: flex;
    flex-direction: column;
    gap: 8px;
    max-width: 260px;
}

label {
    font-weight: bold;
    font-size: 14px;
}

input {
    padding: 10px;
    border: 2px solid #ccc;
    border-radius: 6px;
    font-size: 14px;
    transition: .3s ease;
    outline: none;
}

input:invalid {
    border-color: #ff6b6b;
    background: #ffe9e9;
}

input:valid {
    border-color: #28a745;
    background: #e7ffe7;
}

.msg {
    font-size: 13px;
    color: #666;
}

Hata Yakalama ve Uyarılar :invalid

Anında Hata Yakalama

:invalid sözde sınıfı, form elemanına girilen verinin HTML5 doğrulama kurallarıyla uyuşmadığı durumu temsil eder.

Kullanıcı bir sayı alanına harf girdiğinde veya e-posta alanına "@" koymayı unuttuğunda bu sınıf anında tetiklenir.

Bu sayede, kullanıcı daha "Gönder" butonuna basmadan hatasını fark eder.

Bu, form doldurma sürecindeki sürtünmeyi azaltır.

Görsel Uyarı Yöntemleri En yaygın kullanım, input kenarlığını kırmızı yapmak veya sağ tarafına bir "Ünlem İşareti" ikonu koymaktır.

Daha gelişmiş tasarımlarda, CSS animasyonları (@keyframes) kullanılarak input alanının hafifçe sağa-sola titremesi ( Shake effect ) sağlanabilir.

Bu, "Hayır, bu kabul edilemez" demenin evrensel dijital dilidir.

Kritik İpucu: UX Hatasını Önlemek :invalid sınıfı, sayfa ilk yüklendiğinde de tetiklenebilir (eğer alan required ise).

Bu, kullanıcının daha hiçbir şey yazmadan kırmızı çizgilerle karşılaşmasına ve stres olmasına neden olabilir.

Bunu önlemek için genellikle JavaScript veya :placeholder-shown gibi ek filtreler kullanılır.

</>
Form Doğrulama Sözde Sınıflar :invalid Pseudo Sınıf Örnek (+)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>İnvalid Pseudo Sınıf Örneği</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>

    <h2>:invalid Örneği</h2>

    <div class="form-group">
        <label for="username">Kullanıcı Adı (Min 4 karakter):</label>
        <input type="text" id="username" placeholder="örn: Ali" minlength="4" required>
        <small class="error-msg">⚠ En az 4 karakter giriniz.</small>
    </div>

</body>

</html>
body {
    font-family: Arial, Helvetica, sans-serif;
    padding: 20px;
}

h2 {
    font-size: 20px;
    text-transform: uppercase;
    margin-bottom: 20px;
}

.form-group {
    display: flex;
    flex-direction: column;
    gap: 6px;
    max-width: 260px;
}

label {
    font-size: 14px;
    font-weight: 600;
}

input {
    padding: 10px;
    border: 2px solid #ccc;
    border-radius: 6px;
    outline: none;
    transition: .3s;
    font-size: 14px;
}

input:not(:placeholder-shown):invalid {
    border-color: #ff4d4d;
    background: #ffeaea;
}

input:valid {
    border-color: #28a745;
    background: #eaffea;
}

.error-msg {
    color: #ff3333;
    font-size: 13px;
    opacity: 0;
    transition: .3s ease;
}

input:not(:placeholder-shown):invalid+.error-msg {
    opacity: 1;
}

Sınırlar Dahilinde Güvenli Bölge :in-range

Konuya Genel Giriş Kısmı

:in-range sözde sınıfı, bir giriş alanındaki verinin, HTML öznitelikleriyle çizilmiş olan "sınırlar" içerisinde güvenle durduğu anı temsil eder.

Bu sınıf, tarayıcının yerleşik doğrulama motoruyla doğrudan konuşur; eğer girilen değer matematiksel veya zamansal olarak min ve max değerlerinin kapsama alanındaysa stil uygulanır.

Kapsam Alanı: Sadece Sayılar Değil

Genellikle sadece sayısal (type="number") alanlar için kullanıldığı sanılsa da, kapsamı çok daha geniştir.

Aralık belirtebildiğiniz kaydırıcılar (type="range"), tarihler (type="date") ve saatler (type="time") de bu sınıfın denetimi altındadır.

Yani "2023 ile 2025 yılları arasında bir tarih seçin" dediğinizde, kullanıcının seçimi bu aralıktaysa :in-range devreye girer; bu, formun "Güvenli Bölgesi"dir.

Mantıksal Tutarlılık ve Veri Kalitesi

Web formlarında bazı verilerin ( yaş, adet, puan ) sadece belirli bir matematiksel aralıkta olması mantıklıdır.

Bu sınırların dışı, iş mantığına aykırıdır.

Örneğin: Bir rezervasyon sisteminde "Kişi Sayısı" seçilirken, bu değerin en az 1, en fazla restoranın o anki boş kapasitesi kadar olması gerekir.

HTML tarafında input type="number" min="1" max="10" tanımladığınızda, kullanıcı 5 yazdığında bu sınıf devreye girer ve stil kurallarını uygular.

Görsel Onay ve Pozitif Geri Bildirim Kullanıcıya girdiği sayının sistem tarafından kabul edilebilir olduğunu anlık olarak göstermek, form doldurma güvenini artırır.

Tasarımda genellikle yazı rengi koyu yeşil yapılır, input'un arka planı çok hafif yeşil bir tona boyanır veya sağ tarafa bir "onay ikonu" yerleştirilir.

Bu, kullanıcının bilinçaltına "Doğru yoldayım, sınırlar içindeyim, devam edebilirim" mesajını fısıldar.

</>
Form Doğrulama Sözde Sınıflar :in-range Pseudo Sınıf Örnek (+)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>:in-range / :out-of-range Örneği</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>
    <h2>:in-range / :out-of-range Örneği</h2>

    <div class="form-group">
        <label for="age">Yaş (18-60):</label>
        <input type="number" id="age" min="18" max="60" placeholder="18-60 arası">
    </div>

</body>

</html>
body {
    font-family: Arial, Helvetica, sans-serif;
    padding: 20px;
    background-color: #f5f7fa;
}

h2 {
    text-transform: uppercase;
    font-size: 24px;
    font-weight: 700;
    letter-spacing: 1.5px;
    color: #2c3e50;
    text-align: center;
    margin-bottom: 25px;
    text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.1);
}

.form-group {
    display: flex;
    flex-direction: column;
    gap: 8px;
    max-width: 250px;
    margin: 0 auto;
}

label {
    font-weight: 600;
    color: #555;
}

input {
    padding: 10px;
    border: 2px solid #ccc;
    border-radius: 6px;
    font-size: 14px;
    outline: none;
    transition: 0.3s ease;
}

input:in-range {
    border-color: #4caf50;
    background-color: #e7ffe7;
}

input:out-of-range {
    border-color: #ff4d4d;
    background-color: #ffeaea;
}

input:hover {
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}

Sınır İhlali ve Uyarı :out-of-range

Hata Önleme Mekanizması

Kullanıcının girdiği sayısal değerin veya tarihin, sizin belirlediğiniz limitlerin ( min/max ) dışına taştığı hatalı durumu hedefler.

Bir e-ticaret sitesinde ürün adedini seçerken kullanıcının yanlışlıkla "-5" girmesi veya stoktaki 10 üründen fazlasını talep etmesi sistemsel sorunlara yol açabilir.

:out-of-range sınıfı, bu mantık dışı girişleri anında yakalar.

Dikkat Çekici Uyarılar

Bu durum gerçekleştiğinde, sadece input çerçevesini kırmızı yapmakla kalmayıp, kullanıcının dikkatini çekmek için daha agresif stiller ( kalın yazı, uyarı ikonu ) kullanılmalıdır.

Amaç, kullanıcının imkansız bir işlem yapmaya çalıştığını ( 18 yaşından küçük birinin +18 siteye girmeye çalışması gibi) ona anında bildirmektir.

Unutmayın ki bu sınıf sadece min ve max özelliği tanımlanmış alanlarda çalışır.

</>
Form Doğrulama Sözde Sınıflar :in-range Pseudo Sınıf Örnek (+)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>:out-of-range Farklı Örnek</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>
    <h2>:out-of-range Farklı Örnek</h2>

    <div class="slider-group">
        <label for="volume">Ses Seviyesi (0-100):</label>
        <input type="range" id="volume" min="0" max="100" value="50">
        <span class="msg">Uyarı: Aralık dışına çıkmayın!</span>
    </div>
</body>

</html>
body {
    font-family: Arial, Helvetica, sans-serif;
    padding: 20px;
    background-color: #f5f7fa;
}

h2 {
    text-transform: uppercase;
    font-size: 22px;
    font-weight: 700;
    text-align: center;
    color: #2c3e50;
    margin-bottom: 20px;
}

.slider-group {
    display: flex;
    flex-direction: column;
    gap: 10px;
    max-width: 300px;
    margin: 0 auto;
}

label {
    font-weight: 600;
    color: #555;
}

input[type="range"] {
    width: 100%;
    accent-color: #4caf50;
    cursor: pointer;
}

.msg {
    font-size: 13px;
    color: #ff4d4d;
    opacity: 0;
    transition: opacity 0.3s ease;
}

input:out-of-range+.msg {
    opacity: 1;
}

input[type="range"]:hover {
    outline: 2px solid rgba(76, 132, 255, 0.2);
}

Belirsizlik ve Ara Durum :indeterminate

En Yaygın Senaryo: "Tümünü Seç" Kutusu

Bu sözde sınıf, bir form elemanının ne seçili ne de seçimsiz olduğu, ikisinin arasında bir "Araf" durumunu temsil eder.

Kullanıcıya "Burada kısmi bir seçim var" veya "İşlem devam ediyor ama ne zaman biteceği belli değil" mesajını verir.

Bir e-posta listesinde "Tümünü Seç" kutucuğunu düşünün , eğer listedeki 10 e-postadan sadece 3 tanesini seçerseniz, tepedeki ana kutucuk ne olmalıdır?

Tik atılırsa "Hepsi seçili" yalanını söyler eğer boş bırakılırsa "Hiçbiri seçili değil" yalanını söyler.

İşte bu noktada kutucuğun içine bir tire (-) veya kare işareti konularak :indeterminate durumu devreye girer ve bu

"Altındakilerin bazıları seçili, bazıları değil" demektir.

Teknik Detay: JavaScript Zorunluluğu

Onay kutularında (checkbox) bu durumu HTML'e bir attribute yazarak sağlayamazsınız; bu özellik HTML standardında yoktur.

Bu durumu sadece JavaScript ile tetikleyebilirsiniz: element.indeterminate = true;

Ancak bu durum bir kez ayarlandığında, CSS tarafında input:indeterminate seçicisi ile o kutucuğu yakalayıp rengini veya ikonunu değiştirebilirsiniz.

İlerleme Çubukları (Progress Bars) <progress> elementinde ise durum farklıdır.

Eğer bir ilerleme çubuğuna value (değer) vermezseniz, tarayıcı onu otomatik olarak :indeterminate kabul eder.

Bu, kullanıcının dosya yüklenirken gördüğü o sürekli sağa sola gidip gelen, "Yükleniyor ama yüzde kaçta olduğunu bilmiyorum" animasyonudur.

</>
Form Doğrulama Sözde Sınıflar :indeterminate Pseudo Sınıf Örnek (++)
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Indeterminate Örneğ (HTML , CSS , JAVASCRİPT)i</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>

    <div class="checkbox-container">
        <h2>indeterminate Örneği</h2>
        <div class="form-group">
            <label>
                <input type="checkbox" id="select-all">
                Tümünü Seç
            </label>

            <label>
                <input type="checkbox" class="child"> Seçenek 1
            </label>
            <label>
                <input type="checkbox" class="child"> Seçenek 2
            </label>
            <label>
                <input type="checkbox" class="child"> Seçenek 3
            </label>
        </div>
    </div>

    <script src="script.js?v=1.0.150"></script>
</body>

</html>
body {
    font-family: Arial, Helvetica, sans-serif;
    background: #f4f6f9;
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    margin: 0;
}

h2 {
    text-align: center;
    text-transform: uppercase;
    font-size: 22px;
    font-weight: 700;
    color: #2c3e50;
    margin-bottom: 20px;
}

.checkbox-container {
    background: #ffffff;
    padding: 25px 30px;
    border-radius: 12px;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15);
    max-width: 400px;
    width: 100%;
}

.form-group {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

label {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 15px;
    font-weight: 500;
    cursor: pointer;
}

input[type="checkbox"] {
    width: 18px;
    height: 18px;
    cursor: pointer;
}

input[type="checkbox"]:checked {
    accent-color: #4caf50;
}

input#select-all:indeterminate {
    accent-color: #ffb236;
}
const selectAll = document.getElementById("select-all");
const children = document.querySelectorAll(".child");

children.forEach((ch) => {
  ch.addEventListener("change", () => {
    const total = children.length;
    const checked = document.querySelectorAll(".child:checked").length;

    if (checked === 0) selectAll.indeterminate = false;
    else if (checked === total) selectAll.indeterminate = false;
    else selectAll.indeterminate = true;

    selectAll.checked = checked === total;
  });
});

selectAll.addEventListener("change", () => {
  children.forEach((ch) => (ch.checked = selectAll.checked));
});

Şuana Kadar Ne Öğrendik?

Bu bölümde
  • Karşılaştırma tablosu
  • Tam editör örnekleri; bazı konularda birden fazla
  • Alt konu / not başlıkları
Öğrendiklerimiz
  • Kapsam: „Form ve Durum Sınıfları” (4. ana konu) — kullanıcı etkileşimine bağlı anlık durumlar
  • Alan durumları: işaretleme, etkin/pasif, salt okunur/yazılabilir, zorunluluk ve :placeholder-shown vb.
  • Doğrulama ve aralık: :valid / :invalid, :in-range / :out-of-range, :indeterminate
  • Form diyaloğu üzerinden geri bildirim; içerikte :checked:indeterminate arası tüm alt başlıklar
Sırada Ne Var?
  • Sonraki bölüm: Uluslararasılaştırma ve Dil Duyarlılığı (5. ana konu) — lang / dir ve kültürel uyum
  • :lang() ile belge/dil seçimi; :dir() ile LTR / RTL düzeni
  • Henüz değil: :root, :is(), :where() vb. — 6. ana konuda (global mantıksal seçiciler)
Seviye 4

Uluslararasılaştırma ve Dil Duyarlılığı Global Erişim: Diller, Yönler ve Kültür

Dilin Ötesinde: Tipografi ve Yapı

"World Wide Web" adının hakkını vermek için, tasarladığımız arayüzlerin sadece tek bir dile veya kültüre değil, tüm dünyaya hitap edebilecek esneklikte olması gerekir.

Uluslararasılaştırma, bir web sitesinin kod yapısını değiştirmeden, farklı dillere ve yazım yönlerine otomatik olarak adapte olabilmesini sağlayan mimari yaklaşımdır.

Bir siteyi İngilizce'den Japonca'ya çevirmek sadece kelimeleri değiştirmek değildir; satır yüksekliklerini, font ailelerini ve hatta

vurgu renklerini değiştirmeyi gerektirebilir.

İngilizce'de kullanılan italik vurgusu, bazı Asya dillerinde okunabilirliği bozduğu için tercih edilmez.

İşte bu noktada CSS'in dil odaklı seçicileri devreye girer ve "Eğer dil Japonca ise italik yapma, kalınlaştır" gibi kültürel ayarları otomatikleştirir.

Yönelim Paradoksu: LTR ve RTL

Latin alfabesi kullanan diller Soldan Sağa (LTR) akar.

Ancak Arapça ve İbranice gibi diller Sağdan Sola (RTL) akar.

Bu durum, sadece metnin hizasını değil; ikonların yerini, margin ve padding değerlerinin yönünü, hatta kaydırma çubuğunun konumunu bile değiştirir.

Bu bölümde inceleyeceğimiz seçiciler, HTML'in kendisine (lang="tr" veya dir="rtl") bakarak sayfanın iskeletini anlık olarak yeniden düzenlemenizi sağlar.

Kültürel Noktalama ve "Otomatik" Alıntılar Her dilin kendine has bir noktalama stili vardır.

Örneğin: İngilizce'de alıntılar “...” ile yapılırken, Fransızca'da «...» işaretleri kullanılır.

HTML tarafında sadece standart <q> etiketini kullanıp, CSS'in dil seçicileriyle tırnak işaretlerini ( quotes özelliği ) dile göre otomatik değiştirmek, gerçek bir uluslararasılaştırma örneğidir.

Tasarım Riski: Metin Genişlemesi Bir butona "Giriş" yazdığınızda harika görünebilir.

Ancak aynı buton Almanca'ya çevrildiğinde "Anmelden" veya başka bir dilde daha uzun olabilir.

Dil odaklı seçiciler, belirli dillerde font boyutunu dinamik olarak küçülterek (font-size) tasarımın patlamasını önlemenize yardımcı olur.

Dil Tabanlı Stil ve Tipografi :lang()

Genel Bakış

:lang() sözde sınıfı, bir elementin (veya ebeveyninin) HTML üzerindeki lang özniteliğine bakarak, o elementin hangi dilde yazıldığını algılar ve ona özel stiller uygular.

Bir web sayfası tek bir dilde yazılmış olsa bile, içindeki alıntılar veya teknik terimler farklı dillerde olabilir.

CSS, bu değişimi algılayacak kadar zekidir.

Kritik Teknik Fark: Akıllı Eşleşme

Çoğu geliştirici "Neden [lang="en"] (Attribute Selector) kullanmıyoruz?" diye sorar, cevap ise hiyerarşik zekadır.

Eğer [lang="en"] kullanırsanız, tarayıcı sadece ve sadece "en" değerini arar.

"en-US" veya "en-GB" değerlerini görmezden gelir

Ancak :lang(en) kullanırsanız, tarayıcı "en" ile başlayan tüm alt lehçeleri otomatik olarak kapsar, bu, kodunuzu geleceğe karşı korur.

Tipografik Kültür (CJK Sorunu)

Latin alfabesi için tasarlanmış bir font, Asya dillerindeki ( Çince, Japonca, Korece - CJK ) karmaşık karakterleri gösterirken yetersiz kalabilir veya estetik dışı görünebilir.

:lang(ja) ( Japonca ) veya :lang(zh) ( Çince ) kullanarak, sayfanın geri kalanına dokunmadan sadece bu dillerdeki metinler için özel, okunabilir bir font-family atayabilirsiniz.

Heceleme Kuralları (Hyphenation)

Uzun kelimelerin satır sonunda nasıl bölüneceği dilden dile değişir.

:lang() sayesinde, Almanca gibi uzun kelimeli diller için otomatik hecelemeyi (hyphens: auto) açarken, diğer dillerde bu özelliği kapalı tutarak okuma akışını optimize edebilirsiniz.

Otomatik Alıntı İşaretleri (Quotes)

Her dilin noktalama kültürü farklıdır. İngilizcede “...” kullanılırken, Fransızcada «...», Almancada ise „...“ (aşağıdan açılan) tırnaklar kullanılır.

:lang() ile birlikte quotes özelliğini tanımlayarak, sitenizdeki tüm <q> etiketlerinin, içeriğin diline göre doğru noktalama işaretlerini otomatik olarak almasını sağlayabilirsiniz.

Bu, manuel olarak her alıntı için özel karakter kodu arama zahmetini ortadan kaldırır.

Geleceğe Yatırım: Sesli Asistanlar

Dil tanımlaması sadece görsel değildir; işitsel bir deneyimdir.

Doğru :lang() kullanımı, ekran okuyucuların ( Screen Readers ) metni doğru aksanla telaffuz etmesini sağlar.

CSS tarafında bu seçiciyi kullanmak, HTML'de dil tanımlarının doğru yapılıp yapılmadığını denetlemeniz ( debug etmeniz ) için de harika bir görsel araç olabilir.

</>
Uluslararasılaştırma ve Dil Duyarlılığı Sözde Sınıflar :lang Pseudo Sınıf Örnek (+)
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>
    <div class="lang-box">
        <h2>:lang() Örneği</h2>

        <p lang="tr">Merhaba! Bu paragraf Türkçe yazılmıştır.</p>
        <p lang="en">Hello! This paragraph is written in English.</p>
        <p lang="de">Hallo! Dieser Absatz ist auf Deutsch geschrieben.</p>
    </div>

</body>

</html>
body {
    font-family: system-ui, Arial, sans-serif;
    padding: 30px;
    background: #f7f7f7;
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
}

.lang-box {
    background: white;
    padding: 25px;
    border-radius: 12px;
    width: 420px;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.12);
}

.lang-box h2 {
    text-align: center;
    margin-bottom: 20px;
    font-weight: 700;
    color: #2d3436;
}

.lang-box p {
    padding: 10px 14px;
    border-left: 4px solid transparent;
    background: #f1f1f1;
    border-radius: 6px;
    margin-bottom: 10px;
    transition: 0.3s;
    font-size: 15px;
}

p:lang(tr) {
    border-left-color: #e74c3c;
}

p:lang(en) {
    border-left-color: #0984e3;
    font-style: italic;
}

p:lang(de) {
    border-left-color: #2ecc71;
    letter-spacing: 1px;
}

Yönelim ve Akış Kontrolü :dir()

Genel Bakış

:dir() sözde sınıfı, bir elementin metin okuma yönünün Soldan Sağa mı yoksa Sağdan Sola mı olduğunu, tarayıcının hesaplamalarına dayanarak tespit eder.

Web sadece İngilizce veya Türkçe gibi Latin kökenli dillerden ibaret değildir.

Arapça, İbranice veya Farsça gibi dillerde sayfa yapısının tamamen tersine çevrilmesi gerekir.

Kritik Fark: Nitelik ([dir]) vs Sözde Sınıf (:dir)

Çoğu geliştirici yönü kontrol etmek için [dir="rtl"] nitelik seçicisini kullanır. Ancak bu yöntem yetersizdir.

Nitelik seçicisi, sadece üzerinde o etiketin yazılı olduğu elementi bulur.

Ancak :dir(rtl) çok daha zekidir; elementin üzerinde bir tanımlama olmasa bile, ebeveynlerinden (html veya body) gelen yönü miras alır ve hesaplanmış değeri (computed value) baz alarak karar verir.

Arayüzü Aynalamak (UI Mirroring)

Yön değiştiğinde sadece metin değil, ikonların anlamı da değişir.

"İleri" gitmeyi temsil eden sağa bakan bir ok ( ) , RTL bir düzende "Geri" gitmeyi ifade edebilir.

:dir(rtl) kullanarak, Arapça bir arayüzde bu ikonları otomatik olarak 180 derece döndürebilir (transform: scaleX(-1)) ve mantıksal hatayı düzeltebilirsiniz.

Mantıksal Özelliklerle İlişkisi Modern CSS'te margin-left yerine margin-inline-start kullanmak çoğu sorunu çözer.

Ancak arka plan resimleri, gölgelerin yönü (box-shadow) veya spesifik transformasyonlar gibi "Logical Properties" ile çözülemeyen durumlar için :dir() hala vazgeçilmez bir araçtır.

</>
Uluslararasılaştırma ve Dil Duyarlılığı Sözde Sınıflar :dir Pseudo Sınıf Örnek (+)
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>
    <div class="dir-container">

        <h2>Dir Attribute Örneği</h2>

        <div class="dir-box" dir="ltr">
            <p>LTR Direction content text example.</p>
        </div>

        <div class="dir-box" dir="rtl">
            <p>‮Pseudo RTL directional text sample.‬</p>
        </div>

        <div class="dir-box" dir="auto">
            <p>Auto detects based on first character.</p>
        </div>

    </div>

</body>

</html>
body {
    display: flex;
    justify-content: center;
    background: #111;
    padding: 40px;
    font-family: sans-serif;
    color: #fff;
}

.dir-container {
    width: 480px;
    display: flex;
    flex-direction: column;
    gap: 1.6rem;
}

.dir-box {
    padding: 20px;
    border-radius: 12px;
    background: #1c1c1c;
    border: 2px solid transparent;
    transition: 0.3s;
    font-size: 17px;
}

.dir-box:dir(ltr) {
    border-color: #00c3ff;
    box-shadow: 0 0 8px #00c3ff88;
    text-align: left;
}

.dir-box:dir(rtl) {
    border-color: #ff007a;
    box-shadow: 0 0 8px #ff007a88;
    text-align: right;
}

.dir-box:hover {
    transform: scale(1.03);
}

Şuana Kadar Ne Öğrendik?

Bu bölümde
  • Tam editör örnekleri; :lang ve :dir altında
  • Dil, yön ve kültürel bağlam (metin + örnekler)
  • Alt konu / not başlıkları
Öğrendiklerimiz
  • Kapsam: „Uluslararasılaştırma ve Dil Duyarlılığı” (5. ana konu) — lang / dir ile küresel arayüz
  • :lang() ile dil seçimi; :dir() ile LTR / RTL düzeni
  • Tipografi, tırnak (quotes) ve metin genişlemesi gibi kültürel uyum konuları
Sırada Ne Var?
  • Sonraki bölüm: Global ve Mantıksal Seçiciler (6. ana konu) — belge konumu, gruplama ve özgüllük
  • Konular: :root (köke değişkenler), :is(), :where()
  • Henüz değil: tam ekran, PiP, modal, oynatma durumları — 7. ana konuda (medya ve özel UI)
Seviye 5

Global ve Mantıksal Seçiciler Yönetim ve Mantık Katmanı

Kök ve Değişken Merkezi: :root

Bu sözde sınıflar, bir öğenin durumundan veya etkileşiminden ziyade, belgedeki konumu, hiyerarşisi veya bir koşulu sağlayıp sağlamadığı gibi mantıksal yapıları hedeflemeye odaklanır.

Tasarım sistemleri kurarken ve kod tekrarını (DRY - Don't Repeat Yourself) önlemek için en güçlü araçlardır.

HTML belgesinin kök öğesini (her zaman <html> etiketi) hedefler.

Etiket seçici olan html'den daha spesifiktir ve tarayıcı tarafından desteklenen en yüksek global kapsamı sağlar.

Bu seçici, özellikle CSS Modülü 4 ile gelen CSS Değişkenleri (--degisken-adi) tanımlamak için kullanılır.

Kök öğeye tanımlanan değişkenler, o sayfadaki tüm öğeler tarafından miras alınabilir ve kullanılabilir.

Global Temaların Merkezi: Sitenin ana renk paleti, temel yazı tipi boyutları ve geçiş süreleri gibi global ayarların tek bir merkezde toplanmasını sağlar.

Bu, tema değiştirme ( açık moddan koyu moda geçiş ) veya markanın renklerini tek bir yerden güncelleme işlemlerini son derece verimli ve hızlı hale getirir.

Belgenin Kökü ve Global Değişkenler :root

Teknik Düello: :root vs html

:root sözde sınıfı, belge ağacının en tepesindeki, diğer tüm elementlerin atası olan kök öğeyi seçer.

HTML belgelerinde bu her zaman <html> elementine denk gelir; ancak SVG veya XML gibi diğer belge türlerinde o belgenin kökünü ifade eder.

Çoğu geliştirici "Neden direkt html { ... } yazmıyoruz?" diye sorar bu durumda cevap ise, Özgüllük puanıdır.

html bir etiket seçicidir ve puanı düşüktür ( 0-0-1 ).

Ancak :root bir sözde sınıftır ve puanı daha yüksektir ( 0-1-0 ).

Bu teknik fark, özellikle tarayıcı varsayılanlarını veya CSS kütüphanelerini ezmek istediğinizde :root'u daha baskın ve güvenilir kılar.

CSS Değişkenlerinin (Variables) Evi

Modern web geliştirmede :root, sitenin "Konfigürasyon Dosyası" olarak görev yapar.

Renk paletleri (--ana-renk), font boyutları ve boşluk değerleri burada tanımlanır.

Kök elemente tanımlanan bir değişken, DOM ağacındaki tüm alt elementler tarafından erişilebilir olur.

Bu, sitenin temasını tek bir satırı değiştirerek baştan aşağı güncelleyebilmenizi sağlar.

Dinamik Tema Yönetimi (Dark Mode) JavaScript ile tema değiştirmek istediğinizde, genellikle müdahale edilen yer burasıdır.

JS, :root üzerindeki değişkenlerin değerini değiştirdiğinde, sayfadaki binlerce elementin rengi milisaniyeler içinde, performans kaybı olmadan güncellenir.

Tipografinin Kalbi: REM Birimi CSS'teki en popüler ölçü birimlerinden biri olan rem, adını ve gücünü doğrudan bu seçiciden alır.

1rem değeri, her zaman :root etiketine verilen font boyutuna eşittir.

Eğer :root { font-size: 16px; } tanımlarsanız, sitenizdeki tüm rem değerleri bu 16px üzerinden hesaplanır.

Bu sayede, sadece kökteki tek bir sayıyı değiştirerek tüm sitenin ölçeğini anında değiştirebilirsiniz.

SVG ve Bağımsız Dosyalar Eğer harici bir .svg dosyasını doğrudan tarayıcıda açarsanız, orada bir <html> etiketi yoktur; kök element <svg>'dir.

Bu durumda html { ... } yazarak verdiğiniz stiller çalışmaz, ancak :root { ... } her iki ortamda da sorunsuz çalışır.

Bu özellik, hem web sayfası içinde hem de bağımsız olarak kullanılabilen, taşınabilir grafik bileşenleri tasarlarken hayati önem taşır.

</>
Global ve Mantıksal Seçiciler Sözde Sınıflar :root() Pseudo Sınıf Örnek (++)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>:root Tema Değiştirici</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>

    <div class="container">
        <h2>🎨 Tema Değiştirme</h2>
        <p>
            Bu örnekte <strong>:root</strong> pseudo-class kullanılarak tema değişkenleri global olarak tanımlandı.
            Tek tıkla tüm stil değişir.
        </p>

        <button id="toggleTheme">🌙 Karanlık Moda Geç</button>
    </div>

    <script src="script.js?v=1.0.150"></script>

</body>

</html>
:root {
    --bg-color: #ffffff;
    --text-color: #111;
    --box-bg: rgba(255, 255, 255, 0.55);
    --btn-bg: #007bff;
    --btn-text: #fff;
    --shadow: rgba(0, 0, 0, 0.14);
    --radius: 14px;
    --transition: .35s ease;
}

:root.dark {
    --bg-color: #0f0f0f;
    --text-color: #ffffff;
    --box-bg: rgba(50, 50, 50, 0.4);
    --btn-bg: #ffd43b;
    --btn-text: #111;
    --shadow: rgba(255, 255, 255, 0.1);
}

body {
    font-family: "Segoe UI", sans-serif;
    background: var(--bg-color);
    color: var(--text-color);
    margin: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
}

.container {
    width: 450px;
    background: var(--box-bg);
    backdrop-filter: blur(20px);
    padding: 35px;
    border-radius: var(--radius);
    box-shadow: 0 8px 28px var(--shadow);
    text-align: center;
    transition: var(--transition);
}

.container h2 {
    margin: 0 0 18px;
    font-size: 22px;
    font-weight: 700;
}

.container p {
    font-size: 15px;
    line-height: 1.6;
    margin-bottom: 30px;
    opacity: 0.85;
}

button {
    width: 100%;
    padding: 14px;
    background: var(--btn-bg);
    color: var(--btn-text);
    border: none;
    border-radius: var(--radius);
    font-size: 16px;
    cursor: pointer;
    transition: var(--transition);
    font-weight: 600;
}

button:hover {
    transform: translateY(-2px);
    box-shadow: 0 5px 18px var(--shadow);
}

button:active {
    transform: scale(.97);
}
const btn = document.getElementById("toggleTheme");
btn.addEventListener("click", () => {
  document.documentElement.classList.toggle("dark");

  if (document.documentElement.classList.contains("dark")) {
    btn.textContent = "☀️ Aydınlık Moda Geç";
  } else {
    btn.textContent = "🌙 Karanlık Moda Geç";
  }
});

Akıllı Gruplama ve Kod Kısaltma :is()

Kod Tekrarını Önlemek (DRY Prensibi)

Modern CSS'in en büyük kolaylıklarından biri olan :is(), uzun ve tekrarlayan seçici zincirlerini kısaltan bir "sözdizimsel şekerdir".

Parantez içine yazılan seçici listesindeki herhangi biriyle eşleşen öğeleri seçer. Birden fazla karmaşık kuralı tek satırda birleştirmenizi sağlar.

Eskiden bir başlık stilini hem header, hem main hem de footer içindeki paragraflara uygulamak için şöyle yazardık:
header p, main p, footer p { ... }

:is() ile bu artık çok daha temiz: :is(header, main, footer) p { ... }

Kritik Detay: Öncelik (Specificity) Puanı Bu seçicinin en önemli teknik özelliği şudur: :is() sözde sınıfının öncelik puanı, parantez içindeki

en yüksek önceliğe sahip seçicinin puanına eşittir.

Yani listenizde basit bir etiket (p) ve güçlü bir ID ( #hero ) varsa, tarayıcı tüm grubu sanki bir ID seçicisiymiş gibi güçlü kabul eder.

Bu durum, bazen beklenmedik stil baskınlıklarına yol açabilir.

Hata Toleransı (Forgiving Selector) Normal CSS kurallarında, araya virgülle geçersiz bir seçici ( henüz desteklenmeyen bir özellik ) yazarsanız, tarayıcı tüm satırı iptal eder.

Ancak :is() "affedicidir".

İçindeki geçersiz parçaları görmezden gelir ve geçerli olanları çalıştırmaya devam eder.

</>
Global ve Mantıksal Seçiciler :is() Örnek (+)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>İs Pseudo Sınıf Örneği</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>
    <h2>:is() Örneği</h2>

    <div class="buttons">
        <button class="primary">Birincil</button>
        <button class="secondary">İkincil</button>
        <button class="danger">Tehlike</button>
        <button class="info">Bilgi</button>
    </div>

</body>

</html>
body {
    font-family: Arial, Helvetica, sans-serif;
    padding: 20px;
}

h2 {
    text-transform: uppercase;
    margin-bottom: 15px;
}

.buttons button {
    padding: 10px 16px;
    margin-right: 10px;
    border: none;
    border-radius: 6px;
    color: white;
    font-weight: 600;
    cursor: pointer;
    transition: .3s;
}

:is(.primary, .secondary, .info):hover {
    transform: scale(1.05);
    opacity: 0.85;
}

.primary {
    background: #4c84ff;
}

.secondary {
    background: #777;
}

.danger {
    background: #ff4d4d;
}

.info {
    background: #00bcd4;
}

.danger:hover {
    transform: scale(1.08);
    opacity: 0.9;
}

Sıfır Öncelik ve Kolay Ezilebilirlik :where()

Tek ve Büyük Fark: Sıfır Özgüllük

İşlevsel olarak tıpkı :is() gibi çalışır; parantez içindeki listedeki herhangi biriyle eşleşen öğeleri seçer ve gruplar.

:where() seçicisini benzersiz kılan özellik, içerisine ne yazarsanız yazın ( ister ID, ister binlerce sınıf ), tarayıcının ona verdiği öncelik puanının her zaman SIFIR (0) olmasıdır.

Bu, CSS'teki "Hayalet" seçicidir, varlığı vardır, seçim yapar ama stil savaşlarında hiçbir ağırlığı yoktur.

Kullanım Alanı: CSS Kütüphaneleri ve Resetler

Bir CSS kütüphanesi veya "Reset CSS" dosyası hazırlıyorsanız, yazdığınız kuralların kullanıcı tarafından kolayca ezilebilmesini istersiniz.

Eğer temel stilleri :where() ile yazarsanız, projeyi kullanan geliştirici sonradan basit bir sınıf ile sizin kurallarınızı ezebilir.

Böylece lanet olası !important kullanımına gerek kalmaz.

Özetle: Güçlü ve baskın olmasını istediğiniz gruplamalar için :is(), nazik ve kolay değişebilir varsayılanlar için :where() kullanılır.

</>
Global ve Mantıksal Seçiciler :where() Örnek (+)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Where Pseudo Sınıf Örneği</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>
    <h2>:where() Örneği</h2>

    <div class="cards">
        <div class="card primary">Birincil Kart</div>
        <div class="card secondary">İkincil Kart</div>
        <div class="card info">Bilgi Kart</div>
        <div class="card danger">Tehlike Kart</div>
    </div>

</body>

</html>
body {
    font-family: Arial, Helvetica, sans-serif;
    padding: 20px;
}

h2 {
    text-transform: uppercase;
    margin-bottom: 15px;
}

.cards {
    display: flex;
    gap: 12px;
}

.card {
    padding: 20px;
    border-radius: 8px;
    color: white;
    font-weight: 600;
    transition: .3s;
    cursor: pointer;
}

:where(.primary, .secondary, .info):hover {
    transform: scale(1.05);
    opacity: 0.85;
}

.primary {
    background: #4c84ff;
}

.secondary {
    background: #777;
}

.info {
    background: #00bcd4;
}

.danger {
    background: #ff4d4d;
}

.danger:hover {
    transform: scale(1.08);
    opacity: 0.9;
}

Şuana Kadar Ne Öğrendik?

Bu bölümde
  • Tam editör örnekleri; :root, :is, :where
  • Alt konu / not başlıkları
Öğrendiklerimiz
  • Kapsam: ”Global ve Mantıksal Seçiciler” (6. ana konu) — belge içi mantıksal hedefleme ve DRY
  • :root — kök öğe, CSS değişkenleri ve global tema merkezi
  • :is() — seçici listelerini güvenli biçimde gruplama
  • :where() — aynı gruplama, özgüllük sıfıra yakın (katman/kütüphane dostu)
Sırada Ne Var?
  • Sonraki bölüm: Medya ve Özel UI Durumları (7. ve son ana konu) — viewport ötesi bağlam
  • Top Layer, tam ekran ve PiP; :modal ile diyalog; medya :playing / :paused
  • Konular: :fullscreen:paused arası alt başlıklar (içerikte birden fazla editör örneği)
Seviye 5

Medya ve Özel UI Durumları Ekran Yönetimi ve Görüntüleme Modları

Tarayıcı ile İşletim Sistemi Arasındaki Köprü

Web sayfaları genellikle tarayıcı penceresinin (viewport) sınırları içinde yaşar. Ancak modern web, bu sınırları aşan deneyimler sunar.

Bir videonun tüm ekranı kaplaması veya bir sunumun dikkati dağıtacak her şeyden arınması gibi durumlar, standart CSS akışının dışına çıkar.

Bu kategori altındaki seçiciler, HTML elementlerinin sadece sayfa içindeki durumunu değil, işletim sistemi ve ekran donanımı ile olan ilişkisini hedefler.

Kullanıcı "Tam Ekran" moduna geçtiğinde veya bir videoyu "Resim içinde Resim" ( PiP ) moduna aldığında, elementin bağlamı ( context ) tamamen değişir.

CSS, bu bağlam değişikliğini anlık olarak yakalar ve geliştiriciye bir imkan sunar:

"Element şu an normal akışta değil, özel bir modda, ona göre stil ver".

Teknik Mimari: "Top Layer" (En Üst Katman)

Modern tarayıcılarda, sayfa akışından tamamen bağımsız, tüm "z-index" hesaplamalarının üzerinde yer alan özel bir katman vardır: Top Layer.

Bir element :fullscreen veya :picture-in-picture moduna geçtiğinde, tarayıcı onu DOM ağacındaki yerinden görsel olarak koparır ve bu en üst katmana taşır.

Bu sayede, elementin ebeveyninde overflow: hidden olsa bile, medya içeriği kesilmeden tüm ekranı kaplayabilir.

Güvenlik Kuralı: Kullanıcı Rızası (User Activation)

Bu özel durumlar, "Ayrıcalıklı Modlar" olarak kabul edilir.

Bir web sitesi, sayfa yüklenir yüklenmez sizi otomatik olarak Tam Ekran moduna alamaz.

Bu modların tetiklenmesi için mutlaka bir kullanıcı eylemi ( tıklama veya tuşa basma ) gerekir.

CSS, bu eylem gerçekleşip tarayıcı izin verdiğinde devreye girer; yani CSS burada "başlatan" değil, "yanıt veren" ( reactive ) taraftadır.

Odaklanma ve İmmersive Deneyim :fullscreen

Görsel Dönüşüm İhtiyacı

:fullscreen sözde sınıfı, tarayıcının "Tam Ekran API'si" tarafından tetiklenen ve kullanıcının tüm monitörünü kaplayan elementi hedefler.

Bu durum sadece videolar için değil; oyunlar ( canvas ), sunumlar, haritalar veya tam ekran gösterilmek istenen herhangi bir div için geçerlidir.

Bir element normal sayfadayken kenarlıklara, gölgelere veya yuvarlak köşelere ( border-radius ) sahip olabilir.

Ancak tam ekran moduna geçtiğinde bu dekoratif detaylar genellikle istenmez bunun yerine ekranın köşelerini tam doldurması beklenir.

:fullscreen seçicisi ile, element tam ekrana geçtiği anda kenarlıkları kaldırabilir, arka plan rengini değiştirebilir veya yazıları devasa boyutlara getirebilirsiniz.

Gizli Kahraman: ::backdrop

Tam ekrana geçen bir görselin en boy oranı ( aspect ratio ) ekranla uyuşmazsa ne olur? Kenarlarda boşluklar kalır.

İşte bu boşlukları (arkadaki siyah perdeyi) stilize etmek için ::backdrop sözde öğesi kullanılır.

Bu, :fullscreen ile birlikte çalışan ve tam ekran öğesinin hemen arkasında yer alan sanal bir katmandır.

Teknik Tuzak: Kaybolan Kaydırma Çubukları

Bir web sayfasını aşağı kaydırmak tarayıcının doğal davranışıdır, ancak özel bir div elementini tam ekran yaptığınızda, o element artık sayfanın kaydırma özelliklerini miras almaz.

Eğer tam ekran yaptığınız kutunun içinde çok fazla metin varsa ve taşma yönetimini yapmadıysanız, kullanıcı içeriğin devamını göremez.

Bu yüzden :fullscreen bloğu içine mutlaka overflow-y: auto; ekleyerek, gerektiğinde kendi kaydırma çubuğunu oluşturmasını sağlamalısınız.

Backdrop ile "Glassmorphism" Etkisi

::backdrop sadece siyah bir perde olmak zorunda değildir.

Eğer sayfanızda renkli bir tasarım varsa, tam ekran modunda arkadaki sayfayı tamamen gizlemek yerine,

::backdrop { background: rgba(0,0,0,0.8); backdrop-filter: blur(10px); } kullanarak arkadaki içeriği buzlu cam arkasındaymış gibi flu gösterebilirsiniz.

Bu, kullanıcının "Hala aynı sitedeyim, sadece odaklandım" hissini korumasını sağlayan modern ve şık bir tekniktir.

</>
Medya ve Özel UI Durumları Sözde Sınıflar :fullscreen Pseudo Sınıf Örnek (++)
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>
    <div class="fullscreen-wrapper" id="fullscreenBox">
        <header>
            <h2>📺 Fullscreen Modu</h2>
            <p class="subtitle">Bu kutuyu tam ekran yapabilir veya çıkabilirsiniz.</p>
        </header>

        <div class="content">
            <p>
                Fullscreen modunda arka plan, tipografi ve layout değişecektir.<br>
                Bu sayfa modern CSS + JavaScript ile tasarlandı.
            </p>
        </div>

        <button id="fullscreenBtn" class="toggle-fullscreen-btn">
            ⛶ Tam Ekran Aç
        </button>
    </div>



    <script src="script.js?v=1.0.150"></script>

</body>

</html>
body {
    background: linear-gradient(135deg, #1e1e2f, #13131f);
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    font-family: 'Segoe UI', Tahoma, sans-serif;
    margin: 0;
    padding: 20px;
    color: #eee;
}

.fullscreen-wrapper {
    width: 90%;
    max-width: 600px;
    padding: 30px;
    border-radius: 16px;
    background: rgba(255, 255, 255, 0.07);
    backdrop-filter: blur(12px);
    border: 1px solid rgba(255, 255, 255, 0.08);
    box-shadow: 0 15px 40px rgba(0, 0, 0, 0.4);
    transition: .4s ease;
    text-align: center;
}

.fullscreen-wrapper header h2 {
    margin: 0;
    font-size: 1.8rem;
    font-weight: 600;
}

.subtitle {
    opacity: 0.7;
    font-size: 0.9rem;
    margin-top: 4px;
}

.content {
    margin: 20px 0;
    line-height: 1.6;
    font-size: 1.05rem;
    opacity: 0.9;
}

.toggle-fullscreen-btn {
    background: #00e5ff;
    border: none;
    color: #000;
    font-weight: bold;
    padding: 14px 24px;
    font-size: 1rem;
    border-radius: 10px;
    cursor: pointer;
    transition: 0.3s ease;
}

.toggle-fullscreen-btn:hover {
    transform: scale(1.05);
    background: #53f0ff;
}

#fullscreenBox:fullscreen {
    background: #00e5ff;
    color: #111;
    box-shadow: none;
    border-radius: 0;
    width: 100vw;
    height: 100vh;
    padding: 50px;
    justify-content: center;
    align-items: center;
    display: flex;
    flex-direction: column;
    font-size: 1.3rem;
}
const box = document.getElementById("fullscreenBox");
const btn = document.getElementById("fullscreenBtn");

btn.addEventListener("click", async () => {
  if (!document.fullscreenElement) {
    await box.requestFullscreen();
    btn.textContent = "⤫ Tam Ekrandan Çık";
    btn.style.background = "#ff4f63";
  } else {
    await document.exitFullscreen();
    btn.textContent = "⛶ Tam Ekran Aç";
    btn.style.background = "#00e5ff";
  }
});

Çoklu Görev ve Yüzen Pencere :picture-in-picture

Neyi Hedefler? (Kaynak vs Pencere)

Bu sözde sınıf, kullanıcının bir videoyu ana sayfadan ayırıp, ekranın köşesinde yüzen küçük bir pencere ( PiP - Picture in Picture ) olarak izlemeye başladığı durumu temsil eder.

Teknik Detay: CSS ile o an havada süzülen PiP penceresinin içini stilize edemezsiniz (bu işletim sistemi kontrolündedir).

Bu seçici, videonun sayfada geride bıraktığı orijinal elementi hedefler.

Kullanım Senaryosu: Yer Tutucu (Placeholder) Video PiP moduna geçtiğinde, sayfadaki orijinal video etiketi genellikle siyah veya boş görünür.

:picture-in-picture kullanarak, sayfada kalan bu boş alana "Video şu an PiP modunda oynatılıyor" yazan şık bir arka plan görseli veya bulanıklaştırma efekti ( backdrop-filter ) ekleyebilirsiniz.

Bu, kullanıcıya videonun kaybolmadığını, sadece yer değiştirdiğini hatırlatan harika bir UX dokunuşudur.

Kritik UX: Düzen Kaymasını (CLS) Önlemek Bir video PiP moduna geçtiğinde, eğer CSS ile müdahale edilmezse bazı tarayıcılar orijinal video elementini tamamen gizleyebilir veya boyutunu sıfırlayabilir.

Bu durum, videonun altındaki metinlerin aniden yukarı zıplamasına neden olur ve okuma deneyimini bozar.

:picture-in-picture seçicisi ile orijinal video alanına sabit bir genişlik/yükseklik veya bir "iskelet ekran" arkaplanı atayarak sayfa düzeninin sabit kalmasını garantilersiniz.

Sözde Elementlerle Sinerji (::after) "Video oynatılıyor" mesajını yazmak için HTML'e ekstra bir etiket eklemenize gerek yoktur.

video:picture-in-picture::after kombinasyonunu kullanarak, doğrudan CSS üzerinden boş kalan alana bir mesaj

( content: "Video köşede oynuyor ↘"; ) ve bir ikon yerleştirebilirsiniz.

Bu, CSS'in gücünü birleştirerek kullanmanın harika bir örneğidir.

</>
Medya ve Özel UI Durumları Sözde Sınıflar :picture-in-picture Pseudo Sınıf Örnek (++)
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>:picture-inpicture Pseudo Sınıf Örneği</title>
</head>

<body>

    <div class="modern-pip-card">
        <div class="card-header">
            <div class="icon-box">
                <i class="fas fa-layer-group"></i>
            </div>
            <div class="header-text">
                <h3>Yüzen Pencere Deneyimi</h3>
                <p>Videoyu sayfadan ayırıp serbestçe gezinin.</p>
            </div>
        </div>

        <div class="video-frame">
            <div class="pip-overlay">
                <div class="overlay-content">
                    <i class="fas fa-external-link-alt"></i>
                    <span>Video şu an dışarıda oynatılıyor</span>
                </div>
            </div>

            <video id="demoVideo" controls>
                <source src="" type="video/mp4">
                Tarayıcınız video etiketini desteklemiyor.
            </video>
        </div>

        <button id="togglePipBtn" class="action-btn">
            <i class="fas fa-images"></i>
            <span>Pencereyi Ayır</span>
        </button>
    </div>

    <script src="script.js?v=1.0.150"></script>
</body>

</html>
.modern-pip-card {
    background: #ffffff;
    border-radius: 20px;
    padding: 24px;
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.08);
    max-width: 550px;
    width: 100%;
    margin: 20px auto;
    font-family: 'Segoe UI', system-ui, sans-serif;
    border: 1px solid rgba(0, 0, 0, 0.05);
}

.card-header {
    display: flex;
    align-items: center;
    gap: 16px;
    margin-bottom: 24px;
    text-align: left;
}

.icon-box {
    width: 48px;
    height: 48px;
    background: rgba(99, 102, 241, 0.1);
    color: #6366f1;
    border-radius: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 20px;
}

.header-text h3 {
    margin: 0;
    font-size: 18px;
    color: #1e293b;
    font-weight: 700;
}

.header-text p {
    margin: 4px 0 0 0;
    font-size: 14px;
    color: #64748b;
}

/* Video Çerçevesi */
.video-frame {
    position: relative;
    border-radius: 16px;
    overflow: hidden;
    background: #0f172a;
    /* Video yokken şık dursun */
    aspect-ratio: 16/9;
    box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}

video {
    width: 100%;
    height: 100%;
    display: block;
    object-fit: cover;
    transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}

/* --- PIP AKTİF OLDUĞUNDA (SİHİRLİ KISIM) --- */
video:picture-in-picture {
    opacity: 0;
    /* Videoyu tamamen görünmez yap, arkadaki mesajı göster */
}

/* Arka Plan Mesajı */
.pip-overlay {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #f8fafc;
    border: 2px dashed #cbd5e1;
    border-radius: 16px;
    opacity: 0;
    transition: opacity 0.3s ease;
    z-index: 0;
}

.overlay-content {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    color: #64748b;
    font-weight: 600;
}

.overlay-content i {
    font-size: 24px;
    color: #94a3b8;
}

/* Parent Selector (:has) ile mesajı gösterme */
.video-frame:has(video:picture-in-picture) .pip-overlay {
    opacity: 1;
    z-index: 10;
}

/* Modern Buton */
.action-btn {
    margin-top: 24px;
    width: 100%;
    padding: 14px;
    background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
    color: white;
    border: none;
    border-radius: 12px;
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    transition: transform 0.2s, box-shadow 0.2s;
}

.action-btn:hover {
    transform: translateY(-2px);
    box-shadow: 0 10px 20px -10px rgba(99, 102, 241, 0.5);
}

.action-btn:active {
    transform: translateY(0);
}

.action-btn:disabled {
    background: #e2e8f0;
    color: #94a3b8;
    cursor: not-allowed;
    transform: none;
    box-shadow: none;
}
const video = document.getElementById("demoVideo");
const btn = document.getElementById("togglePipBtn");
const btnText = btn.querySelector("span");

// PiP Desteği Kontrolü
if ("pictureInPictureEnabled" in document) {
  btn.addEventListener("click", async () => {
    // Eğer zaten PiP modundaysa çık
    if (document.pictureInPictureElement) {
      await document.exitPictureInPicture();
    } else {
      // Video hazır değilse uyar (Siyah ekran kalmasın diye)
      if (video.readyState === 0) {
        alert(
          "Lütfen videonun yüklenmesini bekleyin veya oynat butonuna basın."
        );
        return;
      }
      // PiP modunu başlat
      try {
        await video.requestPictureInPicture();
      } catch (error) {
        console.error(error);
      }
    }
  });

  // Olayları Dinle ve Butonu Güncelle
  video.addEventListener("enterpictureinpicture", () => {
    btnText.innerText = "Yüzen Pencereyi Kapat";
    btn.style.background = "#334155";
  });

  video.addEventListener("leavepictureinpicture", () => {
    btnText.innerText = "Pencereyi Ayır";
    btn.style.background = "";
  });
} else {
  btn.disabled = true;
  btnText.innerText = "Tarayıcınız Desteklemiyor";
}

Kısıtlanmış Odak ve Modallık :modal

Genel Bakış

:modal sözde sınıfı, sayfanın geri kalanıyla olan etkileşimi tamamen kesen ( bloke eden ) ve kullanıcıyı sadece kendisiyle etkileşime girmeye zorlayan elementleri temsil eder.

Web standartlarındaki karşılığı genellikle <dialog> elementidir; ancak bu elementin JavaScript ile .showModal() metodu kullanılarak açılmış olması gerekir.

Teknik Devrim: "Inert" (Eylemsizlik) Durumu

Bu sınıf devreye girdiğinde, tarayıcı arka planda kalan her şeyi ( butonlar, linkler, metin seçimleri ) "Inert" yani ölü/tepkisiz duruma getirir.

Bu, erişilebilirlik için hayati önem taşır.

Klavye kullanan bir ziyaretçi TAB tuşuna bastığında, odak asla modal penceresinin dışına çıkmaz, arkadaki sayfa kazara tıklanamaz.

Z-Index Savaşlarının Sonu Eskiden bir modal penceresini en üste çıkarmak için z-index: 99999; gibi rastgele ve yüksek sayılar verilirdi.

:modal durumundaki bir element, tarayıcının özel Top Layer alanına taşınır.

Bu sayede, modal penceresi html yapısının ne kadar derininde olursa olsun ( iç içe 10 div olsa bile ), görsel olarak her zaman en üstte, her şeyin üzerinde yer alır.

Backdrop ile Sahne Işığı Tıpkı :fullscreen'de olduğu gibi, :modal da ::backdrop sözde öğesiyle birlikte çalışır.

Modal açıldığında sayfanın geri kalanını karartmak, bulanıklaştırmak veya renklendirmek için bu ikiliyi kullanırsınız.

(dialog:modal::backdrop { background: rgba(0,0,0,0.5); })

</>
Medya ve Özel UI Durumları Sözde Sınıflar :modal Pseudo Sınıf Örnek (++)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>:modal Pseudo Class Örneği</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>

    <button id="open">Modal Aç</button>

    <dialog id="myModal">
        <div class="modal-content">
            <h2>Modern Modal</h2>
            <p>Bu :modal pseudo sınıfı ile geliştirilmiş modern bir örnektir.</p>
            <button id="close">Kapat</button>
        </div>
    </dialog>

    <script src="script.js?v=1.0.150"></script>

</body>

</html>
* {
    margin: 0;
    box-sizing: border-box;
    font-family: "Segoe UI", sans-serif;
}

body {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    background: linear-gradient(135deg, #1f1c2c, #928dab);
}

button {
    padding: 12px 24px;
    border: none;
    background: #ffffff15;
    color: white;
    border-radius: 8px;
    backdrop-filter: blur(5px);
    cursor: pointer;
    transition: 0.3s;
}

button:hover {
    background: #ffffff30;
}

dialog {
    padding: 0;
    border: none;
    border-radius: 18px;
    background: transparent;
    opacity: 0;
    transform: translateY(-20px) scale(0.8);
    transition: all 0.35s ease, opacity 0.3s;
}

dialog .modal-content {
    padding: 30px;
    background: rgba(255, 255, 255, 0.12);
    border-radius: 18px;
    backdrop-filter: blur(14px) saturate(180%);
    border: 1px solid rgba(255, 255, 255, 0.25);
    color: #fff;
    min-width: 320px;
    text-align: center;
}

dialog:modal {
    opacity: 1;
    transform: translateY(0) scale(1);
}

:modal::backdrop {
    background: rgba(0, 0, 0, 0.55);
    backdrop-filter: blur(6px);
    animation: fadeIn 0.4s ease;
}

@keyframes fadeIn {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}
const modal = document.getElementById("myModal");
document.getElementById("open").onclick = () => modal.showModal();
document.getElementById("close").onclick = () => modal.close();

Medya Akışı ve Oynatma Durumları :playing & :paused

JavaScript Olay Dinleyicilerine (Event Listeners) Veda

Bu iki sözde sınıf, sayfadaki <video> veya <audio> elementlerinin "kalp atışlarını" dinler.

Medya o an akıyor mu (:playing), yoksa durmuş/beklemede mi (:paused)? CSS artık bu sorunun cevabına göre anlık stil değişiklikleri yapabilir.

Eskiden, bir video durdurulduğunda üzerine "Play" ikonu çıkarmak veya video oynarken arka planı karartmak için JavaScript ile play ve pause olaylarını dinleyip, elemente .is-playing gibi sınıflar ekleyip çıkarmamız gerekirdi.

Bu yeni seçiciler sayesinde, tarayıcı bu durumu otomatik algılar.

Örneğin: video:paused + .play-icon { display: block; } diyerek, video durduğu anda oynatma butonunu görünür kılabilirsiniz.

Kullanım Senaryosu: Görsel Ekolayzer Bir ses dosyası ( audio ) oynatılırken hareket eden çubuklar (animasyonlu ekolayzer) hayal edin.

Müzik durduğunda bu animasyonun da durması gerekir.

audio:paused + .equalizer seçicisine animation-play-state: paused; vererek, CSS animasyonunu medya durumuyla tam senkronize edebilirsiniz.

Gelecek Teknolojisi (Bleeding Edge) Bu seçiciler CSS Selectors Level 4 spesifikasyonunun bir parçasıdır ve "en yeni" özellikler arasındadır.

Henüz tüm tarayıcılarda tam standart desteği olmayabilir, ancak modern web'in medya yönetiminde gideceği yönün en net göstergesidir.

Performans Farkı: Main Thread'i Özgür Bırakmak

JavaScript ile bir videonun durumunu dinlemek ( event listener ), tarayıcının ana işlem hattını meşgul eder.

Sitenizde ağır işlemler varsa, JavaScript'in " Video durdu, ikonu göster " emrini vermesi milisaniyelerce gecikebilir ve bu da arayüzde takılma hissi yaratır.

:paused gibi CSS seçicileri ise doğrudan tarayıcının görüntüleme motoru tarafından işlenir.

Bu, site ne kadar yoğun olursa olsun, ikonun videoyla "aynı karede" tepki vermesini sağlar.

Tasarım İpucu: Ambient (Ortam) Videoları

Modern sitelerin "Hero" bölümlerinde sıkça sessiz, döngüsel arka plan videoları kullanılır.

Eğer tarayıcı "Güç Tasarrufu Modu" nedeniyle bu videoyu otomatik durdurursa, sayfa donuk görünebilir.

video:paused kullanarak, video duraklatıldığı anda devreye giren şık bir statik görsel veya bir renk filtresi ekleyerek tasarımın canlılığını koruyabilirsiniz.

</>
Medya ve Özel UI Durumları Sözde Sınıflar :playing and :paused Pseudo Sınıf Örnek (++)
<!DOCTYPE html>
<html lang="tr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>:playing and :paused Pseudo Class Örneği</title>
    <link rel="stylesheet" href="style.css?v=1.0.150">
</head>

<body>

    <div class="animation-container">
        <div id="box" class="box"></div>
        <button id="toggleBtn" class="control-btn"></button>
    </div>

    <script src="script.js?v=1.0.150"></script>

</body>

</html>
body {
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
    background: #111623;
    font-family: Arial, sans-serif;
}

.animation-container {
    position: relative;
}

.box {
    width: 120px;
    height: 120px;
    background: linear-gradient(135deg, #4F46E5, #06B6D4);
    border-radius: 16px;
    animation: spin 2s linear infinite;
    border: 5px solid #555;
    transition: 0.4s;
}

.box:playing {
    border-color: #2ecc71;
    box-shadow: 0 0 22px rgba(46, 204, 113, 0.6);
}

.box:paused {
    border-color: #e74c3c;
    opacity: 0.6;
    box-shadow: none;
}

.control-btn {
    position: absolute;
    bottom: -100px;
    left: 30px;
    width: 60px;
    height: 60px;
    border: none;
    border-radius: 50%;
    cursor: pointer;
    background: rgba(255, 255, 255, 0.15);
    backdrop-filter: blur(10px);
    transition: 0.3s;
    border: 1px solid #fff;
}

.control-btn:hover {
    transform: scale(1.1);
}

.control-btn::before {
    content: "▶";
    font-size: 30px;
    color: white;
    display: flex;
    justify-content: center;
    align-items: center;
}

.box:playing+.control-btn::before {
    content: "⏸";
}

@keyframes spin {
    from {
        transform: rotate(0);
    }

    to {
        transform: rotate(360deg);
    }
}
const box = document.getElementById("box");
const btn = document.getElementById("toggleBtn");

let running = true;

btn.addEventListener("click", () => {
  running = !running;
  box.style.animationPlayState = running ? "running" : "paused";
});

Şuana Kadar Ne Öğrendik?

Bu bölümde
  • Tam editör örnekleri; dört alt başlıkta (bazılarında birden fazla örnek)
  • Alt konu / not başlıkları
Öğrendiklerimiz
  • Kapsam: „Medya ve Özel UI Durumları” (7. ana konu) — tarayıcı/OS/ekran bağlamı; Top Layer, kullanıcı rızası
  • :fullscreen ve ::backdrop; :picture-in-picture (sayfadaki yer tutucu, CLS)
  • :modal<dialog> showModal, odak tuzağı, ::backdrop
  • :playing ve :paused<video> / <audio> akış durumu

Tamamlandı. Bu sayfadaki pseudo-class anlatımı: dinamik etkileşimden yapısal ve form seçicilerine, dil/yön ve global mantıksal seçicilerden bu medya ve özel UI bölümüne kadar tüm ana başlıklar işlendi.