WCAG 2.1.1 · A Seviyesi

Klavye Erişimi

Sayfadaki veya uygulamadaki tüm işlevlerin fare ya da dokunma gerektirmeden, klavye veya platforma uygun eşdeğer giriş yöntemleriyle de kullanılabilmesini ister.

Kısaca

Birçok kullanıcı fare veya dokunmatik ekran kullanmaz; sayfayı klavyeyle, anahtar (switch) cihazıyla, ses komutuyla ya da ekran okuyucunun gezinme hareketleriyle kullanır. Bu araçların hepsi, arka planda klavye benzeri bir arayüze dayanır.

Bu kriter, işlevin kendisi bir yol çizmeyi gerektirmedikçe (örneğin serbest çizim) her işlemin klavyeyle de yapılabilmesini ister. Fareyle açılan her menü, tıklanan her düğme ve sürüklenen her öğe için klavyeyle çalışan bir yol bulunmalıdır.

Neleri kapsar?

  • Medya oynatıcılar: Oynat, duraklat, ses düzeyi, ileri-geri sarma ve kapatma denetimleri.
  • Açılır menüler: Menünün açılması, seçenekler arasında gezinme ve seçim yapma.
  • Diyalog kutuları ve açılır pencereler: İçinde gezinme, işlemleri çalıştırma ve kapatma.
  • Etkileşimle değişen bileşenler: Üzerine gelince veya tıklayınca açılan alt menüler, ipuçları ve ek içerikler.
  • Sürükle-bırak: Sürükleyerek yapılan sıralama, taşıma ve dosya yükleme işlemleri için klavye alternatifi.
  • Kapsam dışı notlar: Odağın bir bileşende sıkışıp kalması bir sonraki kriterin (Klavye Kilitlenmesinin Olmaması), odağın gezdiği sıra ise Odaklama Sırası kriterinin konusudur.

Kimleri etkiler?

Kör kullanıcılar ekranı göremedikleri için fare kullanmaz, tamamen klavye ve ekran okuyucu ile çalışır. El titremesi, felç, kas hastalıkları veya uzuv kaybı gibi motor engelleri olan kişiler klavye, anahtar cihazları, ağızla kullanılan çubuklar ya da ses komutu kullanır. Bu yardımcı teknolojilerin tümü, işlevlere klavye üzerinden erişilebilmesine bağlıdır. Hızlı çalışmak için klavyeyi tercih eden kullanıcılar da bu kriterden yararlanır.

Kontrol listesinde

Bu kriter, Bakanlığın A Seviyesi Kontrol Listesi'nde 56–68 numaralı soruları kapsar. Yönlendirme soruları sayfada ilgili içerik olup olmadığını belirler; yoksa liste sizi sonraki soruya geçirir. Aşağıdaki açıklamalar sorulardan alıntı değil, özetidir. Soruların tam metni için resmî listeye bakın.

BK 10 kapsamındaki sorular
SoruTürüNe kontrol eder?
56YönlendirmeKlavyeyle veya eşdeğer giriş yöntemleriyle kullanılması gereken etkileşimli bileşen olup olmadığını sorar.
57YönlendirmeSayfada video, ses veya benzeri bir medya oynatıcı olup olmadığını sorar.
58★ ZorunluOynatıcının tüm denetimlerinin klavyeyle veya eşdeğer yöntemlerle kullanılıp kapatılabildiğini kontrol eder.
59YönlendirmeSayfada açılır menü olup olmadığını sorar.
60★ ZorunluAçılır menünün klavyeyle açılabildiğini, seçenekler arasında gezinilip seçim yapılabildiğini kontrol eder.
61YönlendirmeSayfada diyalog kutusu olup olmadığını sorar.
62★ ZorunluDiyalog kutusunun klavyeyle kullanılabildiğini ve kapatılabildiğini kontrol eder.
63YönlendirmeKendiliğinden açılan pencere (pop-up) olup olmadığını sorar.
64★ ZorunluKendiliğinden açılan pencerenin odak alabildiğini, içinde gezinilebildiğini ve klavyeyle kapatılabildiğini kontrol eder.
65YönlendirmeÜzerine gelme, odaklanma, dokunma veya tıklama ile durumu değişen ya da ek içerik gösteren bileşen olup olmadığını sorar.
66★ ZorunluBu bileşenlerin ve ortaya çıkan içeriğin klavyeyle de odaklanılabilir ve kullanılabilir olduğunu kontrol eder.
67YönlendirmeSayfada sürükle-bırak işlevi olup olmadığını sorar.
68★ ZorunluSürükle-bırak ile yapılan işlemin klavyeyle veya eşdeğer bir yöntemle de yapılabildiğini kontrol eder.

Resmî kontrol listesini indirin (PDF), yeni sekmede açılır

Web için kod örnekleri

1. Tıklanabilir div yerine gerçek düğme

div veya span klavyeyle odak almaz ve Enter/Space ile çalışmaz. Yerleşik button bunların hepsini kendiliğinden sağlar.

Hatalı
<div class="oynat" onclick="videoyuOynat()">
  <img src="/ikon/oynat.svg" alt="">
</div>
Doğru
<button type="button" class="oynat"
        onclick="videoyuOynat()" aria-label="Oynat">
  <img src="/ikon/oynat.svg" alt="">
</button>

2. Medya oynatıcı denetimleri

Yerleşik controls özniteliği klavyeyle çalışan denetimler sunar. Özel bir oynatıcı yazıyorsanız her denetim bir button veya input type="range" olmalıdır.

<div class="oynatici">
  <video id="video" src="/video/vergi-rehberi.mp4"></video>
  <button type="button" id="oynat-dugme">Oynat</button>
  <label for="ses">Ses düzeyi</label>
  <input type="range" id="ses" min="0" max="1" step="0.1" value="1">
  <button type="button" id="geri-sar">10 saniye geri sar</button>
</div>

<script>
  const video = document.getElementById("video");
  const oynat = document.getElementById("oynat-dugme");
  oynat.addEventListener("click", () => {
    video.paused ? video.play() : video.pause();
    oynat.textContent = video.paused ? "Oynat" : "Duraklat";
  });
  document.getElementById("ses").addEventListener("input",
    (e) => { video.volume = Number(e.target.value); });
  document.getElementById("geri-sar").addEventListener("click",
    () => { video.currentTime = Math.max(0, video.currentTime - 10); });
</script>

3. Açılır menü

Menüyü açan düğme aria-expanded ile durumunu bildirmeli; Escape menüyü kapatıp odağı düğmeye döndürmelidir. Gezinme bağlantılarından oluşan menülerde Tab ile ilerlemek yeterlidir.

Hatalı
<li class="menu" onmouseover="ac()" onmouseout="kapat()">
  Hizmetler
  <ul class="alt-menu">…</ul>
</li>
Doğru
<li class="menu">
  <button type="button" aria-expanded="false"
          aria-controls="hizmetler-menu">Hizmetler</button>
  <ul id="hizmetler-menu" hidden>
    <li><a href="/hizmetler/imar">İmar işlemleri</a></li>
    <li><a href="/hizmetler/ruhsat">Ruhsat başvurusu</a></li>
  </ul>
</li>

<script>
  const dugme = document.querySelector('[aria-controls="hizmetler-menu"]');
  const menu = document.getElementById("hizmetler-menu");

  function ayarla(acik) {
    dugme.setAttribute("aria-expanded", String(acik));
    menu.hidden = !acik;
  }
  dugme.addEventListener("click", () =>
    ayarla(dugme.getAttribute("aria-expanded") !== "true"));
  menu.parentElement.addEventListener("keydown", (e) => {
    if (e.key === "Escape") { ayarla(false); dugme.focus(); }
  });
</script>

4. Diyalog kutusu

Yerleşik dialog öğesi showModal() ile açıldığında odağı içine alır, arka planı etkisiz hâle getirir ve Escape ile kapanır.

<button type="button" id="sil-ac">Başvuruyu sil</button>

<dialog id="sil-diyalog" aria-labelledby="sil-baslik">
  <h2 id="sil-baslik">Başvuru silinsin mi?</h2>
  <p>Bu işlem geri alınamaz.</p>
  <form method="dialog">
    <button value="iptal">Vazgeç</button>
    <button value="sil">Sil</button>
  </form>
</dialog>

<script>
  const diyalog = document.getElementById("sil-diyalog");
  document.getElementById("sil-ac")
    .addEventListener("click", () => diyalog.showModal());
  diyalog.addEventListener("close", () => {
    if (diyalog.returnValue === "sil") { /* silme işlemi */ }
    document.getElementById("sil-ac").focus();
  });
</script>

5. Üzerine gelince görünen ipucu

Yalnızca :hover ile görünen içerik klavye kullanıcısına hiç ulaşmaz. :focus-within veya :focus-visible ekleyin.

Hatalı
.ipucu-kapsayici:hover .ipucu {
  display: block;
}
Doğru
.ipucu-kapsayici:hover .ipucu,
.ipucu-kapsayici:focus-within .ipucu {
  display: block;
}

6. Sürükle-bırak için klavye alternatifi

Sıralanabilir listelerde her öğeye "yukarı taşı" ve "aşağı taşı" düğmeleri eklemek basit ve güvenilir bir alternatiftir. Değişikliği ekran okuyucuya bir durum bölgesiyle bildirin.

<ol id="belgeler">
  <li>
    <span>Nüfus kayıt örneği</span>
    <button type="button" class="yukari">Yukarı taşı<span class="sr-only">: Nüfus kayıt örneği</span></button>
    <button type="button" class="asagi">Aşağı taşı<span class="sr-only">: Nüfus kayıt örneği</span></button>
  </li>
  …
</ol>
<p id="siralama-durumu" role="status" class="sr-only"></p>

<script>
  const liste = document.getElementById("belgeler");
  const durum = document.getElementById("siralama-durumu");

  liste.addEventListener("click", (e) => {
    const oge = e.target.closest("li");
    if (!oge) return;
    const yukari = e.target.closest(".yukari");
    const asagi = e.target.closest(".asagi");
    if (yukari && oge.previousElementSibling) {
      liste.insertBefore(oge, oge.previousElementSibling);
      yukari.focus();
    } else if (asagi && oge.nextElementSibling) {
      liste.insertBefore(oge.nextElementSibling, oge);
      asagi.focus();
    } else return;
    const sira = [...liste.children].indexOf(oge) + 1;
    durum.textContent = `${oge.querySelector("span").textContent}, ${sira}. sıraya taşındı.`;
  });
</script>

Mobil için kod örnekleri

Mobilde "klavye erişimi", harici klavye, anahtar erişimi (Switch Control / Switch Access) ve ekran okuyucu hareketleri ile kullanım anlamına gelir. Standart bileşenler bunları kendiliğinden destekler; sürükleme gibi hareketlere ise erişilebilirlik eylemi eklenmelidir.

iOS (SwiftUI)

import SwiftUI

struct BelgeSiralama: View {
    @State private var belgeler = ["Nüfus kayıt örneği", "İkametgâh", "Gelir belgesi"]

    var body: some View {
        List {
            ForEach(belgeler, id: \.self) { belge in
                Text(belge)
                    // VoiceOver'da yukarı/aşağı kaydırarak seçilen özel eylemler
                    .accessibilityAction(named: "Yukarı taşı") { tasi(belge, -1) }
                    .accessibilityAction(named: "Aşağı taşı") { tasi(belge, 1) }
            }
            .onMove { belgeler.move(fromOffsets: $0, toOffset: $1) }
        }
    }

    private func tasi(_ belge: String, _ yon: Int) {
        guard let i = belgeler.firstIndex(of: belge) else { return }
        let hedef = i + yon
        guard belgeler.indices.contains(hedef) else { return }
        belgeler.swapAt(i, hedef)
    }
}

Android (Jetpack Compose)

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.*

@Composable
fun BelgeSiralama() {
    val belgeler = remember {
        mutableStateListOf("Nüfus kayıt örneği", "İkametgâh", "Gelir belgesi")
    }

    Column {
        belgeler.forEachIndexed { i, belge ->
            Text(
                belge,
                modifier = Modifier
                    .fillMaxWidth()
                    .clickable(onClickLabel = "Belgeyi aç") { /* aç */ }
                    .semantics {
                        customActions = listOf(
                            CustomAccessibilityAction("Yukarı taşı") {
                                if (i > 0) { belgeler.add(i - 1, belgeler.removeAt(i)); true } else false
                            },
                            CustomAccessibilityAction("Aşağı taşı") {
                                if (i < belgeler.lastIndex) { belgeler.add(i + 1, belgeler.removeAt(i)); true } else false
                            }
                        )
                    }
            )
        }
    }
}

Nasıl test edilir?

  • Fareyi bir kenara bırakın: Sayfayı yalnızca Tab, Shift+Tab, Enter, Space, yön tuşları ve Escape ile kullanın. Fareyle yapılabilen her işlemi klavyeyle de yapabiliyor musunuz?
  • Odak göstergesini izleyin: Odak her an görünüyor mu? Odaklanılan öğe çalıştırılabiliyor mu? (Odağın görünürlüğü AA düzeyinde ayrı bir kriterdir, ancak test sırasında sorunları fark etmenizi kolaylaştırır.)
  • Bileşenleri tek tek deneyin: Menüleri açıp kapatın, diyalogları kapatın, medya oynatıcıyı kullanın, ipuçlarını görüntüleyin, sıralama işlemini klavyeyle yapın.
  • Mobilde harici klavye ve anahtar erişimi: Tablete Bluetooth klavye bağlayın veya Switch Control / Switch Access'i açın; tüm işlemleri bu yolla deneyin.
  • Otomatik araçların sınırı: Otomatik araçlar onclick taşıyan ama odak alamayan öğeleri, pozitif tabindex değerlerini ve rolü olmayan etkileşimli öğeleri bulabilir. Ancak bir işlevin klavyeyle gerçekten tamamlanıp tamamlanamadığını ölçemez; bu kriter mutlaka elle test edilmelidir.

Sık yapılan hatalar

  • Tıklanabilir div ve span: Tasarım kolaylığı için düğme yerine kullanılır ve klavyeyle çalışmaz.
  • Yalnızca fare olaylarına bağlanmak: mouseover, mousedown veya dblclick ile tetiklenen işlevlerin klavye karşılığı yoktur.
  • Odak çerçevesini kaldırmak: outline: none kullanıp yerine başka bir gösterge koymamak, klavye kullanıcısının nerede olduğunu bilmesini engeller.
  • Bağlantıyı düğme gibi kullanmak: href içermeyen a öğeleri odak almaz.
  • Sürükle-bırak dosya yükleme alanları: Yanında "Dosya seç" düğmesi olmayan yükleme alanları klavyeyle kullanılamaz.
  • Özel bileşen kütüphanelerine güvenmek: Hazır bileşenlerin klavye desteği her zaman eksiksiz değildir; kullanmadan önce test edin.

Kaynaklar

Kontrol listesi sürümü: V2.2.30.01 (2026). Bu sayfa bilgilendirme amaçlıdır; bağlayıcı metin için Aile ve Sosyal Hizmetler Bakanlığı'nın resmî kontrol listesini esas alın.

Sitenizde bu kriter nasıl görünüyor?

Ücretsiz tarama, bu kriterdeki sorunları ve diğerlerini Bakanlığın A Seviyesi Kontrol Listesi esas alınarak listeler.

Sitemi ücretsiz tara