WCAG 3.3.1 · A Seviyesi

Hata Tanımlaması

Veri girişinde bir hata otomatik olarak algılandığında hatanın metinle bildirilmesini, nedeninin açıkça anlatılmasını ve hangi alanla ilgili olduğunun belirtilmesini ister.

Kısaca

Bir form gönderildiğinde "Hata oluştu" yazısı veya yalnızca kırmızıya dönen bir çerçeve, kullanıcıya neyi düzeltmesi gerektiğini söylemez. Ekran okuyucu kullanıcısı için çerçeve rengi hiç algılanmaz; hangi alanın hatalı olduğunu bulmak için formu baştan dinlemesi gerekir.

Bu kriter, sistemin otomatik olarak fark ettiği giriş hatalarının metinle bildirilmesini ister. Kontrol listesi bunu üç parçada değerlendirir: hatanın metinle bildirilmesi, hatanın nedeninin anlaşılır biçimde açıklanması ve hatanın hangi alanla ilgili olduğunun belirtilmesi.

Neleri kapsar?

  • Metinsel hata mesajı: Hatanın yalnızca renk, simge veya sesle değil, metinle bildirilmesi.
  • Açıklayıcı neden: "Geçersiz giriş" yerine neyin yanlış olduğunu anlatan mesaj.
  • Alanla ilişki: Hata mesajının görsel olarak ilgili alanın yakınında ve kodda o alanla ilişkili olması.
  • Duyurma: Hatanın yardımcı teknolojiler tarafından fark edilebilmesi (hata özeti, odak yönetimi, canlı bölge).
  • Kapsam dışı notlar: Alanların baştan doğru etiketlenmesi ve talimat verilmesi bir sonraki kriterin (Etiketler ve Talimatlar) konusudur. Hatanın nasıl düzeltileceğine dair öneri sunmak AA düzeyindeki ayrı bir kriterin konusudur, ancak açıklayıcı mesajlar çoğu zaman bunu da karşılar.

Kimleri etkiler?

Ekran okuyucu kullanan kör kullanıcılar, hata yalnızca görsel olarak gösterildiğinde formun neden gönderilmediğini anlayamaz. Renk körlüğü olan kişiler kırmızı çerçeveyi fark etmeyebilir. Bilişsel engeli veya öğrenme güçlüğü olan kullanıcılar, belirsiz hata mesajları karşısında ne yapacaklarını bilemez. Ekranı büyüten az gören kişiler ise sayfanın başında çıkan genel bir uyarıyı görmeyebilir.

Kontrol listesinde

Bu kriter, Bakanlığın A Seviyesi Kontrol Listesi'nde 111–114 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 28 kapsamındaki sorular
SoruTürüNe kontrol eder?
111YönlendirmeSayfada kullanıcının veri girdiği ve hata yapabileceği bir işlem (form, arama, doğrulama alanı vb.) olup olmadığını sorar.
112★ ZorunluGiriş hatasının kullanıcıya metin olarak bildirilip bildirilmediğini kontrol eder.
113★ ZorunluHata mesajının, hatanın nedenini kullanıcının anlayacağı biçimde açık ve net anlatıp anlatmadığını kontrol eder.
114★ ZorunluHata mesajının hangi alanla ilgili olduğunu açıkça belirtip belirtmediğini ve alanla görsel ve programatik olarak ilişkilendirilip ilişkilendirilmediğini kontrol eder.

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

Web için kod örnekleri

1. Alanla ilişkilendirilmiş hata mesajı

aria-invalid alanın hatalı olduğunu, aria-describedby ise hatanın ne olduğunu ekran okuyucuya iletir. Mesaj görsel olarak da alanın hemen yanında olmalıdır.

Hatalı
<label for="eposta">E-posta adresi</label>
<input type="email" id="eposta" class="kirmizi-cerceve">
Doğru
<label for="eposta">E-posta adresi</label>
<input type="email" id="eposta"
       aria-invalid="true"
       aria-describedby="eposta-hata">
<p id="eposta-hata" class="hata-mesaji">
  Hata: E-posta adresi "[email protected]" biçiminde olmalıdır.
</p>

2. Açıklayıcı hata metni

Hata mesajı neyin yanlış olduğunu ve mümkünse nasıl düzeltileceğini anlatmalıdır.

Hatalı
<p class="hata">Geçersiz değer.</p>
<p class="hata">Hata var!</p>
Doğru
<p class="hata">Hata: T.C. Kimlik No 11 haneli olmalıdır.
  Girdiğiniz değer 10 hanelidir.</p>
<p class="hata">Hata: Doğum tarihi gelecekte olamaz.</p>

3. Form başında hata özeti

Birden çok hata varsa formun başında bir özet gösterip odağı bu özete taşımak, kullanıcının tüm hataları bir arada görmesini sağlar. Her madde ilgili alana bağlantı vermelidir.

<div id="hata-ozeti" role="alert" tabindex="-1">
  <h2>Başvurunuz gönderilemedi: 2 alanı düzeltin</h2>
  <ul>
    <li><a href="#tckn">T.C. Kimlik No 11 haneli olmalıdır</a></li>
    <li><a href="#telefon">Telefon numarası boş bırakılamaz</a></li>
  </ul>
</div>

<script>
  // Gönderim başarısız olduğunda
  document.getElementById("hata-ozeti").focus();
</script>

4. Hata mesajlarını betikle göstermek

İstemci tarafında doğrulama yapılıyorsa, hata metni oluşturulurken alan ile mesaj aynı anda ilişkilendirilmelidir.

function hataGoster(alan, mesaj) {
  const id = `${alan.id}-hata`;
  let kutu = document.getElementById(id);
  if (!kutu) {
    kutu = document.createElement("p");
    kutu.id = id;
    kutu.className = "hata-mesaji";
    alan.after(kutu);
  }
  kutu.textContent = `Hata: ${mesaj}`;
  alan.setAttribute("aria-invalid", "true");

  // Varsa biçim ipucunu koruyarak hata kimliğini ekle
  const kimlikler = (alan.getAttribute("aria-describedby") || "")
    .split(" ").filter(Boolean);
  if (!kimlikler.includes(id)) kimlikler.push(id);
  alan.setAttribute("aria-describedby", kimlikler.join(" "));
}

function hatayiTemizle(alan) {
  const id = `${alan.id}-hata`;
  document.getElementById(id)?.remove();
  alan.removeAttribute("aria-invalid");
  const kalan = (alan.getAttribute("aria-describedby") || "")
    .split(" ").filter((k) => k && k !== id);
  kalan.length
    ? alan.setAttribute("aria-describedby", kalan.join(" "))
    : alan.removeAttribute("aria-describedby");
}

Alanın başka bir açıklaması da varsa (örneğin biçim ipucu), fonksiyon onu silmez; sonuç aria-describedby="tckn-ipucu tckn-hata" gibi iki kimlik içerir.

5. Tarayıcı doğrulama balonlarına güvenmek

Tarayıcıların yerleşik doğrulama balonları kısa süre görünür, yakınlaştırmada kaybolabilir ve dilleri tutarsız olabilir. Kendi hata mesajlarınızı göstermek daha güvenilirdir.

<form novalidate id="basvuru-formu">
  …
</form>

<script>
  document.getElementById("basvuru-formu").addEventListener("submit", (e) => {
    const tckn = document.getElementById("tckn");
    if (!/^\d{11}$/.test(tckn.value)) {
      e.preventDefault();
      hataGoster(tckn, "T.C. Kimlik No 11 haneli olmalıdır.");
      tckn.focus();
    }
  });
</script>

Mobil için kod örnekleri

iOS (SwiftUI)

import SwiftUI
import UIKit

struct EpostaAlani: View {
    @State private var eposta = ""
    @State private var hata: String?

    var body: some View {
        VStack(alignment: .leading) {
            TextField("E-posta adresi", text: $eposta)
                .keyboardType(.emailAddress)
                .textInputAutocapitalization(.never)
                // VoiceOver alana geldiğinde hatayı da okur
                .accessibilityHint(hata ?? "")

            if let hata {
                Text(hata)
                    .foregroundStyle(.red)
                    .font(.footnote)
            }

            Button("Devam") { dogrula() }
        }
    }

    private func dogrula() {
        if !eposta.contains("@") {
            hata = "Hata: E-posta adresi \"[email protected]\" biçiminde olmalıdır."
            UIAccessibility.post(notification: .announcement, argument: hata)
        } else {
            hata = nil
        }
    }
}

Android (Jetpack Compose)

Compose'da semantics { error(...) }, TalkBack'in alanı hatalı olarak duyurmasını ve hata metnini okumasını sağlar.

import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.error
import androidx.compose.ui.semantics.semantics

@Composable
fun TcknAlani() {
    var tckn by remember { mutableStateOf("") }
    var denendi by remember { mutableStateOf(false) }
    val hata = if (denendi && tckn.length != 11)
        "Hata: T.C. Kimlik No 11 haneli olmalıdır." else null

    OutlinedTextField(
        value = tckn,
        onValueChange = { tckn = it.filter(Char::isDigit) },
        label = { Text("T.C. Kimlik No") },
        isError = hata != null,
        supportingText = { hata?.let { Text(it) } },
        modifier = Modifier.semantics { if (hata != null) error(hata) }
    )
    Button(onClick = { denendi = true }) { Text("Devam") }
}

Nasıl test edilir?

  • Hata üretin: Formu boş gönderin, ardından biçimi yanlış değerlerle (eksik haneli kimlik numarası, @ işareti olmayan e-posta) deneyin.
  • Mesajları okuyun: Her hata metinle bildiriliyor mu? Neyin yanlış olduğunu ve hangi alanla ilgili olduğunu açıkça söylüyor mu?
  • Ekran okuyucuyla deneyin: Gönderimden sonra hata duyuruluyor mu? Hatalı alana geldiğinizde alanın hatalı olduğu ve hata metni okunuyor mu?
  • Gri tonlamada bakın: Renk olmadan hatalı alanlar hâlâ ayırt edilebiliyor mu?
  • Otomatik araçların sınırı: Otomatik araçlar genellikle formun ilk hâlini tarar ve hata durumlarını görmez. Hata durumunu oluşturup yeniden taramak, aria-describedby bağlantılarının bozuk olup olmadığını gösterebilir; ancak mesajların açık ve doğru olup olmadığı elle değerlendirilmelidir.

Sık yapılan hatalar

  • Yalnızca renkle hata göstermek: Kırmızı çerçeve veya kırmızı etiket tek başına bir hata bildirimi değildir.
  • Genel mesajlar: "Lütfen formu kontrol edin" gibi, hangi alanın neden hatalı olduğunu söylemeyen mesajlar.
  • Mesajı alanla ilişkilendirmemek: Görsel olarak alanın altında duran mesajın kodda alana bağlı olmaması.
  • Hata sonrası odağı kaybetmek: Sayfa yenilendiğinde odağın sayfanın başına gitmesi ve hatanın duyurulmaması.
  • Yazarken anlık hata göstermek: Kullanıcı daha yazmayı bitirmeden "geçersiz" uyarısı vermek, ekran okuyucu kullanıcılarını sürekli böler.
  • Girilen verileri silmek: Hata sonrası formun tamamen boşaltılması; kriterin parçası olmasa da kullanıcıyı ciddi biçimde zorlar.

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