ARIA (Accessible Rich Internet Applications), HTML öğelerine eklenen role ve aria-* öznitelikleriyle ekran okuyucu gibi yardımcı teknolojilere "bu öğe nedir, şu an hangi durumdadır, neyle ilişkilidir" bilgisini veren bir rol ve öznitelik kümesidir. Kısa cevap şudur: yerel bir HTML öğesi (<button>, <nav>, <progress>, <details> gibi) işinizi görüyorsa ARIA eklemeyin; yalnızca HTML'in karşılığını vermediği özel bileşenlerde ve dinamik durumlarda ARIA kullanın.
Bu yazıda ARIA'nın neyi değiştirip neyi değiştirmediğini, "ARIA'nın ilk kuralı"nı, altı rol kategorisini, durum ile özellik arasındaki farkı, aria-expanded, aria-pressed ve aria-hidden gibi sık kullanılan öznitelikleri çalışan örneklerle ele alıyoruz. Erişilebilir ad konusu (aria-label, aria-labelledby, aria-describedby) ayrı bir yazıda: erişilebilir ad rehberi. Serinin tamamı için HTML öğrenme rehberine bakabilirsiniz.
ARIA ne yapar, ne yapmaz?
Tarayıcı her sayfa için DOM'un yanında bir de erişilebilirlik ağacı oluşturur. Ekran okuyucular sayfayı bu ağaç üzerinden okur: her düğümün bir rolü (düğme, bağlantı, başlık), bir adı ("Kaydet") ve varsa durumu (basılı, açık, seçili) vardır. ARIA öznitelikleri yalnızca bu ağaçtaki bilgiyi değiştirir. MDN bunu açıkça vurgular: ARIA bir öğenin işlevini veya davranışını değiştirmez. role="button" yazdığınız bir <div> düğme gibi duyurulur ama klavyeyle odaklanmaz, Enter veya Boşluk tuşuyla tetiklenmez, form göndermez.
MDN'nin ARIA giriş sayfasındaki örnek bu farkı iyi gösterir. Anlamsız bir <div> öğesine role="progressbar", aria-valuemin, aria-valuemax ve aria-valuenow ekleyerek bir ilerleme çubuğu tarif edebilirsiniz. Ancak aria-valuenow değerini JavaScript ile sürekli güncellemek ve öğeyi CSS ile ilerleme çubuğu gibi göstermek sizin işinizdir. Aynı sonuç yerel öğeyle tek satırda elde edilir:
<!-- ARIA ile tarif edilen ilerleme cubugu: deger ve gorunum sizin sorumlulugunuzda -->
<div id="yukleme" role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100"></div>
<!-- Yerel oge: rol ve deger tarayicidan gelir -->
<progress id="yukleme2" value="75" max="100">%75</progress>MDN ayrıca <progress> öğesinde min özniteliğine izin verilmediğini, en küçük değerin her zaman 0 olduğunu not eder. <progress> ve <meter> öğelerinin ayrıntıları için progress, meter ve output yazısına bakın.
ARIA'nın ilk kuralı: önce yerel HTML
W3C'nin "Using ARIA" notundaki ilk kural, MDN'nin de alıntıladığı haliyle şöyle özetlenebilir: ihtiyaç duyduğunuz anlam ve davranışı zaten taşıyan bir HTML öğesi veya özniteliği varsa, başka bir öğeyi ARIA rolüyle kılık değiştirmek yerine o yerel öğeyi kullanın. Gerekçe basittir: yerel öğeler klavye erişimini, rolü ve durumu kendiliğinden getirir. ARIA seçtiğinizde ise tarayıcının yaptığı her şeyi betikle taklit etme sorumluluğu size geçer.
MDN bu kurala "kötü ARIA, hiç ARIA olmamasından kötüdür" sözünü de ekler ve WebAIM'in bir milyondan fazla ana sayfa üzerinde yaptığı taramaya atıf yapar: ARIA kullanılan ana sayfalarda, kullanılmayanlara göre ortalama yüzde 41 daha fazla hata tespit edilmiş. Bu, ARIA'nın zararlı olduğu anlamına gelmez; yanlış yerde kullanıldığında erişilebilirliği iyileştirmek yerine bozabileceğini gösterir.
Aşağıdaki iki düğme ekran okuyucuya aynı rolü bildirir, ama yalnızca ikincisi gerçek bir düğme gibi davranır:
<!-- Kotu: rol var, davranis yok. tabindex, click ve keydown isleyicileri elle eklenmeli -->
<div id="kaydet-div" role="button" tabindex="0">Kaydet</div>
<!-- Iyi: odaklanma, Enter ve Bosluk ile tetiklenme tarayicidan gelir -->
<button type="button" id="kaydet">Kaydet</button>MDN'nin button rolü sayfasına göre role="button" kullanırsanız öğeyi odaklanabilir yapmanız, click ve keydown olayları için işleyici yazmanız ve hem Enter hem de Boşluk tuşunu işlemeniz gerekir. Yerel <button> öğesinde click olayı fare tıklamasında da, odaktayken Boşluk veya Enter basıldığında da tetiklenir; <div> ya da <span> ile yapılan düğmede ise role="button" olsa bile yalnızca fare tıklamasında tetiklenir. Düğme türleri ve form davranışı için button etiketi yazısına göz atın.
ARIA rolleri: altı kategori

Rol, role="rol-adi" biçiminde eklenir ve öğenin ne tür bir arayüz parçası olduğunu söyler. HTML'deki birçok öğenin varsayılan bir rolü vardır; örneğin <input type="radio"> öğesinin rolü radiodur. Anlamsız <div> ve <span> öğelerinin ise ek bir anlam verilmedikçe rolü yoktur. MDN rolleri altı kategoride toplar:
| Kategori | Örnek roller | Not |
|---|---|---|
| Belge yapısı | toolbar, tooltip, feed, math, presentation/none, note | Çoğunun HTML karşılığı var (article, img, list, table, heading); onları kullanın |
| Bileşen (widget) | scrollbar, searchbox, slider, spinbutton, switch, tab, tabpanel, treeitem | Genellikle JavaScript ile etkileşim gerektirir |
| Bileşik bileşen | combobox, menu, menubar, tablist, tree, treegrid | Alt rollerle birlikte kullanılır |
| Yer işareti | banner, complementary, contentinfo, form, main, navigation, region, search | header, aside, footer, form, main, nav, section, search öğelerinin örtük rolleri |
| Canlı bölge | alert, log, marquee, status, timer | Dinamik değişiklikleri duyurur |
| Pencere | alertdialog, dialog | Sayfa içindeki alt pencereler |
| Soyut | command, composite, input, landmark, range, widget, window... | Yalnızca tarayıcılar içindir, içerikte kullanılmaz |
Tablo yedi satır gösteriyor çünkü MDN bileşik bileşenleri bileşen kategorisinin alt başlığı olarak verir. Soyut roller için WAI-ARIA belirtimi kesindir: içerik yazarları soyut rolleri kullanmamalıdır; kullansanız da yardımcı teknolojilere anlamlı bir bilgi geçmez. Yer işareti rollerinde ise MDN ölçülü olmayı önerir: çok sayıda yer işareti ekran okuyucuda "gürültü" yaratır ve sayfanın genel düzenini anlamayı zorlaştırır.
Bazı rollerin kendine özgü kuralları vardır. Bazıları belirli durum veya özelliklerle birlikte kullanılmak zorundadır, bazıları da yalnızca başka bir rolün içinde anlam taşır. MDN'nin uyarıcı örneği şudur: <ul role="tabpanel"> ekran okuyucuda "sekme paneli" olarak duyurulur; ama içinde gerçek sekmeler yoksa öğe aslında bir sekme paneli değildir ve erişilebilirlik iyileşmek yerine kötüleşir.
Durumlar ve özellikler: aria-* öznitelikleri
ARIA öznitelikleri iki gruba ayrılır. Özellikler (properties) bir bileşenin görece sabit niteliklerini anlatır: bir açılır menüsü olup olmadığı (aria-haspopup), zorunlu olup olmadığı (aria-required) veya hangi öğe tarafından etiketlendiği (aria-labelledby) gibi. Durumlar (states) ise etkileşim sırasında değişen bilgilerdir: işaretli mi (aria-checked), devre dışı mı (aria-disabled), açık mı (aria-expanded), basılı mı (aria-pressed). Durumlar değiştikçe değerlerini betikle güncellemek zorundasınız; aksi halde ekran okuyucu eski bilgiyi okur.
MDN ARIA özniteliklerini dört kategoride listeler: bileşen öznitelikleri (aria-checked, aria-disabled, aria-expanded, aria-invalid, aria-valuenow gibi), canlı bölge öznitelikleri (aria-live, aria-atomic, aria-relevant, aria-busy), sürükle bırak öznitelikleri (aria-dropeffect, aria-grabbed) ve ilişki öznitelikleri (aria-controls, aria-describedby, aria-labelledby, aria-owns, aria-activedescendant gibi).
Bunların bir kısmı "global" özniteliktir; yani rol verilmiş olsun ya da olmasın her HTML öğesinde kullanılabilir. aria-describedby, aria-hidden, aria-live, aria-label ve aria-labelledby bu gruptadır. Tek istisna: aria-label ve aria-labelledby, presentation rolüne ve onun eş anlamlısı none rolüne sahip öğelerde kullanılamaz. Canlı bölgeler ve aria-live için WCAG temelleri yazısındaki bölüme bakın.
Uygulamalı örnek: aria-expanded ile aç-kapa düğmesi
Bir düğme başka bir içeriği gösterip gizliyorsa, MDN'ye göre düğmeye aria-controls ile kontrol edilen öğenin id değerini, aria-expanded ile de o anki durumu yazmalısınız. Aşağıdaki örnek MDN'nin kullanıcı adı yardım örneğinden uyarlandı. Görünür bir metni olmayan "?" düğmesine aria-label ile ad veriliyor, simge karakteri aria-hidden="true" ile erişilebilir addan çıkarılıyor ve açıklama paragrafı başlangıçta hidden ile gizleniyor:
<label for="kullanici">Kullanıcı adı</label>
<input id="kullanici" name="kullanici" aria-describedby="kullanici-aciklama" />
<button type="button" aria-expanded="false" aria-controls="kullanici-aciklama" aria-label="Kullanıcı adı hakkında yardım">
<span aria-hidden="true">?</span>
</button>
<p id="kullanici-aciklama" hidden>
Kullanıcı adı, bu hizmete giriş yaparken kullandığınız addır.
</p>Düğmeye basıldığında hem paragrafın hidden özniteliğini kaldırmanız hem de aria-expanded değerini true yapmanız gerekir. ARIA bunu sizin yerinize yapmaz:
const dugme = document.querySelector("[aria-controls='kullanici-aciklama']");
const aciklama = document.getElementById("kullanici-aciklama");
dugme.addEventListener("click", () => {
const acik = dugme.getAttribute("aria-expanded") === "true";
dugme.setAttribute("aria-expanded", String(!acik));
aciklama.hidden = acik;
});MDN'nin bir uyarısını da not edin: aria-expanded özniteliğinin varlığı, öğenin başka bir şeyi kontrol ettiğini bildirir. Hiçbir şeyi açıp kapatmayan öğelere bu özniteliği eklemeyin. Ağaç görünümündeki uç düğümler için de aynı kural geçerlidir; alt düğümü olmayan bir treeitem öğesine aria-expanded verirseniz yardımcı teknoloji onu yanlışlıkla üst düğüm sanır. Betik gerektirmeyen bir aç-kapa için details ve summary öğeleri çoğu zaman daha iyi bir başlangıçtır. JavaScript tarafını öğrenmek isterseniz JavaScript öğrenme rehberi yardımcı olur.
Geçiş düğmesi: aria-pressed
aria-pressed, bir düğmeyi iki konumlu bir geçiş düğmesine (toggle button) dönüştürür. Değer false ise düğme basılı değildir, true ise basılıdır, mixed ise kısmen basılıdır (örneğin kontrol ettiği diğer düğmeler farklı durumdaysa). Öznitelik hiç yoksa düğme geçiş düğmesi değildir. Yerel <button> öğesine role eklemeden doğrudan aria-pressed yazabilirsiniz:
<button type="button" aria-pressed="false">Sesi kapat</button>MDN burada önemli bir tasarım kuralı verir: geçiş düğmesinin etiketi durum değiştiğinde değişmemelidir. Etiket "Sesi kapat" olarak kalır, ekran okuyucu durumu ayrıca "basılı" ya da "basılı değil" diye bildirir. Tasarımınız etiketin "Sesi kapat" ile "Sesi aç" arasında değişmesini istiyorsa bu bir geçiş düğmesi değildir ve aria-pressed kullanılmamalıdır; aksi halde kullanıcı "Sesi aç, basılı" gibi çelişkili bir duyuru duyar.
Rol, içeriği ve öğenin ömrünü de etkiler
Bazı roller alt öğelerin anlamını siler. MDN'nin button rolü sayfasına göre erişilebilirlik API'leri bir düğmenin içinde anlamlı öğeleri temsil edemez; bu yüzden tarayıcılar button rolündeki bir öğenin bütün alt öğelerine otomatik olarak presentation rolü uygular. <div role="button"><h3>Başlık</h3></div> yazdığınızda ekran okuyucu kullanıcısı için o başlık yoktur; erişilebilirlik ağacında yalnızca "Başlık" metnini taşıyan bir düğme kalır.
İkinci kural rolün değişmemesidir. MDN'nin bileşen rehberi, yerinde düzenleme (inline edit) örneğini verir: "görüntüleme" modunda salt okunur bir <input> öğesine button rolü verip "düzenleme" moduna geçince rolü kaldırmak cazip görünebilir. Bunu yapmayın. Rol değişecekse öğeyi kaldırıp yeni rolü taşıyan başka bir öğeyle değiştirin: görüntüleme modu için button rolü verilmiş bir öğe, düzenleme modu için ayrı bir metin <input> öğesi.
Klavye: rol vermek yetmez
MDN'nin bileşen rehberine göre ARIA ile yapılmış bir bileşende klavye davranışı şöyle olmalıdır: Tab tuşu bileşenin bütününe odak vermeli (bir menü çubuğuna Tab ile gelince odak ilk menü öğesine atlamamalı), ok tuşları bileşenin içinde gezinmeyi sağlamalı, form dışındaki bir bileşende Enter ve Boşluk denetimi etkinleştirmeli, bir formun içinde ise Boşluk denetimi etkinleştirirken Enter formun varsayılan eylemini göndermelidir. Emin olmadığınızda masaüstündeki eşdeğer denetimin davranışını taklit edin. Odak sırası ve tabindex değerleri için tabindex ve klavye erişimi yazısını okuyun.
Sık yapılan ARIA hataları

- Yerel öğe varken rol kullanmak:
<button>yerinediv role="button",<a>yerinespan role="link",<h2>yerinediv role="heading"gibi. MDN bu rollerin çoğu için "kullanmaktan kaçının" der. - Örtük rolü tekrar etmek:
<nav role="navigation">veya<main role="main">yazmak bir şey kazandırmaz. - Durumu güncellememek:
aria-expanded="false"ile başlayıp içerik açıldığında değeritrueyapmamak. - Soyut rolleri kullanmak:
role="widget",role="input"veyarole="landmark"içerikte geçersizdir. - Odaklanabilir öğeyi
aria-hidden="true"ile gizlemek. - Bir rolün gerektirdiği yapıyı kurmamak: içinde
tabrolleri olmayan birtablist,optioniçermeyen birlistboxgibi. - Bağlantıya
role="button"verip yalnızca Enter'ı işlemek: MDN, düğmelerin Boşluk tuşuyla da tetiklenmesinin beklendiğini, bu yüzden Boşluk için de bir işleyici gerektiğini hatırlatır.
ARIA'yı gerçek yardımcı teknolojiyle test edin
MDN'ye göre ARIA desteği işletim sistemine, tarayıcıya, yardımcı teknolojinin türüne ve bunların sürümlerine göre değişir; eski yazılımlar bazı rolleri hiç desteklemeyebilir veya yanlış bildirebilir. Yardımcı teknoloji kullanan bazı kişiler, alıştıkları düzeni kaybetme kaygısıyla yazılımlarını güncellemekte isteksiz olabilir. Bu da yine semantik HTML'i öne çıkarır, çünkü yerel öğelerin desteği çok daha geniştir. Yazdığınız ARIA'yı gerçek bir ekran okuyucuyla deneyin; MDN tarayıcı emülatörlerinin ve simülatörlerin tam desteği ölçmek için yeterli olmadığını belirtir. Genel erişilebilirlik ilkeleri için WCAG temelleri yazısı iyi bir sonraki adımdır.
Sık Sorulan Sorular
ARIA eklemek sayfayı otomatik olarak erişilebilir yapar mı?
Hayır. ARIA yalnızca erişilebilirlik ağacındaki bilgiyi değiştirir; odaklanma, klavye ile tetikleme ve durum güncellemesi gibi davranışları sizin eklemeniz gerekir. Yanlış kullanılan ARIA, hiç kullanılmamasından daha çok sorun çıkarabilir.
Hangi durumlarda ARIA gerçekten gerekir?
HTML'de karşılığı olmayan bileşenlerde (sekme listesi, ağaç görünümü, araç çubuğu, birleşik kutu gibi), yerel öğelerin taşımadığı durum bilgisinde (bir düğmenin açtığı içeriğin açık olup olmadığı) ve dinamik güncellemelerin duyurulmasında (canlı bölgeler) ARIA gerekir.
role="presentation" ile aria-hidden="true" arasındaki fark nedir?
role="presentation" öğenin anlamını kaldırır ama içeriğini ekran okuyucuya açık bırakır. aria-hidden="true" öğeyi içeriğiyle birlikte erişilebilirlik ağacından tamamen çıkarır.
<code><button></code> öğesine role="button" yazmalı mıyım?
Gerek yoktur. <button> öğesinin örtük rolü zaten buttondur. Aynı şey <nav>, <main>, <ul> ve diğer anlamlı öğeler için de geçerlidir.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: HTML öğrenme rehberi · aria-label, aria-labelledby, aria-describedby · WCAG temelleri · semantik etiketler · tabindex ve klavye erişimi · hidden ve inert
