Ders 19 / 25
Boş ve Hata Durumları
Boş durum ile hata durumunun rol, öncelik ve odak belirtimi; kurtarma yolunun tuş sayısıyla ölçülmesi, hata özetinin keşif maliyetine etkisi ve durum belirtiminin eksiksizlik denetimi.
İçindekiler
İskelet, içeriğin geleceği varsayımına dayanıyordu. Yükleme bittiğinde bu varsayımın tutmadığı iki durum kalır: hiçbir kayıt gelmemesi ve isteğin başarısız olması. İkisi ekranda benzer görünür — boş bir alan ve bir cümle — ama kullanıcıya bambaşka şeyler söyler.
Yükleme ve Boş Durumlar dersi boşluğun üç nedenini ayırmış, Hata ve Uyarı Durumları dersi hatayı kurtarılabilirliğine göre sınıflandırmıştı. Bu ders o ayrımların belirtim karşılığını yazar: hangi rol, hangi duyuru önceliği, odak nereye gider, ve kurtarma yolu kaç tuş sürer.
Ne Çözer, Ne Zaman Kullanılmaz
Boş durum ve hata durumu iki ayrı kalıptır ve karıştırılmaları en pahalı kusurdur.
Boş durum, sistemin doğru çalıştığı ama gösterecek içeriğin bulunmadığı ekrandır. Hata sınıfına girmez; bilgi sınıfına girer. Uyarı rengi, uyarı simgesi ve atılgan duyuru kullanılmaz.
Hata durumu, bir şeyin planlandığı gibi gitmediği ekrandır. Kullanıcının bir şey yapması gerekir ve yapılacak şey ekranda yazılıdır.
Ayrımın sınandığı tek soru şudur: kullanıcı bir şey yapmadığında sistem yanlış bir durumda mı kalıyor? Yanıt hayırsa boş durumdur. Sonuçsuz arama boş durumdur; ödünç alma isteğinin gönderilememesi hatadır.
Kullanılmayacak durumlar:
- Boş durumu hata gibi sunmak. Süzgeç hiçbir kayıt döndürmediğinde kırmızı bir uyarı göstermek, kullanıcıya sistemin bozulduğunu söyler.
- Hatayı boş durum gibi sunmak. İstek başarısız olduğunda “Kayıt bulunamadı” yazmak, var olan kayıtları yok göstermek demektir; kullanıcı aramayı bırakır.
- Her ikisini de kip pencereye koymak. Boş durum sayfanın kendisidir; kip pencere onu kullanıcının kapatması gereken bir engele çevirir.
Yerel Öge Önce, ARIA Sonra
| Durum | Rol | Öncelik | Odak |
|---|---|---|---|
| Boş durum (üç türü) | role="status" |
kibar | Yerinde kalır |
| Alan doğrulama hatası | Hata özeti role="alert" |
atılgan | Özete taşınır |
| İstek hatası | role="alert" |
atılgan | İleti kabına taşınır |
| Ağ kopması | role="status" |
kibar | Yerinde kalır |
Üç kural bu tabloyu üretir.
Boş durum odağı çalmaz. Kullanıcı süzgeç alanında yazmaya devam ediyor olabilir; sonuç sayısı değiştiğinde odağı listeye taşımak yazmayı keser. Bildirim, kibar bölgeden yapılır.
Ağ kopması kibardır, hata atılgan. Ağın kopması kullanıcının yaptığı bir şeyin sonucu değildir ve bağlantı geldiğinde kendiliğinden düzelir; işi durduran bir bildirim değildir.
Hata özeti belgede önceden bulunur. Formlar ve Kimlik konusundaki erişilebilir hata sunumu kuralı burada geçerlidir: özet kabı boş olarak konur, gönderim başarısız olduğunda içi doldurulur ve odak oraya taşınır.
Ayrıca boş durumun bir başlığı olmalıdır. Başlık, ekran okuyucu kullanıcısının başlık düzleminden bu bölüme atlamasını sağlar; başlıksız bir boş durum düzlemde görünmez.
Kurtarma Yolu Ölçülebilir
Belirtimin en somut yanı, hatadan düzeltmeye giden yolun uzunluğudur. Odak halkası bilinen bir dizidir; tuş sayısı sayılabilir. Aşağıdaki betik üyelik formunda iki hatalı alan bulunan bir gönderimi üç ayrı odak stratejisiyle ölçüyor, sonra dokuz durumun belirtimini dört alanlı bir denetimden geçiriyor.
// kurtarma.mjs — kurtarma yolunun tus sayisiyla olculmesi ve durum belirtiminin denetimi // --- (a) Kurtarma yolunun uzunlugu ------------------------------------------ // Uyelik formunun bulundugu sayfanin odak halkasi (belge sirasinda). const SAYFA = [ "atlama-baglantisi", "logo", "gezinme-katalog", "gezinme-hesabim", "arama-alani", "form-uye-no", "form-ad", "form-eposta", "form-telefon", "form-adres", "form-iade-tarihi", "form-not", "form-gonder", "altlik-yardim", "altlik-iletisim", "altlik-gizlilik", ]; // Sekme ve geri sekme ayni maliyette; iki oge arasindaki uzaklik halkada en kisa yoldur. function adim(halka, bas, hedef) { const i = halka.indexOf(bas), j = halka.indexOf(hedef); if (i < 0 || j < 0) throw new Error(`halkada yok: ${i < 0 ? bas : hedef}`); return Math.min((j - i + halka.length) % halka.length, (i - j + halka.length) % halka.length); } // Bir strateji: baslangic odagi ve sirayla gidilecek hedefler. // baglanti: true olan hedefe tek tusla (giris) gidilir. function yol(ad, halka, bas, hedefler) { let konum = bas, toplam = 0; const parca = []; for (const h of hedefler) { const n = h.baglanti ? 1 : adim(halka, konum, h.hedef); toplam += n; parca.push(`${h.hedef}:${n}${h.baglanti ? "*" : ""}`); konum = h.hedef; } return { ad, toplam, iz: parca.join(" ") }; } const A = yol("ozetsiz, odak yerinde", SAYFA, "form-gonder", [ { hedef: "form-eposta" }, { hedef: "form-iade-tarihi" }, { hedef: "form-gonder" }, ]); // Hata ozeti forma eklenir; odak ozete tasinir, ozetteki baglanti alana goturur. const HALKA_B = [...SAYFA]; HALKA_B.splice(HALKA_B.indexOf("form-uye-no"), 0, "hata-ozeti", "ozet-eposta", "ozet-iade-tarihi"); const B = yol("hata ozeti + odak ozete", HALKA_B, "hata-ozeti", [ { hedef: "ozet-eposta" }, { hedef: "form-eposta", baglanti: true }, { hedef: "form-iade-tarihi" }, { hedef: "form-gonder" }, ]); const C = yol("odak ilk hatali alana", SAYFA, "form-eposta", [ { hedef: "form-eposta" }, { hedef: "form-iade-tarihi" }, { hedef: "form-gonder" }, ]); // Kesif: kac hata oldugunu ogrenmek icin kac alanin gezilmesi gerekir? const ALAN_SAYISI = SAYFA.filter((x) => x.startsWith("form-") && x !== "form-gonder").length; const KESIF = { [A.ad]: ALAN_SAYISI, [B.ad]: 0, [C.ad]: ALAN_SAYISI - 1 }; console.log(`form alani sayisi: ${ALAN_SAYISI}, hatali alan: form-eposta ve form-iade-tarihi`); console.log("\nstrateji tus sayisi kesif iz (* = baglantiyla dogrudan)"); for (const s of [A, B, C]) console.log(`${s.ad.padEnd(24)} ${String(s.toplam).padStart(10)} ${String(KESIF[s.ad]).padStart(6)} ${s.iz}`); // --- (b) Durum belirtiminin denetimi ---------------------------------------- // Her durum icin dort alan tanimli olmali: rol, duyuru onceligi, odak hedefi, kurtarma eylemi. const DURUM = [ { ad: "ilk kullanim boslugu", rol: "status", oncelik: "kibar", odak: "yerinde", kurtarma: "arama alanina yonlendiren aciklama" }, { ad: "sonucsuz arama", rol: "status", oncelik: "kibar", odak: "yerinde", kurtarma: "suzgecleri tek tek kaldirma" }, { ad: "temizlenmis liste", rol: "status", oncelik: "kibar", odak: "yerinde", kurtarma: null }, { ad: "alan dogrulama hatasi", rol: "alert", oncelik: "atilgan", odak: "hata ozeti", kurtarma: "alana giden baglanti ve duzeltme onerisi" }, { ad: "sunucu hatasi", rol: "alert", oncelik: "atilgan", odak: "hata iletisi", kurtarma: "yeniden dene dugmesi" }, { ad: "ag kopmasi", rol: "status", oncelik: "kibar", odak: "yerinde", kurtarma: "baglanti gelince yeniden deneme" }, { ad: "yetki hatasi", rol: "alert", oncelik: "atilgan", odak: null, kurtarma: "oturum acma sayfasina donus" }, { ad: "bulunamayan kayit", rol: null, oncelik: null, odak: "baslik", kurtarma: "katalog aramasina donus" }, { ad: "istek siniri asildi", rol: "alert", oncelik: "atilgan", odak: "hata iletisi", kurtarma: null }, ]; const ZORUNLU = ["rol", "oncelik", "odak", "kurtarma"]; // "temizlenmis liste" bir basaridir; kurtarma eylemi aranmaz. const MUAF = { "temizlenmis liste": ["kurtarma"] }; console.log("\ndurum rol oncelik odak kurtarma eksik"); let eksikToplam = 0; for (const d of DURUM) { const eksik = ZORUNLU.filter((a) => d[a] === null && !(MUAF[d.ad] ?? []).includes(a)); eksikToplam += eksik.length; console.log( `${d.ad.padEnd(25)} ${(d.rol ?? "—").padEnd(8)} ${(d.oncelik ?? "—").padEnd(9)} ${(d.odak ?? "—").padEnd(15)} ` + `${(d.kurtarma ? "var" : "—").padEnd(9)} ${eksik.length ? eksik.join(",") : "yok"}`, ); } console.log(`\ntoplam eksik alan: ${eksikToplam} / ${DURUM.length * ZORUNLU.length}`);
form alani sayisi: 7, hatali alan: form-eposta ve form-iade-tarihi strateji tus sayisi kesif iz (* = baglantiyla dogrudan) ozetsiz, odak yerinde 10 7 form-eposta:5 form-iade-tarihi:3 form-gonder:2 hata ozeti + odak ozete 7 0 ozet-eposta:1 form-eposta:1* form-iade-tarihi:3 form-gonder:2 odak ilk hatali alana 5 6 form-eposta:0 form-iade-tarihi:3 form-gonder:2 durum rol oncelik odak kurtarma eksik ilk kullanim boslugu status kibar yerinde var yok sonucsuz arama status kibar yerinde var yok temizlenmis liste status kibar yerinde — yok alan dogrulama hatasi alert atilgan hata ozeti var yok sunucu hatasi alert atilgan hata iletisi var yok ag kopmasi status kibar yerinde var yok yetki hatasi alert atilgan — var odak bulunamayan kayit — — baslik var rol,oncelik istek siniri asildi alert atilgan hata iletisi — kurtarma toplam eksik alan: 4 / 36
İlk tablo tek bir sayıyla karar vermenin neden yanlış olduğunu gösteriyor.
Özetsiz kurulum on tuş istiyor ve keşif sütunu asıl bedeli veriyor: kullanıcı kaç hata olduğunu öğrenmek için yedi alanın hepsini gezmek zorundadır. Gönderim başarısız olduğunda odak gönder düğmesinde kaldığı için, ilk hatalı alana ulaşmak beş geri sekme tuşu gerektirir.
Odağı doğrudan ilk hatalı alana taşımak beş tuşla en ucuz yol. Ama keşif sütunu altı diyor: kullanıcı odaklandığı alanın hatalı olduğunu öğrenir, ikinci hatanın varlığını öğrenmez. İkinci hatayı ancak forma devam ederken bulur ya da hiç bulmaz ve gönder düğmesine ikinci kez basar.
Hata özeti yedi tuş istiyor — doğrudan taşımadan iki tuş fazla — ama keşif maliyetini sıfıra indiriyor. Özet, kaç hata olduğunu tek bir cümlede söyler ve her hataya bir bağlantı verir. İki fazladan tuş, “kaç hata var” sorusunun yanıtının bedelidir ve ucuzdur.
Bu ölçüm bir kuralı gerekçelendirir: birden çok hata varsa özet, tek hata varsa doğrudan taşıma. Tek hatada özetin keşif kazancı yoktur ve iki tuş boşa gider.
İkinci tablo belirtimin kendisini denetliyor. Dokuz durumun otuz altı alanından dördü eksik ve üçü ayrı türden kusur:
- Yetki hatasında odak hedefi tanımsız. İleti ekranda belirir ama odak formda kalır; kullanıcı iletiyi hiç duymaz.
- Bulunamayan kayıtta rol ve öncelik tanımsız. Ekranda bir başlık vardır, duyuru yoktur. Bu durum aslında bir sayfa geçişidir ve başlığa odaklanma doğru karardır; eksik olan, bunun bir durum bildirimi olarak da tanımlanmasıdır.
- İstek sınırı aşıldığında kurtarma eylemi tanımsız. Kullanıcıya ne yapacağı söylenmiyor; “biraz sonra yeniden deneyin” gibi bir yol yazılmadığında hata çıkmaz sokaktır.
“Temizlenmiş liste” satırında kurtarma alanı boş olduğu hâlde eksik sayılmıyor, çünkü o durum bir başarıdır ve kurtarılacak bir şey yoktur. Denetimin muafiyet listesi bu ayrımı belirtimin parçası hâline getirir.
Ölçülebilir Kısıtlar
3.3.1 Hata Tanımlama. Hatalı alan metinle belirtilmelidir; kırmızı kenarlık tek başına yetmez. Bu, 1.4.1 Rengin Kullanımı ölçütünün form karşılığıdır.
3.3.3 Hata Önerisi. Hatanın nasıl düzeltileceği biliniyorsa yazılmalıdır. “Geçersiz tarih” bir tanımlamadır, öneri değildir; “İade tarihi bugünden sonra olmalı” ikisini birden yapar.
3.3.4 Hata Önleme. Geri alınamaz işlemlerde gönderim tersine çevrilebilir, denetlenebilir ya da onaylanabilir olmalıdır. Kip Pencereler dersindeki onay kalıbı bu ölçütün karşılığıdır.
4.1.3 Durum İletileri. Boş durumun sonuç sayısı odak taşımadan duyurulmalıdır.
2.4.6 Başlıklar ve Etiketler. Boş durumun başlığı, içeriğin ne olduğunu betimlemelidir; “Sonuç yok” başlığı yerine “Süzgeçlere uyan kayıt yok” başlığı düzlemde işe yarar.
1.4.11 Metin Dışı Kontrast. Hata alanının kenarlığı çevresindeki yüzeye karşı en az 3:1 oranını karşılamalıdır; hata rengi yalnız metinde değil sınırda da ayırt edilebilmelidir.
Sık Yapılan Hata ve Nasıl Anlaşılır
Odak gönderimden sonra yerinde kalıyor. Anlaşılması: formu hatalı gönderip bir kez sekme tuşuna basmak; odak formun başına ya da özete gitmiyorsa strateji yoktur.
Hata özeti sonradan ekleniyor. Duyuru bazen yapılır bazen yapılmaz. Anlaşılması: sayfa ilk kurulduğunda özet kabının belgede olup olmadığına bakmak.
Boş durum atılgan duyuruyla bildiriliyor. Süzgeç her değiştiğinde kullanıcının okuması
kesilir. Anlaşılması: boş durum bölgesinin rolüne bakmak; role="alert" ise yanlıştır.
Hata iletisi alana bağlanmamış. İleti ekranda görünür ama alana odaklanıldığında
okunmaz. Anlaşılması: alanın aria-describedby bağının ileti kimliğini gösterip
göstermediğine bakmak.
Boş durumda başlık yok. Anlaşılması: başlık düzlemini çıkarıp boş durumun orada görünüp görünmediğine bakmak.
Özet
- Boş durum sistemin doğru çalıştığı bir sonuçtur ve bilgi sınıfına girer; hata durumu kullanıcıdan bir eylem ister ve o eylem ekranda yazılıdır.
- Ayrımın sınandığı soru tektir: kullanıcı hiçbir şey yapmazsa sistem yanlış bir durumda kalıyor mu?
- Boş durum kibar bölgeden bildirilir ve odağı çalmaz; alan doğrulama hatası atılgan bildirilir ve odak hata özetine taşınır.
- Kurtarma yolu tuş sayısıyla ölçülür: özetsiz kurulum on tuş ve yedi alanlık keşif, doğrudan taşıma beş tuş ve altı alanlık keşif, hata özeti yedi tuş ve sıfır keşif üretir.
- Birden çok hata varsa özet, tek hata varsa doğrudan taşıma seçilir; özetin iki fazladan tuşu “kaç hata var” sorusunun bedelidir.
- Bir durumun belirtimi rol, öncelik, odak hedefi ve kurtarma eylemi alanlarının dördünü de taşımalıdır; denetim, eksik alanı ve muafiyeti birlikte tanımlar.
Sonraki Adım
Boş ve hata durumları bir ekranın tamamını kaplayan bildirimlerdi. Aynı bilgi çoğu zaman çok daha küçük bir yüzeyde taşınır: satırın yanındaki küçük bir etiket, sayının yanındaki renkli bir nokta, kaydın durumunu bildiren tek sözcüklük bir rozet. Bu küçük yüzeyler iki tuzağı birlikte barındırır — bilgiyi yalnız renkle taşımak ve erişilebilir ada yalnız sayı yazmak. Sonraki ders rozetlerin ve etiketlerin belirtimini yazar, rengin tek başına ayırt edici olmadığını kontrast ve renk körlüğü izdüşümüyle hesaplar ve ikinci kanalın nasıl denetleneceğini gösterir.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.