Blocked aria-hidden Hatası: Konsol Uyarısını Susturmak Yerine Erişilebilirliği Düzeltme Rehberi
Blocked aria-hidden konsol hatasının gerçek nedenini keşfedin; focus yönetimi, inert özelliği ve modern modal pratikleriyle erişilebilirliği güvenceye alın.
Modern ön yüz (front-end) geliştirmede en sık karşılaşılan fakat en çok yanlış çözülen konsol uyarılarından biri hiç şüphesiz şudur: "Blocked aria-hidden on an element because its descendant retained focus". İster Angular, ister React (Radix UI / shadcn), ister Bootstrap veya Ionic kullanıyor olun, bir modal pencereyi kapattığınız anda tarayıcı konsolunda bu turuncu uyarıyı görme olasılığınız oldukça yüksektir.
Arama motorlarında veya Stack Overflow üzerinde bu hatayı arattığınızda karşınıza çıkan çözümlerin ezici çoğunluğu ne yazık ki ölümcül bir ortak noktaya sahiptir: Konsolu sustururlar ancak ekran okuyucu kullanan gerçek bir kullanıcının sayfa üzerindeki odağını (focus) tamamen bir kara deliğe hapsederler. Bu rehberde, uyarının arkasındaki tarayıcı mekaniğini, popüler "geçici çözümlerin" neden zararlı olduğunu ve problemi mimari düzeyde nasıl kalıcı olarak çözeceğinizi ele alıyoruz.
Uyarının Gerçek Anlamı: Hayalet Odak (Ghost Focus) Problemi
Tarayıcılar bu uyarıyı keyfi olarak üretmez. Bir DOM elemanına aria-hidden="true" atadığınızda, tarayıcının erişilebilirlik ağacına (Accessibility Tree) şu mesajı vermiş olursunuz: "Bu elemanı ve altındaki her şeyi yardımcı teknolojilerden (ekran okuyucular vb.) tamamen gizle."
Ancak aynı anda klavye veya tarayıcı odağı (focus) hala o gizlenen elemanın içindeki bir düğmede veya bağlantıda bulunuyorsa, ortaya teknik bir çelişki çıkar. Yardımcı teknoloji odağın nerede olduğunu anlayamaz; kullanıcı klavyeyle nereyi kontrol ettiğini duymaz veya odak aniden belgenin en tepesine (<body>) sıçrar. Kullanıcı, sayfada nerede olduğunu tamamen kaybeder ve onlarca sekme (Tab) tuşuna basarak eski konumunu yeniden aramak zorunda kalır.
Kritik Kural: Odak (focus), bir bölge gizlenmeden (
aria-hidden="true") veya etkisizleştirilmeden (inert) önce o bölgeyi terk etmelidir. Tüm mimari bu temel işlem sırasına dayanır.
Yaygın ve Yanlış Çözüm Tuzakları
Geliştiricilerin konsolu susturmak adına sıklıkla düştüğü ve yardımcı teknolojileri felç eden yöntemleri inceleyelim:
document.activeElement.blur()Çağırmak: En yaygın yanılgıdır. Elemanın odağını kaldırırsınız, konsol uyarısı kaybolur. Fakat kullanıcı odağı doğrudan<body>etiketine düşer. Kullanıcı bağlamını tamamen kaybeder.setTimeoutile Gizlemeyi Geciktirmek: İşlem sırasını asenkron bir gecikmeyle çözmeye çalışmak yarış durumlarına (race condition) neden olur ve ekran okuyucu yazılımlarında anlık ses patlamalarına ya da sessizliklere yol açar.aria-hiddenÖzelliğini Silmek: Sorunun kaynağını çözmek yerine semantik erişilebilirlik katmanını ortadan kaldırır; arka plandaki elemanlar modal açıkken dahi okunabilir kalır.- UI Kütüphanelerinde
modal={false}Yapmak: Radix UI veya shadcn/ui gibi modern kütüphanelerde bu hatayı görünce modal davranışını kapatmak, dış tıklama kapatmalarını ve erişilebilirlik tuzaklarını bozar.
| Uygulanan Yöntem | Konsol Hatası Çözülür mü? | Ekran Okuyucu Dostu mu? | Teknik Risk / Yan Etki |
|---|---|---|---|
blur() Çalıştırmak | Evet | Hayır (Kritik Hata) | Odak <body> seviyesine düşer, bağlam kaybolur. |
setTimeout ile Kapatmak | Kısmen | Hayır | Asenkron yarış durumları ve tutarsız render. |
aria-hidden Kaldırmak | Evet | Hayır | Arka plan modal açıkken erişilebilir kalır. |
Doğru Sıralama & inert | Evet | Evet (Mükemmel) | Standartlara tam uyum, sıfır erişilebilirlik kaybı. |
Native <dialog> Kullanımı | Evet | Evet (Mükemmel) | Modern tarayıcılarda sıfır kütüphane bağımlılığı. |
Doğru Yaklaşım: İşlem Sıralaması (Order of Operations)
Çoğu modal kapatma fonksiyonu doğru fonksiyon çağrılarına sahiptir, ancak bu çağrılar yanlış sırada işletilir. Kod mantıksal olarak yukarıdan aşağıya okunurken, tarayıcı DOM manipülasyonlarını anında uygular.
Hatalı Uygulama Örneği
// HATALI: Yaygın kullanılan kapatma sırası
function closeModalHatalı() {
// 1. Arka plan/overlay gizleniyor, ancak odak HALA içeride!
overlay.setAttribute('aria-hidden', 'true');
overlay.classList.add('fade-out');
// 2. Odak gizleme işlemi yapıldıktan SONRA tetikleyiciye aktarılıyor (Çok geç!)
triggerButton.focus();
}
Doğru Uygulama Örneği (Focus Management & Inert)
// DOĞRU: İşlem sırası optimize edilmiş modal kapatma
function closeModalDogru(triggerButton, modalOverlay, mainContent) {
// 1. Sayfa gövdesinin inert durumunu kaldır (odak alabilmesi için)
mainContent.removeAttribute('inert');
// 2. Kapatılacak alandan odağı ÇIKAR ve tetikleyici butona geri ver
if (triggerButton && typeof triggerButton.focus === 'function') {
triggerButton.focus();
}
// 3. Artık odak güvenli bölgede olduğuna göre modalı inert yap ve gizle
modalOverlay.setAttribute('inert', '');
modalOverlay.style.pointerEvents = 'none';
modalOverlay.classList.add('fade-out');
modalOverlay.addEventListener('transitionend', () => {
modalOverlay.remove();
}, { once: true });
}
Modern Çözüm: Yerel <dialog> Elemanına Geçiş
Eğer projenizde eski bir UI kütüphanesine bağımlı değilseniz, en temiz ve hatasız yaklaşım HTML5 yerel <dialog> elemanını kullanmaktır. .showModal() metodu çağrıldığında tarayıcı:
- Otomatik olarak arka plandaki tüm elemanları inert hale getirir.
- Modal kapatıldığında (
dialog.close()) odağı modalı açan tetikleyiciye tarayıcı seviyesinde kusursuz iade eder. Esctuşu dinlemesini varsayılan olarak yönetir.
// Modern TypeScript ve Yerel Dialog Kullanımı
const dialogElement = document.querySelector<HTMLDialogElement>('#user-profile-modal');
const openBtn = document.querySelector<HTMLButtonElement>('#open-modal-btn');
openBtn?.addEventListener('click', () => {
// show() değil, showModal() kullanılmalıdır (Erişilebilirlik kalkanı açar)
dialogElement?.showModal();
});
// HTML:
// <dialog id="user-profile-modal">
// <form method="dialog">
// <p>Profil Detayları</p>
// <button type="submit">Kapat</button>
// </form>
// </dialog>
Teknik SEO ve Erişilebilirlik (a11y) İlişkisi
Google, Core Web Vitals ve sayfa kalitesi algoritmalarında sadece görsel performansı değil, kullanıcı deneyimi sinyallerini de (UX) kapsamlı şekilde değerlendirmektedir. W3C standartlarına ve WCAG 2.1 yönergelerine uygun olmayan web siteleri, erişilebilirlik denetimlerinde (Lighthouse Accessibility Skoru) düşük puanlar alır. Doğru DOM hiyerarşisi ve sorunsuz odak akışı, arama motoru botlarının JavaScript render süreçlerinde sayfa düzenini stabil anlamasını sağlar ve DOM derinliğindeki mantıksal hataları önler.
Kaynak: CSS-Tricks - https://css-tricks.com/blocked-aria-hidden-fix/
Sıkça Sorulan Sorular
Bu konu hakkında geliştiricilerin ve site sahiplerinin en çok merak ettiği soruların yanıtları.
Doğrudan bir sıralama cezası getirmese de dolaylı olarak etki eder. Bu uyarı, Google Lighthouse erişilebilirlik (Accessibility) skorunuzu düşürür. Ayrıca klavye ve ekran okuyucu kullanıcılarının sitede kalma süresini ve hemen çıkma oranlarını (Bounce Rate) olumsuz etkileyerek kullanıcı deneyimi sinyallerine zarar verir.