WCAG Başarı Kriterleri · Level AA
WCAG 4.1.3: Durum Mesajları
WCAG 4.1.3, durum mesajlarının — form gönderimi onayları, hata bildirimleri ve sepet güncellemeleri gibi — rol veya özellik aracılığıyla programatik olarak belirlenebilir olmasını gerektirir; böylece yardımcı teknolojiler, kullanıcının odağı hareket ettirmesini gerektirmeden bu mesajları duyurabilir. Bu, odak mesajın üzerine kaymasa bile ekran okuyuculara güvenen kullanıcıların önemli geri bildirimleri almasını sağlar.
Bu Kuralın Anlamı
WCAG Başarı Ölçütü 4.1.3 Durum Mesajları (Seviye AA, WCAG 2.1’de tanıtılmış ve WCAG 2.2’ye taşınmıştır) şöyle der: "İşaretleme dilleri kullanılarak uygulanan içerikte, durum mesajları, yardımcı teknolojiler tarafından odağa ihtiyaç duymadan kullanıcıya sunulabilecek şekilde, rol veya özellikler aracılığıyla programatik olarak belirlenebilir."
Pratikte bu, arayüzünüz kullanıcıya bir sonuca ilişkin mesaj ürettiğinde — bir aramanın sonuç döndürmesi, bir form gönderiminin başarılı olması, bir öğenin alışveriş sepetine eklenmesi, doğrulama sonrası bir hatanın oluşması veya bir sürecin tamamlanması gibi — bu mesajın, kullanıcının ona gitmesini gerektirmeyecek bir şekilde yardımcı teknolojiye (AT) açığa çıkarılması gerektiği anlamına gelir. Temel kısıt, mesajın duyurulması için klavye odağına veya programatik odağa ihtiyaç duymamasıdır.
Bu ölçüt, bir işaretleme diliyle (HTML, SVG vb.) yazılmış tüm içeriğe uygulanır ve WCAG tarafından tanınan dört geniş durum mesajı kategorisini kapsar:
- Başarı mesajları: "Siparişiniz alındı" veya "Ayarlar başarıyla kaydedildi" gibi onaylar.
- Hata veya uyarı mesajları: "E-posta adresi geçerli değil" veya "Lütfen tüm zorunlu alanları doldurun" gibi doğrulama geri bildirimleri.
- İlerleme veya durum güncellemeleri: "Yükleniyor… lütfen bekleyin" veya "Yükleme %60 tamamlandı" gibi mesajlar.
- Bağlam değişikliği mesajları: "5 sonuç bulundu" veya "Sepetinizde 3 ürün var" gibi dinamik güncellemeler.
Bir mesaj, uygun bir ARIA canlı bölge rolü veya özelliği — en yaygın olarak role="status", role="alert", aria-live="polite" veya aria-live="assertive" — atandığında bu ölçütü geçer; böylece ekran okuyucular, kullanıcı sekmeyle gitmek zorunda kalmadan, mesaj göründüğünde veya değiştiğinde onu otomatik olarak duyurur.
Bir mesaj, DOM’a dinamik olarak (JavaScript aracılığıyla) enjekte edildiğinde ancak herhangi bir canlı bölge semantiği taşımadığında, ekran okuyucu kullanıcılarının sayfada bir şeyin değiştiğinden habersiz kalmasına neden olarak kalır.
WCAG tarafından tanımlanan önemli bir istisna: Eğer bir durum mesajı, odak mesaj öğesine taşınarak iletiliyorsa (örneğin odak alan bir iletişim kutusu veya bir alert() iletişim kutusu), bu etkileşim için ölçüt uygulanmaz — odak hareketi ihtiyacı tek başına karşılar. Ölçüt, özellikle odak değişimi olmadan görünen mesajlarla ilgilidir.
Neden Önemlidir
Ekran okuyucu kullanıcıları sayfalarda satır satır veya işaretler, başlıklar ve etkileşimli kontroller arasında atlayarak gezinir. Bir sayfa, DOM’a sessizce "Mesajınız gönderildi" şeklinde bir bant enjekte ettiğinde ve bunu duyurmadığında, görme engelli bir kullanıcının işlemin başarılı olduğunu bilmesinin hiçbir yolu yoktur. Formu tekrar gönderebilir, süresiz bekleyebilir veya kafa karışıklığı içinde görevi tamamen bırakabilir. Aynı sorun, yakınlaştırma ve büyütmeye güvenen az gören kullanıcıları da etkiler — mevcut görünüm alanlarının dışında beliren bir durum mesajı, sesli olarak duyurulmadıkça fark edilmez.
Switch erişimi veya göz takibi teknolojisine güvenen motor engelli kullanıcılar da aynı şekilde etkilenir. Bu kullanıcılar genellikle sayfayı yeni içerik için hızlıca tarayamaz; ilgili bilginin kendilerine getirilmesi için AT’ye güvenirler. Canlı bölge duyuruları olmadan, her durum güncellemesi samanlıkta iğne arama problemine dönüşür.
Bilişsel açıdan farklı kullanıcılar da fayda görür: net, anında geri bildirim, bir eylemin tamamlandığını doğrular ve belirsizliğin bilişsel yükünü azaltır. AT "Ürün sepete eklendi" dediğinde, bilişsel engeli olan bir kullanıcı, devam etmeden önce onayı görsel olarak aramak zorunda kalmaz.
Somut bir gerçek dünya senaryosu: görme engelli bir kullanıcı, bir Türk bankasının web sitesinde çok alanlı bir sigorta başvuru formu dolduruyor. Formu gönderiyor, ancak istemci tarafı doğrulama çalışıyor ve alanların yakınında beş kırmızı hata mesajı gösteriyor. Canlı bölge olmadığı için, kullanıcının ekran okuyucusu (JAWS veya NVDA) sessiz kalıyor. Kullanıcı formun başarıyla gönderildiğini varsayıp tarayıcı sekmesini kapatıyor — tüm başvurusunu kaybediyor. Doğru uygulanmış bir role="alert" veya özet canlı bölge ile AT, "3 hata bulundu. Lütfen vurgulanan alanları gözden geçirin" mesajını anında duyurur ve kullanıcının sorunları düzeltmesini sağlar.
İş açısından bakıldığında, erişilebilir olmayan durum geri bildirimi doğrudan dönüşüm oranlarına zarar verir. Dünya genelinde yaklaşık 1,3 milyar insan bir tür engelle yaşamaktadır ve durum mesajlarının erişilebilir olmasını sağlamak, form terk oranlarını, destek talebi hacmini ve uyumsuzlukla ilişkili hukuki riski azaltır. Türk kuruluşları için erişilemezlik, bu makalenin ilerleyen bölümlerinde açıklanan 5378 sayılı Engelliler Kanunu ve yeni Cumhurbaşkanlığı Genelgesi yükümlülüklerinin ihlali anlamına da gelebilir.
İlgili Axe-core Kuralları
- aria-live (otomatik): Axe-core
aria-livekuralı,aria-liveözniteliğini kullanan öğelere geçerli değerlerden birinin atanıp atanmadığını kontrol eder:off,politeveyaassertive.aria-live="true"veyaaria-live="yes"gibi geçersiz veya yanlış yazılmış bir değere ayarlandığı öğeleri işaretler; bu da canlı bölgenin yardımcı teknoloji tarafından sessizce yok sayılmasına neden olur. Bu kural, geliştiriciler canlı bölge oluşturmak istediklerinde, özniteliğin ekran okuyucuların gerçekten dikkate alacağı şekilde doğru biçimlendirilmesini sağlar. - Manuel test (tam kapsama için gerekli): Otomatik araçlar WCAG 4.1.3’ü tam olarak denetleyemez, çünkü temel hata modu, dinamik olarak üretilen bir mesajda eksik bir canlı bölgedir — bu tür bir yokluğu statik kod analizi güvenilir şekilde tespit etmekte zorlanır. Bir araç, kullanıcı etkileşiminden önce DOM’u tararken, hangi öğelerin daha sonra durum mesajına dönüşeceğini bilemez. Axe-core, bir düğmeye tıklandıktan sonra metin enjekte edilecek bir
<div>öğesini, tarama anında div boş veya henüz mevcut olmadığı için işaretlemeyebilir. Bu nedenle canlı bir ekran okuyucu ile manuel test zorunludur: bir test uzmanı durum mesajını tetiklemeli ve duyuruyu dinlemelidir. Eğer hiçbir duyuru yapılmıyorsa ve odak hareket etmemişse, otomatik araçların ne rapor ettiğinden bağımsız olarak ölçüt başarısız olur.
Nasıl Test Edilir
- Axe DevTools veya Lighthouse ile otomatik tarama: Axe DevTools tarayıcı eklentisini (Chrome veya Firefox) kurun ve tam sayfa taraması yapın.
aria-livekuralı altında herhangi bir ihlal olup olmadığına bakın. Ayrıcaaria-roledescriptionveyaaria-atomicyanlış kullanımı altında işaretlenen sorunları kontrol edin. Temiz bir otomatik taramanın 4.1.3’ün geçtiği anlamına gelmediğini unutmayın — yalnızca hatalı biçimlendirilmiş canlı bölge özniteliklerinin bulunmadığı anlamına gelir. Tüm işaretlenen öğeleri not alın ve manuel adımlara geçmeden önce bunları çözün. - Tüm dinamik durum mesajlarını belirleyin: Sayfayı ve JavaScript’ini gözden geçirerek, sayfa yenilemesi veya odak değişimi olmadan durum mesajı üreten tüm kullanıcı etkileşimlerini kataloglayın. Yaygın örnekler: form gönderim geri bildirimi, sepet miktar rozetleri, arama sonuç sayıları, dosya yükleme ilerlemesi, bülten aboneliği onayları, filtre sonuç güncellemeleri ve oturum zaman aşımı uyarıları.
- NVDA + Firefox ile manuel test: Sayfayı NVDA çalışırken açın. Katalogladığınız her durum mesajını tetikleyin (bir form gönderin, sepete ürün ekleyin, arama yapın). Dikkatle dinleyin — NVDA mesaj metnini bir iki saniye içinde otomatik olarak duyurmalıdır. Hiçbir şey duymuyorsanız ve odak hareket etmediyse, ölçüt başarısızdır. Doğruluk için NVDA’nın Konuşma Görüntüleyicisini (Araçlar > Konuşma Görüntüleyici) kullanarak tüm duyuruların metin kaydını inceleyin.
- JAWS + Chrome ile manuel test: Aynı etkileşimleri JAWS ile tekrarlayın.
role="status"mesajlarının nazik bir kesintiyle,role="alert"mesajlarının ise anında kesintiyle duyurulduğunu doğrulayın. Yanlışaria-atomicveyaaria-relevantayarları nedeniyle JAWS’un aynı mesajı birden fazla kez duyurmadığını kontrol edin. - VoiceOver + Safari (macOS/iOS) ile manuel test: macOS’te Safari ile VoiceOver kullanın ve aynı etkileşimleri tekrarlayın. VoiceOver’ın
aria-liveişleyişinin Windows ekran okuyucularından biraz farklı olabileceğini unutmayın — duyuruların gerçekleştiğini ve mantıklı şekilde ifade edildiğini doğrulayın. - Etkileşim sonrası DOM’u inceleyin: Tarayıcı Geliştirici Araçlarını kullanarak durum mesajını tetikleyin ve ardından görünen öğeyi inceleyin.
role="status",role="alert"veya geçerli biraria-liveözniteliğine sahip olduğunu doğrulayın. Mesaj, işaretlenmemiş bir kapsayıcıya düz metin olarak enjekte ediliyorsa, bu başarısızdır. Ayrıca canlı bölge kapsayıcısının, mesaj enjekte edilmeden önce DOM’da mevcut olduğundan emin olun — ekran okuyucular yalnızca önceden var olan canlı bölgelere yapılan değişiklikleri duyurur, DOM’a yeni eklenen öğeleri değil.
Nasıl Düzeltilir
Form Doğrulama Özeti — Hatalı
<!-- Error summary injected after failed submission -->
<div id='error-summary' class='error-box'>
<p>Please fix the following errors before submitting:</p>
<ul>
<li>Email address is required.</li>
<li>Password must be at least 8 characters.</li>
</ul>
</div>
<!-- Problem: no role or aria-live attribute; screen readers will not announce this -->
Form Doğrulama Özeti — Doğru
<!-- role="alert" causes immediate announcement when content is injected -->
<div id='error-summary' role='alert' class='error-box'>
<p>Please fix the following errors before submitting:</p>
<ul>
<li>Email address is required.</li>
<li>Password must be at least 8 characters.</li>
</ul>
</div>
<!-- The container must be present in the DOM before JavaScript injects content into it -->
Alışveriş Sepeti Ürün Sayısı — Hatalı
<!-- Cart badge updated via JavaScript after user clicks "Add to cart" -->
<button id='add-to-cart'>Add to Cart</button>
<span id='cart-count' class='badge'>0</span>
<!-- Problem: cart-count has no live region; update from 0 to 1 is silent to screen readers -->
Alışveriş Sepeti Ürün Sayısı — Doğru
<!-- Separate polite live region announces cart update without interrupting the user -->
<button id='add-to-cart'>Add to Cart</button>
<span id='cart-count' class='badge' aria-hidden='true'>1</span>
<!-- Visually hidden live region provides the announcement -->
<div
id='cart-status'
role='status'
aria-live='polite'
aria-atomic='true'
class='visually-hidden'
>
<!-- JavaScript updates this text: "1 item in your cart" -->
</div>
<!-- aria-atomic="true" ensures the full sentence is read, not just the changed number -->
Arama Sonuç Sayısı — Hatalı
<!-- Results count rendered after AJAX search -->
<p id='results-info'>Showing 24 of 140 results for "laptop"</p>
<!-- Problem: element is replaced entirely via innerHTML; no live region present -->
Arama Sonuç Sayısı — Doğru
<!-- Live region pre-exists in the DOM; JavaScript updates its content after search -->
<p
id='results-info'
role='status'
aria-live='polite'
aria-atomic='true'
>
Showing 24 of 140 results for "laptop"
</p>
<!-- role="status" implies polite + atomic; explicit attributes added for clarity and compatibility -->
Dosya Yükleme İlerlemesi — Hatalı
<!-- Progress percentage injected into DOM during upload -->
<div class='progress-container'>
<div class='progress-bar' style='width: 60%'></div>
<span id='progress-text'>60%</span>
</div>
<!-- Problem: percentage updates are visual only; no announcement to AT -->
Dosya Yükleme İlerlemesi — Doğru
<!-- Use aria-valuenow on a progressbar role, plus a separate polite status for milestones -->
<div class='progress-container'>
<div
role='progressbar'
aria-valuenow='60'
aria-valuemin='0'
aria-valuemax='100'
aria-label='File upload progress'
class='progress-bar'
style='width: 60%'
>
</div>
</div>
<div
id='upload-status'
role='status'
aria-live='polite'
aria-atomic='true'
class='visually-hidden'
>
Upload complete. Your file has been saved.
</div>
<!-- Only announce key milestones (25%, 50%, 75%, complete) to avoid over-announcement -->
Yaygın Hatalar
- Canlı bölge öğesini mesajla aynı anda oluşturmak: Yeni oluşturulan bir DOM öğesine
role="alert"eklemek ve hemen içerik doldurmak, çoğu zaman başarısız olur; çünkü ekran okuyucular yeni düğümü henüz canlı bölge olarak kaydetmemiştir. Boş kapsayıcıyı sayfa yüklenirken oluşturun ve yalnızca durum mesajı hazır olduğunda metin içeriğini güncelleyin. - Acil olmayan mesajlar için
aria-live="assertive"kullanmak: Assertive canlı bölgeler, ekran okuyucunun o anda okuduğu her şeyi keser. "Ürün sepete eklendi" gibi rutin mesajlar içinassertivekullanmak, kullanıcıların okuma akışının sürekli kesilmesiyle rahatsız olmasına neden olur.assertivei (veyarole="alert"i) gerçek zaman baskılı hata veya uyarılar için saklayın; diğer her şey içinpolitekullanın. aria-live’ı"true"veya"1"gibi geçersiz bir değere ayarlamak: Yalnızca"off","polite"ve"assertive"geçerli değerlerdir. Geçersiz değerler, tarayıcı uyarısı olmadan canlı bölgeyi sessizce devre dışı bırakır ve axe-core’unaria-livekuralının öğeyi işaretlemesine neden olur.- Durumu iletmek için yalnızca renk veya simgelere güvenmek: Sayfaya enjekte edilen yeşil onay işareti simgesi veya kırmızı kenarlık yalnızca görsel bir sinyaldir. Canlı bölgede eşlik eden metin olmadan, ekran okuyucu kullanıcıları hiçbir bilgi almaz. Görsel göstergeleri her zaman metin tabanlı bir canlı bölge duyurusuyla eşleştirin.
- Bir cümlenin bir kısmını güncellerken
aria-atomic="true"’yu atlamak: JavaScript yalnızca bir cümlenin içindeki sayıyı güncelliyorsa (örneğin "Sepette 4 ürün" ifadesinde "3"ü "4" yapmak gibi), bazı ekran okuyucular yalnızca değişen düğümü duyurur ve bağlam olmadan "4" der. Kapsayıcıdaaria-atomic="true"ayarlamak, AT’ye tüm bölgeyi bir bütün olarak okumasını söyler. - Her artan ilerleme güncellemesini duyurmak: Dosya yükleme sırasında her saniye yeni bir durum mesajı enjekte etmek ("10%", "11%", "12%"…) kullanıcıyı duyurularla boğar ve ekran okuyucuyu kullanılamaz hale getirir. Yalnızca anlamlı kilometre taşlarını veya nihai tamamlanma durumunu duyurun.
- Canlı bölge kapsayıcısını, koşullu olarak
display:noneveyavisibility:hiddenile gizlenen öğelerin içine yerleştirmek: Gizli bir üst öğe içindeki canlı bölge etkisizdir ve canlı bölge öğesinin kendisi görünür olsa bile hiçbir şey duyurmaz. Duyuru anında canlı bölgenin üst öğe zincirinin gizli olmadığından emin olun. - Gezinme sonrası görünen başarı mesajları için
role="alert"kullanmak: Bir durum mesajı sayfa yenilemesi sonrasında da kalıyorsa (örneğin yönlendirme sonrası sunucu tarafında oluşturulan bir flash mesaj),role="alert"kullanmak yinelenen veya aşırı agresif duyurulara neden olabilir. Bunun yerinerole="status"kullanmayı veya odağı mesaj bölgesine taşımayı düşünün; böylece duyuru kullanıcının gezinmesine doğal şekilde entegre olur. - Araç ipucu veya toast kütüphanelerinin canlı bölgeleri otomatik olarak ele aldığını varsaymak: Birçok popüler UI bileşen kütüphanesi (örneğin Bootstrap Toasts, özel araç ipucu sistemleri) varsayılan olarak ARIA canlı bölge öznitelikleri eklemez. Üçüncü taraf bileşenlerin oluşturulmuş HTML’sini her zaman inceleyin ve eksikse
role="status"veyaaria-liveekleyin. - Yayın öncesi gerçek ekran okuyucularla test etmemek: Axe gibi otomatik araçlar, dinamik bir durum mesajında eksik canlı bölgeyi tespit edemez. Yalnızca otomatik denetimlere güvenmek, 4.1.3 hatalarının fark edilmeden kalmasına yol açar. Dinamik geri bildirim üreten her özellik için NVDA, JAWS ve VoiceOver ile manuel ekran okuyucu testini QA sürecinizin standart bir parçası haline getirin.
Türkiye’nin Erişilebilirlik Mevzuatıyla İlişkisi
Türkiye’nin 2025/10 sayılı Cumhurbaşkanlığı Genelgesi, 21 Haziran 2025 tarihli ve 32933 sayılı Resmî Gazete’de yayımlanarak, Türkiye’de faaliyet gösteren geniş bir kurum yelpazesi için bağlayıcı dijital erişilebilirlik yükümlülükleri getirmiştir. Genelge, uyum için teknik standart olarak WCAG 2.1 ve WCAG 2.2’ye atıfta bulunur ve çoğu kapsanan kuruluş için asgari temel olarak Seviye AA uyumunu açıkça zorunlu kılar.
WCAG 4.1.3 Durum Mesajları, Seviye AA ölçütüdür; bu da Genelge kapsamındaki tüm kuruluşlar için doğrudan zorunlu kapsam içinde olduğu anlamına gelir. Aşağıdaki kuruluş türleri açıkça kapsam dahilindedir:
- Kamu kurum ve kuruluşları — tüm merkezi ve yerel yönetim birimleri, bakanlıklar, belediyeler ve kamu iktisadi teşebbüsleri, dijital hizmetlerinin tamamında AA uyumunu sağlamak zorundadır.
- Bankalar ve finans kuruluşları — Bankacılık Düzenleme ve Denetleme Kurumu (BDDK) tarafından düzenlenen bu kuruluşlar, dinamik durum geri bildiriminin — işlem onayları, hata mesajları ve bakiye güncellemeleri gibi — son derece yaygın olduğu kritik çevrimiçi hizmetler (internet bankacılığı, kredi başvuruları, kart yönetimi) sunar. 4.1.3’teki hatalar, engelli kullanıcıların finansal bağımsızlığını doğrudan engeller.
- E-ticaret platformları — çevrimiçi perakende, durum mesajları için birincil kullanım alanıdır (sepet güncellemeleri, sipariş onayları, stok uyarıları). E-ticaret işletmecileri, bu dinamik bildirimlerin tüm kullanıcılar için erişilebilir olmasını sağlamak zorundadır.
- Hastaneler ve sağlık kuruluşları — randevu alma sistemleri, tahlil sonuç portalları ve hasta panoları sıklıkla durum mesajları kullanır. Erişilemeyen sağlık bilgileri, engelli hastalar için ciddi sonuçlar doğurabilir.
- 200.000 ve üzeri abonesi olan telekomünikasyon şirketleri — hesap yönetim portalları, fatura bildirimleri ve hizmet durum güncellemelerinin tümü, 4.1.3 dahil olmak üzere Seviye AA’ya uygun olmalıdır.
- Seyahat acenteleri ve özel ulaşım şirketleri — rezervasyon onayları, koltuk seçimi geri bildirimi ve seyahat planı güncelleme mesajları kullanıcı deneyiminin merkezindedir ve programatik olarak belirlenebilir olmalıdır.
- Millî Eğitim Bakanlığı (MoNE) tarafından yetkilendirilmiş özel okullar ve eğitim kurumları — öğrenme yönetim sistemleri, not portalları ve kayıt platformları, tüm öğrenciler ve velilere hizmet verebilmek için durum mesajlarını erişilebilir şekilde açığa çıkarmalıdır.
Erişilebilirlik Logosu, Aile ve Sosyal Hizmetler Bakanlığı tarafından verilen, Türkiye’deki dijital olarak erişilebilir web siteleri ve uygulamalar için resmi sertifikasyon işaretidir. Logoya hak kazanmak için bir kuruluşun tam Seviye AA uyumunu göstermesi gerekir — buna 4.1.3 de dahildir. Durum mesajlarının modern web arayüzlerinde her yerde bulunması nedeniyle, Erişilebilirlik Logosu almak isteyen herhangi bir kuruluş, 4.1.3’ü zorunlu bir denetim maddesi olarak görmeli ve canlı bölge kalıplarını tüm dinamik içerik alanlarında tutarlı şekilde uygulamalıdır.
Uyum sağlamayan kuruluşlar, Genelge kapsamında idari yaptırım, Erişilebilirlik Logosu’na uygunluk kaybı ve giderek daha fazla erişilebilirlik bilincine sahip bir pazarda itibar kaybı riskiyle karşı karşıya kalır. WCAG 4.1.3’ü doğru şekilde uygulamak, yalnızca teknik bir onay kutusu değildir — Türkiye’de yaşayan yaklaşık 8,5 milyon engelli vatandaş için eşit dijital erişime yapılan somut bir yatırımdır.
