4.1.3 Durum Mesajları
İşaretleme dilleri kullanılarak oluşturulan içeriklerde durum mesajları, yardımcı teknolojiler tarafından kullanıcıya odak almaksızın sunulabilmesi için rol veya özellikler aracılığıyla programatik olarak belirlenebilir.
Bu kural ne anlama geliyor
WCAG 4.1.3 Durum Mesajları, kullanıcılara iletilen önemli mesajların — başarı onayları, hata özetleri, ilerleme güncellemeleri ve arama sonucu sayıları gibi — klavye odağını mesaja taşımadan yardımcı teknolojiye iletilmesini gerektirir. Bu, ARIA canlı bölgeler aracılığıyla sağlanır: role="status", role="alert", role="log", role="progressbar" veya aria-live niteliği olan öğeler.
Durum mesajı, kullanıcıya bir eylemin başarısı veya sonucu, bir uygulamanın bekleme durumu veya bir sürecin ilerlemesi hakkında bilgi sağlayan ve odak değişikliğini haklı kılacak kadar önemli olmayan herhangi bir içerik güncellemesidir. Kullanıcı bir form gönderdiğinde "Değişiklikleriniz kaydedildi" bannerı görünürse gören kullanıcı bunu hemen fark eder. Ekran okuyucu kullanıcısı ise sayfadaki mevcut konumunu kaybetmeden aynı mesajın duyurulmasına ihtiyaç duyar.
Neden önemlidir
Gören kullanıcılar görsel değişiklikleri — bir bildirim toastu, bir yükleme göstergesi, bir hata bannerı — fark eder çünkü gözleri sayfayı tarayabilir. Ancak ekran okuyucu kullanıcıları yalnızca ekran okuyucunun duyurduğunu duyar. Bir durum mesajı görsel olarak görünür ancak canlı bölge aracılığıyla sunulmazsa ekran okuyucu sessiz kalır. Kullanıcı formunun kaydedildiğini, aramasının sıfır sonuç döndürdüğünü veya bir hata oluştuğunu bilemez.
Bu, modern web uygulamalarında yaygın olan asenkron işlemler için özellikle sorunludur. AJAX form gönderme, gerçek zamanlı doğrulama, yazarken arama, dosya yükleme ilerlemesi ve alışveriş sepeti güncellemelerinin hepsi kullanıcının odağını bozmadan duyurulması gereken durum mesajları üretir.
İlgili axe-core kuralları
4.1.3 uyumluluğunu doğrudan test eden axe-core kuralı şu anda bulunmamaktadır. Durum mesajları, uygun ARIA canlı bölgelerinin yerinde olduğunun ve ekran okuyucuların güncellemeleri doğru duyurduğunun doğrulanması için manuel test gerektirir. Otomatik araçlar canlı bölge niteliklerinin varlığını doğrulayabilir, ancak uygulamadaki her durum mesajının kapsanıp kapsanmadığını belirleyemez.
Nasıl test edilir
Durum mesajlarını test etmek öncelikle manuel bir süreçtir. Durum güncellemeleri üreten eylemleri gerçekleştirmeli ve bunların ekran okuyucu tarafından duyurulduğunu doğrulamalısınız.
- Uygulamadaki tüm durum mesajlarını belirleyin: form başarı/hata mesajları, arama sonucu sayıları, yükleme göstergeleri, sepet güncellemeleri, bildirim toastları ve ilerleme göstergeleri.
- Bir ekran okuyucu etkinleştirin (macOS'ta VoiceOver, Windows'ta NVDA) ve her durum mesajını tetikleyin.
- Ekran okuyucunun mesajı mevcut konumunuzdan odak kaymadan duyurduğundan emin olun.
- Acil mesajların (hatalar, uyarılar) role="alert" veya aria-live="assertive" kullandığını ve hemen duyurulduğunu doğrulayın.
- Acil olmayan mesajların (başarı, bilgi, ilerleme) role="status" veya aria-live="polite" kullandığını ve ekran okuyucu mevcut konuşmasını bitirdikten sonra duyurulduğunu doğrulayın.
- Canlı bölge kapsayıcısının mesaj enjekte edilmeden önce DOM'da var olduğundan emin olun — dinamik olarak oluşturulan canlı bölgeler tüm ekran okuyucuları tarafından tanınmayabilir.
Nasıl düzeltilir
Durum mesajlarını duyurmak için ARIA canlı bölgelerini kullanın. Anahtar nokta doğru aciliyet seviyesini seçmek ve canlı bölgenin içerik enjekte edilmeden önce DOM'da mevcut olmasını sağlamaktır.
role="status" ile başarı mesajı
<!-- Canlı bölge kapsayıcısı sayfa yüklendiğinde DOM'da (boş) -->
<div role="status" aria-live="polite" id="form-durum"></div>
<!-- Form gönderildikten sonra mesajı enjekte edin -->
<script>
document.getElementById('form-durum').textContent =
'Değişiklikleriniz başarıyla kaydedildi.';
</script>
role="alert" ile hata bildirimi
<!-- Kapsayıcı başından beri DOM'da mevcut -->
<div role="alert" aria-live="assertive" id="hata-bildirimi"></div>
<!-- Hata oluştuğunda -->
<script>
document.getElementById('hata-bildirimi').textContent =
'Hata: Kaydedilemedi. Lütfen internet bağlantınızı kontrol edin.';
</script>
Arama sonuçları sayısı
<!-- Arama geri bildirimi için canlı bölge -->
<div role="status" aria-live="polite" aria-atomic="true" id="arama-sonuç-sayısı">
"erişilebilirlik" için 24 sonuç gösteriliyor
</div>
<!-- Kullanıcı yazarken güncellenir -->
<script>
function sonuçlarıGüncelle(sorgu, sayı) {
document.getElementById('arama-sonuç-sayısı').textContent =
`"${sorgu}" için ${sayı} sonuç gösteriliyor`;
}
</script>
İlerleme göstergesi
<!-- Canlı bölgeli ilerleme çubuğu -->
<div
role="progressbar"
aria-valuenow="45"
aria-valuemin="0"
aria-valuemax="100"
aria-label="Dosya yükleme ilerlemesi"
aria-live="polite"
>
%45 tamamlandı
</div>
<!-- Tamamlanma mesajı -->
<div role="status" aria-live="polite" id="yükleme-durum"></div>
<script>
// Yükleme tamamlandığında:
document.getElementById('yükleme-durum').textContent =
'Yükleme tamamlandı. "rapor.pdf" dosyası kaydedildi.';
</script>
React uygulama deseni
function DurumDuyurucu({ mesaj, aciliyet = "polite" }) {
return (
<div
role={aciliyet === "assertive" ? "alert" : "status"}
aria-live={aciliyet}
aria-atomic="true"
className="sr-only"
>
{mesaj}
</div>
);
}
// Form bileşeninde kullanım
function IletisimFormu() {
const [durum, setDurum] = useState("");
async function gönder(veri) {
try {
await formuGonder(veri);
setDurum("Mesajınız başarıyla gönderildi.");
} catch {
setDurum("Mesaj gönderilemedi. Lütfen tekrar deneyin.");
}
}
return (
<form onSubmit={gönder}>
{/* form alanları */}
<button type="submit">Gönder</button>
<DurumDuyurucu mesaj={durum} />
</form>
);
}
Sık yapılan hatalar
- Canlı bölgeyi mesajla aynı anda dinamik olarak oluşturmak — birçok ekran okuyucu yalnızca içerik değişmeden önce DOM'da mevcut olan canlı bölgeleri izler.
- "Başarıyla kaydedildi" gibi acil olmayan mesajlar için role="alert" kullanmak — assertive duyurular kullanıcıyı böler ve hatalar ile uyarılar için ayrılmalıdır.
- Canlı bölge kullanmak yerine odağı durum mesajına taşımak — bu kullanıcının konumunu bozar ve 4.1.3'un amacını ihlal eder.
- Güncelleme sırasında mesajın tamamı yerine yalnızca değişen kısmın okunması gerektiğinde aria-atomic="true" eklemeyi unutmak.
- Sık hızlı güncellemeler yapan bir kapsayıcıda (örneğin gerçek zamanlı günlük) gecikme olmadan aria-live kullanmak — bu ekran okuyucuyu duyurularla doldurur.
- Canlı bölgeyi display:none veya visibility:hidden ile gizlenen bir kapsayıcının içine yerleştirmek — canlı bölgeler işleyebilmek için erişilebilirlik ağacında görünür olmalıdır.
Kaynaklar
- W3C WAI: ARIA Live Regions— W3C WAI
- Deque: aria-live regions best practices— Deque University
- WebAIM: ARIA Live Regions— WebAIM
- The A11Y Project: Notifications— A11Y Project