tabindex global özniteliği bir öğenin odaklanabilir olup olmayacağını, Tab tuşuyla sırayla gezilirken bu sıraya girip girmeyeceğini ve sıradaki yerini belirler. Kısa cevap şudur: yalnızca 0 ve -1 değerlerini kullanın. tabindex="0" öğeyi belge sırasındaki yerinde Tab ile ulaşılabilir yapar; tabindex="-1" öğeyi Tab sırasına koymadan JavaScript ile odaklanabilir kılar. Sıfırdan büyük değerler sırayı bozar ve MDN tarafından önerilmez.

Bu yazıda tabindex değerlerinin tam davranışını, varsayılan olarak odaklanabilen öğeleri, div ile düğme yapmanın neden sorun olduğunu, menü gibi gruplu bileşenlerde "roving tabindex" tekniğini, autofocus ve accesskey özniteliklerini ve klavye erişiminin temel kurallarını MDN belgelerine göre anlatıyoruz. Genel erişilebilirlik ilkeleri için WCAG temelleri yazısına bakabilirsiniz.

tabindex değerleri ne anlama gelir?

tabindex değerleri ne anlama gelir? Öğenin platform kuralına göre (form denetimleri, bağlantılar evet), Negatif, genellikle -1, Evet, Pozitif, örneğin 3

tabindex bir tam sayı alır. Öğe çiziliyorsa ve geçerli herhangi bir tam sayı değeri varsa, JavaScript ile focus() çağrılarak ya da fareyle tıklanarak odaklanabilir. Değer yalnızca öğenin sıralı klavye gezintisinde, yani Tab ile ulaşılıp ulaşılamayacağını belirler:

tabindexFare veya focus() ile odakTab ile ulaşılır mı
YokÖğenin platform kuralına göre (form denetimleri, bağlantılar evet)Öğenin platform kuralına göre
Negatif, genellikle -1EvetHayır; odağı betik taşımalıdır
0EvetEvet, belgedeki konumuna göre ve pozitif değerlerden sonra
Pozitif, örneğin 3EvetEvet, değere göre sıralanır, 0 olanlardan önce gelir
Değersiz (tabindex)Tarayıcı belirlerTarayıcı belirler

Negatif değerlerde sayının kendisi önemli değildir; -1 yazmak yaygın kullanımdır. Pozitif değerlerde tabindex="4" taşıyan öğe 5 ve 0 olanlardan önce, 3 olandan sonra odaklanır. Aynı pozitif değeri paylaşan öğeler kendi aralarında kaynak sırasını izler. İzin verilen en büyük değer 32767'dir.

Neden pozitif tabindex kullanılmaz?

Pozitif değer taşıyan öğeler, sayfanın varsayılan etkileşimli öğelerinin önüne geçer. MDN'nin klavye bileşenleri rehberi bunun pratik sonucunu açıkça yazar: tek bir pozitif değer kullandığınız anda sayfadaki tüm odaklanabilir öğelerin değerlerini sizin belirlemeniz ve bakımını yapmanız gerekir. WCAG klavye sayfası da odak sırasının sayfanın mantıksal sırasından farklı olmasının yalnızca klavye kullanan kişilerin kafasını karıştırdığını vurgular.

Doğru yaklaşım, odaklanabilir öğeleri HTML kaynağında zaten mantıklı sırayla yazmaktır. MDN aynı uyarıyı odaklanabilir öğelerin sırasını görsel olarak değiştiren CSS özellikleri için de yapar: görsel sıra ile odak sırası ayrışırsa klavye ve yardımcı teknoloji kullanıcıları sayfada yollarını bulmakta zorlanır.

html
<!-- Kaçının: odak sırası 3, 1, 2 gibi karışır -->
<button tabindex="2">Kaydet</button>
<button tabindex="1">Önizle</button>
<button>İptal</button>

<!-- Tercih edin: sıra kaynaktaki sıradır -->
<button>Önizle</button>
<button>Kaydet</button>
<button>İptal</button>

Varsayılan olarak odaklanabilen öğeler

Bazı öğelere tarayıcı arka planda 0 değerinde bir tabindex verir. MDN listesi şöyledir: href taşıyan <a> ve <area>, <button>, <frame>, <iframe>, <input>, <object>, <select>, <textarea>, SVG a öğesi ve bir <details> öğesinin özetini veren <summary>. Bu öğelere, varsayılan davranışı değiştirmeyecekseniz tabindex eklemeyin; örneğin negatif değer vermek öğeyi odak sırasından çıkarır.

İki özel durum daha vardır. dialog öğesine tabindex eklenmemelidir; pencere etkileşimli değildir ve odak içindeki öğelere gider. button öğesindeki disabled ise düğmenin basılmasını ve odaklanmasını engeller. Ayrıca MDN'nin düğme sayfası, bir düğmeye tıklamanın onu odaklayıp odaklamadığının tarayıcıya ve işletim sistemine göre değiştiğini not eder.

tabindex="-1" ne zaman işe yarar?

tabindex="-1" ne zaman işe yarar?

MDN iki tipik örnek verir: ekrana geldiğinde odaklanması gereken ama Tab ile doğrudan ulaşılmaması gereken ekran dışı bir pencere ve hatalı bir form gönderildiğinde hemen odaklanması gereken bir hata mesajı. Aşağıdaki örnekte hata özeti normalde Tab sırasında yer almaz; form doğrulaması başarısız olunca betik focus() çağırır ve ekran okuyucu özeti okur.

html
<div id="hata-ozeti" tabindex="-1" hidden>
  <h2>Formda 2 hata var</h2>
  <ul>
    <li><a href="#eposta">E-posta adresi eksik</a></li>
    <li><a href="#telefon">Telefon numarası geçersiz</a></li>
  </ul>
</div>
javascript
const ozet = document.getElementById("hata-ozeti");
ozet.hidden = false;
ozet.focus(); // Tab sırasında değil ama odak alabilir

Programla odaklanan öğelerin de görünür bir odak halkası olmalıdır. Klavye bileşenleri rehberi, CSS outline özelliğinin koşulsuz olarak kaldırılmamasını, gereksiz halkaları önlemek gerekiyorsa :focus-visible sözde sınıfının kullanılmasını söyler. Hata mesajı tasarımının ayrıntıları form doğrulama yazısında.

div ile düğme yapmayın

MDN, etkileşimli olması amaçlanan ama etkileşimli içerik kategorisinde olmayan bir öğeyi tabindex ile klavyeden odaklanabilir yapmaktan kaçınmayı önerir. Tipik örnek, <button> yerine <div> ile yazılmış bir düğmedir. Etkileşimli olmayan öğelerle yazılmış bileşenler erişilebilirlik ağacında doğru biçimde listelenmez; bu da yardımcı teknolojilerin onlara ulaşmasını ve onları kullanmasını engeller. <a>, <button>, <details>, <input>, <select> ve <textarea> gibi öğeler yerleşik rol ve durumlarıyla gelir; aynı bilgiyi ARIA ile elle yönetmek zorunda kalmazsınız.

html
<!-- Sorunlu -->
<div class="dugme" tabindex="0">Sepete ekle</div>

<!-- Doğru -->
<button type="button">Sepete ekle</button>

Yerel bir karşılığı olmayan özel bir bileşen yazmak zorundaysanız WCAG klavye sayfasındaki kurallar geçerlidir: fareyle tıklanabilen her öğe klavyeyle de odaklanabilmeli ve kullanılabilmeli, klavye olay işleyicisi tıklama işleyicisiyle aynı işi yapmalıdır. tabindex yalnızca öğeyi gerçekten etkileşimli yaptıysanız, örneğin uygun klavye olaylarını tanımladıysanız eklenmelidir. Odaklanan her öğenin görünür bir odak stili olmalıdır.

Gruplu bileşenler ve roving tabindex

Menü, sekme listesi, ızgara ya da ağaç görünümü gibi gruplu bileşenlerde MDN şu düzeni önerir: kapsayıcı Tab sırasındadır (tabindex="0"), içindeki her seçenek, sekme, hücre ya da satır Tab sırasından çıkarılır (tabindex="-1"). Kullanıcı bileşene Tab ile girer, içinde ok tuşlarıyla gezinir. Böylece on maddelik bir menü, Tab ile geçilmesi gereken on ayrı durak yerine tek bir durak olur.

Kullanıcı bileşenden çıkıp geri döndüğünde odağın en son seçili maddeye dönmesi beklenir. Bunun için iki teknik vardır. Birincisi "roving tabindex": ok tuşuyla yeni bir maddeye geçildiğinde betik o maddeye odak verir, onun tabindex değerini 0, bir önceki maddeninkini -1 yapar. İkincisi aria-activedescendant: odak kapsayıcıda kalır, kapsayıcıdaki bu öznitelik "sanal" odağın hangi alt öğede olduğunu kimliğiyle gösterir.

html
<ul id="yazi-menusu" tabindex="0">
  <li id="yazi-sans" tabindex="-1">Sans-serif</li>
  <li id="yazi-serif" tabindex="-1">Serif</li>
  <li id="yazi-mono" tabindex="-1">Monospace</li>
</ul>

Bu iskelet yalnızca odak düzenini gösterir; ok tuşlarına yanıt veren ve tabindex değerlerini güncelleyen bir betik olmadan klavyeyle kullanılamaz. Devre dışı bir özel denetim için rehber, öğenin tabindex="-1" ile Tab sırasından çıkarılmasını; gruplu bir bileşendeki devre dışı maddelerin ise ok tuşlarıyla hâlâ ulaşılabilir kalmasını söyler. Rehber ayrıca odak değiştirmek için focus olayını elle tetiklemeyi değil, element.focus() çağırmayı önerir.

autofocus: sayfa açılınca odak

autofocus mantıksal bir global özniteliktir; öğenin sayfa yüklenince, ya da bir dialog veya popover içindeyse o katman gösterilince odak almasını sağlar. Bir belgede, bir <dialog> içinde ya da bir popover içinde bu özniteliği yalnızca bir öğe taşımalıdır; birden çok öğeye verilirse odaklanabilen ilk öğe odak alır. Öznitelik yalnızca form denetimlerine değil, örneğin contenteditable bir alana da uygulanabilir.

html
<form action="/ara">
  <label for="arama">Sitede ara</label>
  <input type="search" id="arama" name="q" autofocus>
</form>

Sayfa bir parça tanımlayıcısıyla (#bolum gibi) açılırsa ve bu parça bir öğeyi gösteriyorsa autofocus çalışmaz; odak genellikle parçanın gösterdiği öğeye gider. MDN erişilebilirlik açısından da uyarır: otomatik odak, ekran okuyucu kullanıcılarını önceden haber vermeden forma "ışınlar", sayfanın yüklenirken kaymasına ve dokunmatik cihazlarda ekran klavyesinin açılmasına yol açabilir. Ekran okuyucu odaklanan denetimin etiketini okur ama ondan önceki içeriği okumaz. Bu yüzden autofocus eklemeden önce kullanıcının gerçekten hemen o alanla çalışıp çalışmayacağını düşünün. MDN'nin dialog sayfası ise açılan bir pencerede kullanıcının ilk etkileşime gireceği öğeye autofocus verilmesini açıkça önerir.

accesskey: neden genellikle önerilmez?

accesskey öğe için bir klavye kısayolu oluşturulmasına ipucu verir. Değer tek bir yazdırılabilir karakter olmalıdır; klavyeyle üretilebilen aksanlı karakterler de buna dahildir. Kısayolun nasıl tetikleneceği tarayıcıya ve platforma göre değişir; MDN tablosunda örneğin Windows'ta Chrome ve Edge için Alt ile tuş, Firefox için Alt + Shift ile tuş birleşimi yer alır.

html
<p><b>Y</b>ardım düğmesi için kısayol tanımlandı.</p>
<button accesskey="y">Yardım</button>

MDN bu özniteliğin sorunlarını şöyle sıralar: değer sistemin, tarayıcının ya da yardımcı teknolojinin kendi kısayollarıyla çakışabilir; bazı değerler bazı klavyelerde, özellikle farklı dillerde bulunmayabilir; sayıya dayalı kısayollar işleviyle mantıksal bir bağ kurmadığı için bilişsel güçlük yaşayan kişileri şaşırtabilir; kullanıcı kısayolların varlığından haberdar edilmezse onları yanlışlıkla tetikleyebilir. Bu nedenlerle genel amaçlı web sitelerinin ve uygulamaların çoğunda accesskey kullanılmaması önerilir.

Odağı izlemek ve klavye olaylarını bağlamak

Özel bir bileşen yazdığınızda MDN'nin klavye bileşenleri rehberindeki birkaç genel kural işinizi kolaylaştırır. İlki, odak değişikliklerini izlemek için focus ve blur olaylarını dinlemektir; ama her odak değişikliğinin klavye ya da fare olayından geleceğini varsaymayın, çünkü ekran okuyucular gibi yardımcı teknolojiler odağı herhangi bir odaklanabilir öğeye taşıyabilir. Belgenin genelinde odak durumunu öğrenmek için document.activeElement ve document.hasFocus() kullanılabilir.

İkincisi, klavye ile fare aynı deneyimi üretmelidir. Ok tuşlarıyla gezinirken tabindex ya da stil güncelleyen kod, fareyle tıklamada da aynı değişikliği yapmalıdır. Fare olayına bağlanan her işleyici klavye olayına da bağlanmalıdır; rehberin örneğinde onclick ile çağrılan bir işlev, onkeydown içinde Enter tuşu kontrol edilerek de çağrılır. Üçüncüsü, bileşeniniz bir tuşu kendisi işliyorsa, örneğin ok tuşlarıyla gezinme, tarayıcının aynı tuşla sayfayı kaydırması gibi varsayılan davranışlar engellenmelidir. Son olarak rehber, keydown olayının tuş basılı tutulduğunda tekrar edip etmemesinin tarayıcıya ve işletim sistemine göre değiştiğini, bu davranışa güvenilmemesi gerektiğini not eder. Olay dinleyicilerinin yazımı için JavaScript öğrenme rehberine bakabilirsiniz.

Klavye erişimi için kontrol listesi

Klavye erişimi için kontrol listesi: Sayfa yalnızca klavyeyle eksiksiz kullanılabilmelidir., Odaklanabilen her öğe etkileşimli olmalı; kullanıcı onunla bir şey..., Tıklanabilen...
  • Sayfa yalnızca klavyeyle eksiksiz kullanılabilmelidir.
  • Odaklanabilen her öğe etkileşimli olmalı; kullanıcı onunla bir şey yapabilmelidir.
  • Tıklanabilen her öğe klavyeyle de odaklanabilmeli ve etkinleştirilebilmelidir.
  • Odak sırası kaynak sırasını izlemeli; pozitif tabindex kullanılmamalıdır.
  • Odaklanan öğenin görünür bir odak stili olmalıdır.
  • Geçici olarak kullanılamayan bölümler inert ile Tab sırasından ve erişilebilirlik ağacından çıkarılabilir.

Sık yapılan hatalar

  • Bağlantı ve düğmelere gereksiz yere tabindex="0" eklemek. Bu öğeler zaten odaklanabilir.
  • Sırayı düzeltmek için pozitif değerler vermek; kaynak sırasını düzeltin.
  • <div> veya <span> öğesine tabindex="0" verip klavye olayını unutmak; öğe odak alır ama Enter ile çalışmaz.
  • tabindex="-1" verilen öğenin Tab ile ulaşılabileceğini sanmak.
  • Birden çok öğeye autofocus vermek.
  • Odak halkasını CSS ile koşulsuz olarak kaldırmak.

Sık Sorulan Sorular

tabindex="0" ile tabindex="-1" arasındaki fark nedir?

İkisi de öğeyi fareyle ya da focus() ile odaklanabilir yapar. Fark Tab tuşundadır: 0 öğeyi kaynak sırasındaki yerinde Tab sırasına ekler, -1 eklemez.

Bir bağlantıyı Tab sırasından nasıl çıkarırım?

tabindex="-1" vermek bağlantıyı Tab sırasından çıkarır, ama bağlantı fareyle kullanılabilir kalır. Bölümün tamamı geçici olarak kullanılamıyorsa inert daha uygundur, çünkü odak, tıklama ve erişilebilirlik ağacını birlikte ele alır.

tabindex bir div öğesini düğmeye çevirir mi?

tabindex öğenin rolünü değiştirmez. MDN, etkileşimli olmayan öğelere tabindex vermenin onları erişilebilirlik ağacında etkileşimli bileşen olarak listelemediğini söyler; rol ve durum bilgisi için yerel etkileşimli öğeler ya da ARIA gerekir.

accesskey yerine ne kullanılabilir?

MDN'nin accesskey sayfası, ilgili konu olarak aria-keyshortcuts özniteliğini gösterir. Hangi yolu seçerseniz seçin, kısayolların varlığını kullanıcıya açıkça bildirmeniz gerekir.

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 · WCAG temelleri · ARIA nedir · hidden ve inert · dialog etiketi · button etiketi · global öznitelikler