Erişilebilirlik29 Nisan 20269 dk okuma

Bağlantı İsimleri: “link, link, link” Sorununu Bitirmek

Bir bağlantı, kullanıcıyı başka bir yere götürür; ama nereye götürdüğünü söylemiyorsa o sadece bir tuzaktır. Ekran okuyucu “link” deyip geçer ve kullanıcı tıklamak zorunda mı, yoksa zaman kaybı mı, bilemez. axe-core'un link-name kuralı, sayfanızdaki bağlantıların hangilerinin bu sessizlik içinde olduğunu yakalar.

1. link-name hatası nedir?

axe-core'un link-name kuralı, sayfadaki <a> öğelerinin (ve role="link" taşıyan diğer öğelerin) bir erişilebilir ada sahip olup olmadığını kontrol eder. Erişilebilir ad, ekran okuyucunun bağlantıya geldiğinde sesli olarak söylediği metindir. Yoksa cihaz yalnızca “link” der ve kullanıcı bağlantının nereye gittiğini bilemez.

Bu kural, WCAG 2.1 2.4.4 Link Purpose (In Context) ve 4.1.2 Name, Role, Value kriterlerinin doğrudan karşılığıdır. İkisi de A seviyesi yani uyumluluğun en alt eşiğinde.

2. Neden önemli?

Görme engelli kullanıcıların büyük çoğunluğu sayfayı baştan sona okumaz; bunun yerine ekran okuyucunun “tüm bağlantıları listele” (NVDA: Ins+F7, JAWS: Ins+F7, VoiceOver: Ctrl+Opt+U) modunu kullanır. Bu listede bağlantılar ad sırasına göre dizilir. Üç tane “Devamını oku”, beş tane “Buraya tıkla” ve dört adet adsız bağlantı varsa kullanıcının elinde içerikten ayrı, anlamsız bir liste vardır.

Adı olmayan bir bağlantı, klavye odağı sırasında da görünmez kalır. Kullanıcı Tab tuşuyla geçtiğinde ekran okuyucudan tek duyduğu “link” olur ve o bağlantıya gerçekten gitmek isteyip istemediğini bilemez.

3. Hangi durumlarda tetiklenir?

Crawl verisinde tekrar tekrar gördüğümüz beş senaryo:

  1. İçi tamamen boş bağlantı: Genellikle “skip link” veya anchor olarak kullanılan ama erişilebilir adı eklenmemiş <a href="#main"></a>.
  2. Yalnızca ikon barındıran bağlantı: Sosyal medya butonları, paylaşım simgeleri, “daha fazlası” oklarının çoğu bu kategoride. İçinde yalnızca SVG vardır, metin yoktur.
  3. Yalnızca görsel barındıran bağlantı: İçindeki <img> öğesinin alt niteliği boş olduğunda bağlantı tamamen sessizleşir. E-ticarette ürün kartlarında çok sık görülen bir hata.
  4. aria-hidden ile gizlenmiş tek metin: Tasarımcı görsel düzeni bozmasın diye metni aria-hidden ile saklamış ama yerine bir alternatif eklememiş.
  5. Dekoratif olduğu varsayılarak işaretlenmiş bağlantı: aria-hidden="true" bir bağlantıya konursa kullanıcı odaklanabilir ama ne olduğunu duyamaz; bu çelişki “focusable but invisible” hatasını tetikler.

4. Doğru çözümler

4.1 Sosyal medya ikonlu bağlantı

Footer'daki Twitter, Instagram, LinkedIn ikonları neredeyse her sitede aynı hatayı yapar: SVG dışında metin yoktur, ekran okuyucu sırayla “link, link, link” der. Çözümün özü, ya bağlantıya bir aria-label eklemek ya da görsel olarak gizli bir metin koymaktır.

Yanlış / WrongEkran okuyucu: 'link'
<a href="https://twitter.com/keysonar">
  <svg viewBox="0 0 24 24">...</svg>
</a>
Doğru / RightEkran okuyucu: 'Twitter'da bizi takip edin, link'
<a
  href="https://twitter.com/keysonar"
  aria-label="Twitter'da bizi takip edin"
>
  <svg aria-hidden="true" viewBox="0 0 24 24">...</svg>
</a>

4.2 Görselle sarılı kart bağlantısı

Ürün kartları genellikle bir görsel ve hemen altında ürün adıyla fiyat içerir. Hem görsel hem de yazı aynı bağlantı içine sarılır. Bu durumda görselin alt metnini boş bırakın — yazı zaten erişilebilir adı sağlayacaktır.

Yanlış / WrongÜrün adı 2 kez okunur: önce alt, sonra metin
<a href="/p/123">
  <img src="/p/123.jpg" alt="iPhone 15 Pro 256GB">
  <h3>iPhone 15 Pro 256GB</h3>
  <p>89.999 TL</p>
</a>
Doğru / Rightalt boş; metin bağlantının adını sağlar
<a href="/p/123">
  <img src="/p/123.jpg" alt="">
  <h3>iPhone 15 Pro 256GB</h3>
  <p>89.999 TL</p>
</a>

4.3 “Devamını oku” / “Daha fazla” tarzı bağlantılar

Listelerde aynı yazıyla tekrar eden bağlantılar (her makalenin sonunda “Devamını oku”) link-name kuralını teknik olarak geçer ama WCAG 2.4.4 açısından kötü bir deneyim yaratır. Çözümün iki yolu vardır:

Doğru / RightYöntem 1: aria-label ile hedefin başlığını ekle
<a
  href="/blog/seo-temelleri"
  aria-label="SEO temelleri yazısının devamını oku"
>
  Devamını oku
  <span aria-hidden="true"> →</span>
</a>
Doğru / RightYöntem 2: aria-labelledby ile çevresindeki başlığa referans ver
<article>
  <h2 id="post-101">SEO temelleri</h2>
  <p>...</p>
  <a href="/blog/seo-temelleri" aria-labelledby="post-101">
    Devamını oku
  </a>
</article>

4.4 Skip link ve anchor bağlantıları

Erişilebilirlik için vazgeçilmez olan “ana içeriğe atla” bağlantısı görsel olarak gizlenir ama erişilebilirlik ağacında metin taşımalıdır. Bu bağlantı odak alana kadar ekrandan saklı tutulur.

Doğru / RightSayfa başına eklenen skip link örneği
<a href="#main" class="skip-link">
  Ana içeriğe atla
</a>

<style>
  .skip-link {
    position: absolute;
    left: -9999px;
    top: auto;
  }
  .skip-link:focus {
    left: 1rem;
    top: 1rem;
    z-index: 999;
    background: #000;
    color: #fff;
    padding: 0.5rem 1rem;
  }
</style>

4.5 React / Next.js bağlantıları

Yanlış / Wrongİkonlu link, ad yok
<Link href="/cart">
  <ShoppingCart className="w-5 h-5" />
</Link>
Doğru / RightÇevrilmiş aria-label kullanımı
<Link href="/cart" aria-label={t("nav.cart")}>
  <ShoppingCart aria-hidden className="w-5 h-5" />
</Link>

Çok dilli sitelerde aria-label'ı sayfanın aktif diliyle aynı dilden alın. Türkçe bir sayfada sabitlenmiş İngilizce "Cart" etiketi, ekran okuyucuda İngilizce telaffuzla “kart” gibi okunur ve kullanıcı için anlamsızlaşır.

5. Erişilebilir ad nasıl belirlenir?

Tarayıcı, bir bağlantının adını şu öncelik sırasına göre hesaplar; ilk dolu olan değer kullanılır:

  1. aria-labelledby
  2. aria-label
  3. Bağlantının kendi içerdiği metin (yazı, img alt, vb.)
  4. title özniteliği — son çare
Yanlış / WrongEkranda 'Hesabım' ama ekran okuyucuda 'Profil'
<a href="/account" aria-label="Profil">
  Hesabım
</a>
Doğru / Right
<a href="/account">Hesabım</a>

6. Gözden kaçan durumlar

  • Boş hedefli bağlantılar: href="#" veya javascript:void(0) kullanılan “sahte” bağlantılar. Bunlar gerçekte buton olarak çalışıyorsa <button>'a dönüştürülmelidir; yine de ad mecburi.
  • Aynı sayfada aynı isimli farklı linkler: “Detay” sözcüğü on yerde geçiyorsa, ekran okuyucu kullanıcısı bunlardan hangisinin hangi içerik için olduğunu ayırt edemez. aria-label ile her birine bağlam ekleyin.
  • Bağlantıların içine sarılmış buton/menü: <a><button>...</button></a> HTML'de geçersizdir ve hangi öğenin gerçekte tıklanabilir olduğu belirsizleşir. axe-core bunu çoğu zaman yakalar; tasarım aşamasında ayrıştırın.
  • Yeni sekmede açılan bağlantılar: target="_blank" tek başına yeterli değil; kullanıcıya yeni sekmede açılacağını da söyleyin: aria-label="... (yeni sekmede açılır)”.
  • title özniteliği: Dokunmatik cihazlarda görünmez ve ekran okuyucularda tutarsızdır. Erişilebilir ad kaynağı olarak title'a güvenmeyin.

7. Nasıl test edilir?

  1. Ekran okuyucu link listesi: NVDA'da Ins+F7, VoiceOver'da Ctrl+Opt+U. Listede “link”, “tıkla” veya tekrar eden adlar varsa düzeltilmesi gereken bağlantı vardır.
  2. axe DevTools: Tarayıcı eklentisi tek sayfayı anında tarar; geliştirme sırasında en hızlı geri bildirim aracı.
  3. Keysonar SEO Tools: Sitenin tamamını otomatik tarar, link-name hatası olan tüm sayfaları listeler ve zaman içindeki gerilemeleri takip eder. Tek tek DevTools açmadan tüm rapor doğrudan panelden alınabilir.
  4. Klavye yalnızca testi: Mouse'u bırakın, sadece Tab tuşuyla sayfayı gezin. Odak hangi bağlantıdayken “ne ifade ettiğini bilmiyorum” diyorsanız, o bağlantıda bir ad eksik demektir.

8. Hızlı kontrol listesi

  • Her <a> öğesi ya görünür metin ya aria-label ya da aria-labelledby içeriyor.
  • Yalnızca ikondan oluşan bağlantılar sayfa diliyle aynı dilde aria-label taşıyor.
  • İçinde <img> bulunan bağlantıların ya alt'ı dolu ya da metni var; ikisi varsa alt boş bırakıldı.
  • 'Devamını oku' tarzı tekrarlayan bağlantılar bağlamı içeren bir aria-label/aria-labelledby ile ayrıştırıldı.
  • Sayfanın başında 'ana içeriğe atla' skip link'i var ve odaklanınca görünür hale geliyor.
  • Yeni sekmede açılan bağlantılar bunu kullanıcıya bildiriyor.
  • Görünür metni olan bağlantıya gereksiz yere aria-label EKLENMEDİ.
  • Sahte (#, javascript:void(0)) bağlantılar gerçek butona dönüştürüldü.

9. Referanslar

  • WCAG 2.1 SC 2.4.4 — Link Purpose (In Context) — Level A
  • WCAG 2.1 SC 4.1.2 — Name, Role, Value — Level A
  • WCAG 2.1 SC 2.4.9 — Link Purpose (Link Only) — Level AAA
  • HTML Living Standard — The a element
  • WAI-ARIA Authoring Practices: Link pattern

Sitenizdeki erişilebilirlik hatalarını otomatik tespit edin

Keysonar SEO Tools tüm sayfalarınızı tarar, button-name dahil 90+ axe kuralını kontrol eder ve etkilenen sayfaların tam listesini verir.

Ücretsiz başla