Gizli bölge içinde hâlâ odaklanmış bir buton, hayalet odak sorununu gösteren kavramsal görsel

Konsolda Blocked aria-hidden on an element because its descendant retained focus uyarısını gördüyseniz, tarayıcınız bir hata değil bir erişilebilirlik çakışmasını bildiriyordur. Chrome, gizlemeye çalıştığınız bir bölgenin içinde hâlâ odaklanmış bir eleman bulduğu için aria-hidden uygulamayı reddediyor — ve StackOverflow’da en çok paylaşılan “çözümlerin” neredeyse tamamı sorunu çözmek yerine sessizce gizliyor.

Bu uyarı ne anlama geliyor?

aria-hidden="true", bir öğeyi ekran okuyucuların erişilebilirlik ağacından kaldırır — ama odak sırasından kaldırmaz. İki özellik birbirinden bağımsız çalışır. Bu da şu tuhaf durumu yaratabilir: bir eleman aynı anda hem tamamen odaklanabilir hem de tamamen algılanamaz olabilir.

Sonuç, geliştiricilerin “hayalet odak” (ghost focus) dediği durum: ekran okuyucu kullanıcıya bir şeye odaklandığını bildirir, ama okuyucu o şeyi erişilebilirlik ağacında bulamaz çünkü ebeveyni aria-hidden ile gizlenmiştir. Chrome, tam da bunu önlemek için aria-hidden uygulamasını bloklar ve konsola uyarı basar.

Uyarı iki farklı anda tetiklenebilir:

  • Açılış anı — “just received focus” (Chrome 127, Haziran 2024): gizli bölge içinde bir eleman odak alırsa.
  • Kapanış anı — “retained focus” (Chrome 131, Aralık 2024): bir modal kapanırken odak hâlâ o bölgenin içinde kalmışsa.

Firefox ve Safari aynı çakışmayı sessizce kendi başına düzeltiyor — konsolda hiçbir şey görmezsiniz, ama sorunun kendisi (odağın kullanıcıya kaybolması) her üç tarayıcıda da gerçek. Chrome’un farkı, sorunu görünür kılması.

Bu uyarıyla nerede karşılaşırsınız?

Bu spesifik hata mesajı, gerçek projelerde yaygın bir GitHub issue kalıbı haline geldi — çoğu vaka modal/dialog kapanış animasyonlarında:

  • Angular Material MatDialog bileşeninde tekrarlanan bir issue (#30187, #31927).
  • UIkit modal bileşeninde açık bir bug raporu (#5104).
  • phpMyAdmin ve Bootstrap tabanlı arayüzlerde kapanış animasyonu sırasında (#19793).

Ortak nokta: modal/dialog kapanırken CSS geçiş animasyonu (transition) bitmeden aria-hidden veya inert uygulanıyor, oysa o anda odak hâlâ modalin içindeki bir butonda.

Herkesin denediği yanlış çözümler

Aşağıdaki dört “çözüm” konsol uyarısını susturur ama asıl sorunu — kullanıcının odağının nereye gittiğini — çözmez.

  • çarpı işareti document.activeElement.blur() — Odağı zorla kaldırır, tarayıcı odağı <body>‘ye düşürür. Ekran okuyucu kullanıcısı sayfanın en başına fırlatılır.
  • çarpı işareti setTimeout / requestAnimationFrame ile geciktirme — Zamanlama belirsizdir; düşük CPU gücünde yine aynı hatayı üretebilir.
  • çarpı işareti aria-hidden’ı tamamen kaldırmak — Arka plandaki içerik ekran okuyucu için hâlâ “orada” görünür; modal sözleşmesi bozulur.
  • çarpı işareti modal={false} gibi prop’larla modal davranışını kapatmak — Odak tuzağını tamamen ortadan kaldırır.

Dördü de aynı hatayı yapıyor: sırayı değil, belirtiyi düzeltiyorlar.

Doğru çözüm: inert + odak sırası kontratı

CSS-Tricks’te Durgesh Rajubhai Pawar’ın önerdiği çözüm tek bir kurala dayanıyor: odaklanmış eleman gizlenmeden veya inert yapılmadan önce odak, o bölgeden çıkmış olmalı. Sıra önemli:

function closeModal() {
  // ADIM 1: Arka planı yeniden etkileşilebilir yap
  background.removeAttribute('inert');

  // ADIM 2: Odağı geri yükle — herhangi bir gizlemeden ÖNCE
  triggerButton.focus();

  // ADIM 3: Kapanan modal'ı inert yap (artık odak içinde değil)
  overlay.setAttribute('inert', '');
  overlay.style.pointerEvents = 'none';
  overlay.classList.add('fade-out');

  // ADIM 4: Geçiş animasyonu bitince DOM'dan kaldır
  overlay.addEventListener('transitionend', () => overlay.remove());
}

Bu yaklaşımın aria-hidden‘a göre üstünlüğü şu: inert hem görünürlüğü hem odaklanabilirliği tek özellikte yönetir. aria-hidden yalnızca ekran okuyucudan gizler, fare/klavye ile hâlâ etkileşime izin verir — bu da ikinci bir çakışma kaynağıdır. inert, elemanı hem erişilebilirlik ağacından hem de odak sırasından aynı anda çıkarır. onay işareti Bootstrap gibi kütüphaneler, native <dialog> elementine geçerek bu sorunu yapısal olarak zaten çözüyor.

Kendi projenizde nasıl test edersiniz

  • Modal/dialog’unuzu klavye ile (Tab, Enter, Esc) açıp kapatın, konsolu açık tutun.
  • Kapanış animasyonu sırasında Tab’a basmayı deneyin — hata genelde tam bu anda tetiklenir.
  • aria-hidden veya inert uygulayan kodun, odağı taşıyan koddan sonra çalıştığını doğrulayın.
  • Üçüncü parti bir modal kütüphanesi kullanıyorsanız (Bootstrap, Angular Material, UIkit), GitHub issue’larında sürümünüze özel bir düzeltme olup olmadığını kontrol edin.

CSS ve frontend tarafında taze konulara ilgi duyuyorsanız CSS’e Gap Decorations Geldi yazımıza da göz atabilirsiniz.

Sık sorulan sorular

“Blocked aria-hidden on an element because its descendant retained focus” hatası ne zaman ortaya çıktı?

Chrome, açılış anındaki uyarıyı (“just received focus”) sürüm 127 ile Haziran 2024’te, kapanış anındaki “retained focus” varyasyonunu ise sürüm 131 ile Aralık 2024’te eklemeye başladı.

inert attribute’u hangi tarayıcılarda destekleniyor?

inert, güncel Chrome, Firefox ve Safari sürümlerinin tamamında destekleniyor ve modern tarayıcı standardı haline geldi — <dialog> elementini native kullanan Bootstrap gibi kütüphaneler bu sorunu zaten yapısal olarak çözüyor.

Bootstrap veya Angular Material modal’ımda bu uyarıyı nasıl doğru şekilde susturabilirim?

Kütüphanenin kapanış event’ini dinleyip inert özelliğini odak geri yüklendikten sonra uygulayarak: örneğin Bootstrap’te modal hide event’i tetiklendiğinde önce tetikleyici butona focus() çağrısı yapıp ardından inert eklemek, blur() veya setTimeout gibi geçici çözümlere göre kalıcı bir düzeltmedir.

aria-hidden ile inert arasındaki fark nedir?

aria-hidden yalnızca elemanı ekran okuyucunun erişilebilirlik ağacından çıkarır ama fare/klavye etkileşimini engellemez; inert ise hem erişilebilirlik ağacından çıkarır hem de odaklanmayı ve tüm kullanıcı etkileşimini aynı anda devre dışı bırakır — bu yüzden modal/dialog gizleme senaryolarında daha güvenli kabul edilir.


Kaynak: CSS-Tricks, “Blocked aria-hidden on an element” — Durgesh Rajubhai Pawar, 12 Ağustos 2026

Aytaç Özdalgıç

Hakkında

Aytaç Özdalgıç

Full Stack Designer — Grafik Tasarım Yöneticisi, KJ Power

UX odaklı tasarım kararlarını yazılım mimarisiyle ilişkilendirerek sürdürülebilir dijital sistemler kurguluyorum. 20 yıla yakın kariyerimde, kullanıcı araştırmasından frontend’e uzanan uçtan uca ürün geliştirme süreçlerinde çalıştım.

Hakkımda daha fazlası →

Bir Yorum Yazın

Aytaç Özdalgıç sitesinden daha fazla şey keşfedin

Okumaya devam etmek ve tüm arşive erişim kazanmak için hemen abone olun.

Okumaya Devam Edin