WCAG 2.1.2 · A Seviyesi · EN 301 549 9.2.1.2

Klavye Tuzağı Olmaması

Odak bir bileşene klavyeyle girebiliyorsa, klavyeyle ondan çıkabilmesini de ister.

Kısaca

Klavye kullanıcısı bir bileşene Tab ile girer ve sonra çıkamaz. Geri gidemez, ileri de gidemez. Tek çıkış yolu, sahip olmadığı bir fare ya da sayfayı yeniden yükleyip işini kaybetmektir.

Bu kriter, klavye odağı bir klavye arayüzüyle bir bileşene taşınabiliyorsa odağın yine yalnızca klavye arayüzüyle ondan uzaklaştırılabilmesini ister. Bunun için ok tuşlarından, Tab'dan ya da standart çıkış yöntemlerinden fazlası gerekiyorsa kullanıcıya nasıl yapılacağı söylenmelidir.

Neleri kapsar?

  • Kural: Odağın gidebildiği her yerden odak yalnızca klavyeyle çıkabilir.
  • Tipik tuzaklar: Gömülü oynatıcılar, zengin metin düzenleyicileri, üçüncü taraf bileşenleri, iframe'ler, haritalar ve eklentiler.
  • Kipli iletişim kutuları: Açık bir kipli iletişim kutusunda odağı içeride tutmak, Escape ya da görünür bir kapatma düğmesi çıkışa izin veriyorsa tuzak sayılmaz.
  • Standart olmayan çıkışlar: Bir bileşenden çıkmak için alışılmadık bir tuş gerekiyorsa kullanıcıya girişte ya da girerken söylenmelidir.
  • Tüm sayfa: Başka kaynaklardan gelen içerik dahil sayfadaki tüm içerik için geçerlidir.
  • Kapsam dışı notlar: Kontrollerin işletilebilirliği 2.1.1'dir. Odağın kendiliğinden beklenmedik biçimde taşınması 3.2.1 kapsamındadır.

Kimleri etkiler?

Takılıp çıkması gereken yalnızca klavye ya da ekran okuyucu kullanıcıları. Anahtar ya da ses denetimi kullananlar. İşlerini kaybedebilir ya da devam edemez hâle gelebilirler.

EAA ve EN 301 549'da

Avrupa Erişilebilirlik Yasası (Direktif (AB) 2019/882) 28 Haziran 2025'ten sonra piyasaya sunulan kapsamdaki ürün ve hizmetler için geçerlidir. Yasanın 47. gerekçesi web siteleri ve mobil uygulamalar için dört ilkeyi sayar: algılanabilirlik, işletilebilirlik, anlaşılabilirlik ve sağlamlık. Her bileşenden çıkış yolu, "işletilebilirlik" ilkesinin parçasıdır.

Teknik karşılığı EN 301 549 standardında bulunur. Standart, WCAG 2.1.2'i atıfla alır ve ortama göre ayrı maddelere dönüştürür.

WCAG 2.1.2'in EN 301 549'daki karşılıkları
MaddeOrtamNe ister?
9.2.1.2Web sayfalarıWeb içeriğinin WCAG 2.1.2 kriterini karşılamasını ister.
10.2.1.2Web dışı dokümanlar (PDF, Office dosyaları)Standardın uyguladığı hâllerde dokümanların klavye odağını tuzağa düşürmemesini ister.
11.2.1.2Web dışı yazılım (yerel mobil uygulamalar)Yazılımın klavye odağını tuzağa düşürmemesini ister.

Kriterin web dışı dokümanlara uygulanıp uygulanmadığı ve nasıl uygulandığı standardın 10. maddesinde belirtilir. Madde numaraları EN 301 549'un "9. + WCAG numarası" düzenine göredir. V3.2.1'de yazılım maddesi, açık ve kapalı işlevsellik için ayrı alt maddelere bölünmüştür. Kaynak gösterirken tam numaraları standarttan kontrol edin.

Standart sürümü: EN 301 549 V4.1.1 (Eylül 2026), WCAG 2.2'yi esas alan ve EAA için hazırlanan ilk sürümdür. Henüz AB Resmî Gazetesi'nde atıf almamıştır; bu nedenle EAA gereksinimlerini karşılamanın gönüllü teknik yolu olarak görülmelidir. Atıf yapıldığında EAA ile ilgili uygunluk karinesi sağlayacaktır. 2.1.2 kriterinin metni WCAG 2.1 ve 2.2'de aynıdır.

EAA bağlamında dikkat: Yasanın Madde 2/4 hükmü bazı içerikleri gereksinimlerin dışında bırakır; örneğin 28 Haziran 2025'ten önce yayımlanmış ofis dosya biçimleri ve bu tarihten sonra güncellenmeyen arşivler. Bu tarihten sonra yayımladığınız ya da değiştirdiğiniz içerik bu istisnaların kapsamında değildir.

Directive (EU) 2019/882, EUR-Lex, İngilizce, yeni sekmede açılır

Web için kod örnekleri

1. Tab'ı yutan bir bileşen

Çıkış olmadan Tab'ın varsayılan davranışını engellemek kullanıcıyı sıkıştırır.

Hatalı
duzenleyici.addEventListener("keydown", e => {
  if (e.key === "Tab") e.preventDefault(); // sekme ekler, çıkış yok
});
Doğru
duzenleyici.addEventListener("keydown", e => {
  if (e.key === "Escape") { duzenleyici.dataset.tuzak = "kapali"; } // Esc, sonra Tab çıkarır
  if (e.key === "Tab" && duzenleyici.dataset.tuzak !== "kapali") {
    e.preventDefault(); sekmeEkle();
  }
});
// Belgeleyin: "Düzenleyiciden çıkmak için Escape, sonra Tab'a basın."

2. Kapatılabilen bir kipli iletişim kutusu

Yerel bir dialog açıkken odağı içeride tutar ve Escape ile kapanır.

Hatalı
<div class="modal">…</div> <!-- odak döner ve kapatma tuşu yok -->
Doğru
<dialog id="ayarlar" aria-labelledby="b">
  <h2 id="b">Ayarlar</h2>
  …
  <button type="button" onclick="this.closest('dialog').close()">Kapat</button>
</dialog>
<script>ayarlar.showModal(); // Escape kapatır</script>

3. Gömülü içerik

Üçüncü taraf oynatıcılar ve bileşenler odağı tuzağa düşürebilir. Test edin ve tuzak kurmayanları seçin.

Hatalı
<iframe src="https://widget.example/sohbet" title="Sohbet"></iframe> <!-- Tab'ı tuzağa düşürür -->
Doğru
<iframe src="https://widget.example/sohbet" title="Sohbet"></iframe>
<!-- Testten sonra: Tab girer ve çıkar; çıkmıyorsa bileşeni değiştirin ya da yenisini seçin -->

4. Çıkışı olmayan odak döngüsü

Her Tab'ta odağı ilk öğeye döndüren bir betik sonsuza dek döner.

Hatalı
son.addEventListener("keydown", e => {
  if (e.key === "Tab" && !e.shiftKey) { e.preventDefault(); ilk.focus(); }
});
Doğru
// Döngüyü yalnızca kapatma düğmesi olan ve Escape'e yanıt veren açık bir kipli iletişim kutusunda kurun

5. Sayfanın üzerinde açılan bir panel

Kipli olmayan bir panel açıldığında kullanıcıların Tab ile ondan çıkmasına ve Escape ile kapatmasına izin verin.

Hatalı
panel.addEventListener("focusout", () => panel.querySelector("input").focus());
Doğru
panel.addEventListener("keydown", e => {
  if (e.key === "Escape") { panel.hidden = true; tetikleyici.focus(); }
});

6. İletişim kutusu açıkken arka plan içeriği

Odağın olması gereken yerde kalması için kipli pencerenin arkasındaki sayfayı etkisiz yapın.

Hatalı
<main>…</main> <!-- iletişim kutusunun arkasında hâlâ Tab ile erişilebilir -->
Doğru
<main inert>…</main> <!-- iletişim kutusu açıkken -->

Mobil için kod örnekleri

Yerel uygulamalar özel görünümlerde ve katmanlarda odağı tuzağa düşürebilir. Her katmanın klavye ya da anahtarla kapatılabildiğinden emin olun.

iOS (SwiftUI)

import SwiftUI

struct AyarlarSayfasi: View {
    @Environment(\.dismiss) private var dismiss

    var body: some View {
        NavigationStack {
            Form { /* kontroller */ }
                .navigationTitle("Ayarlar")
                .toolbar {
                    // Klavye ve VoiceOver ile çalışan görünür bir kapatma kontrolü
                    ToolbarItem(placement: .confirmationAction) {
                        Button("Bitti") { dismiss() }
                    }
                }
        }
        // Standart sayfalar donanım klavyesinde Escape ile de kapanır
    }
}

Android (Jetpack Compose)

import androidx.compose.material3.*
import androidx.compose.runtime.Composable

@Composable
fun AyarlarDialog(onDismiss: () -> Unit) {
    // AlertDialog, Geri/Escape ile kapanır ve açıkken odağı içeride tutar
    AlertDialog(
        onDismissRequest = onDismiss,
        title = { Text("Ayarlar") },
        text = { /* kontroller */ },
        confirmButton = {
            TextButton(onClick = onDismiss) { Text("Bitti") }
        }
    )
}

Nasıl test edilir?

  • Tüm sayfada Tab ile gezinin: Her kontrolde ileri ve geri gidin. Her zaman devam edebiliyor musunuz?
  • Her bileşene girin: Düzenleyicilere, oynatıcılara, haritalara, gömülü içeriğe ve menülere Tab ile girin. Klavyeyle çıkabiliyor musunuz?
  • Escape ve Tab'ı deneyin: Escape katmanları kapatıyor mu? Tab bileşenlerden çıkarıyor mu? Özel bir tuş gerekiyorsa açıklanmış mı?
  • İletişim kutularını test edin: Açık bir kipli iletişim kutusunda odak içeride kalıyor ve Escape ya da görünür bir düğmeyle kapatabiliyor musunuz?
  • Üçüncü taraf içeriği test edin: Sohbet bileşenleri, çerez bannerları, reklamlar ve video oynatıcılar sık rastlanan sorunlu öğelerdir.
  • Mobili kontrol edin: Donanım klavyesi ya da anahtarla her sayfadan ve katmandan çıkabiliyor musunuz?
  • Denetleyiciyi başlangıç olarak kullanın: Otomatik araçlar tuzakları tespit edemez. Bir kişi her bileşende Tab ile gezinmelidir.

Sık yapılan hatalar

  • Bir düzenleyicide Tab tuşunu yutmak: Klasik tuzak.
  • Kapatma tuşu olmayan kipli iletişim kutuları: Escape ve görünür bir kapatma düğmesi birlikte çalışmalıdır.
  • Odağı yakalayan üçüncü taraf bileşenleri: Eklemeden önce test edin.
  • Sınırsız odak döngüleri: Döngü yalnızca kapatılabilen bir kipli pencerede kabul edilebilir.
  • Çıkışı olmayan çerez ve tanıtım bannerları: Klavyeyle kapatılabilir olmalıdır.
  • Açıklanmayan çıkış tuşları: Özel bir tuş gerekiyorsa kullanıcılara söyleyin.
  • Odak kaybında odağı geri taşımak: Odağı geri çekmek kullanıcıların çıkmasını engeller.
  • Yalnızca fareyle test etmek: Tuzaklar fare kullanıcılarına görünmez.

Kaynaklar

Standart sürümü: EN 301 549 V4.1.1 (2026-09), WCAG 2.2. Bu sayfa bilgilendirme amaçlıdır ve hukuki tavsiye niteliği taşımaz; bağlayıcı metin için Avrupa Erişilebilirlik Yasası'nın (Direktif (AB) 2019/882) ve EN 301 549 standardının resmî metinlerini esas alın.

Corpowid, Gartner tarafından tanınan bir platformdur.

Corpowid, dijital erişilebilirlik alanındaki yenilikçi yaklaşımı ve performansı nedeniyle dünyanın önde gelen araştırma ve danışmanlık şirketlerinden biri olan Gartner tarafından takdir edilmiştir. Bu rozetler, yapay zeka destekli ve kapsayıcı web deneyimleri oluşturma konusundaki kararlılığımızı yansıtmaktadır.

Corpowid hakkında sorularınız mı var?

Bizimle iletişime geçin.

Size en kısa sürede geri dönüş sağlayacağız.