Erişilebilirlik29 Nisan 202610 dk okuma

Form Etiketleri: Dönüşümü Sessiz Sessiz Düşüren Hata

Bir form kullanılabilir olmadan önce kullanıcının her alanın ne istediğini bilmesi gerekir. Görenler için bu bilgi etikettir; ekran okuyucu kullanıcısı için ise etiket programatik olarak alana bağlanmış olduğunda çalışır. axe-core'un label kuralı, formdaki hangi alanların bu bağı kuramamış olduğunu yakalar.

1. label hatası nedir?

Kural, form kontrollerinin (<input>, <select>, <textarea>) erişilebilir bir ada sahip olup olmadığını kontrol eder. Erişilebilir adın gelebileceği dört kaynak vardır:

  1. Bir <label> öğesinin for niteliğiyle alana bağlanmış olması
  2. Alanın bir <label> içinde sarmalanmış olması (implicit label)
  3. Alanın aria-label niteliği taşıması
  4. Alanın aria-labelledby ile başka bir öğeye referans vermesi

Bunlardan hiçbiri yoksa label kuralı tetiklenir. Bu, WCAG 2.1 1.3.1 Info and Relationships ve 4.1.2 Name, Role, Value kriterlerinin doğrudan ihlalidir.

2. Neden önemli?

Etiketsiz bir form alanı, klavye veya ekran okuyucu kullanıcısı için duvardır. Tab tuşuyla alana ulaşıldığında ekran okuyucu yalnızca alanın türünü söyler — “edit, blank” — ama o alana ne yazılması gerektiğini bilmez.

Konu erişilebilirlikle de bitmiyor. Etiket-alan bağı, mobil cihazlarda dokunma alanını da büyütür: kullanıcı sadece input'a değil, etiketin de yazılı olduğu alana dokunduğunda alan odaklanır. Bu, küçük checkbox'ları büyük parmaklarla işaretlemeyi mümkün kılar. Yani etiket, sadece engelliler için değil, herkes için kullanılabilirliği artırır.

Formlar bir sitenin para kazanma noktasıdır. Sepete ekle, üye ol, abone ol — hepsi form. Yanlış etiketlenmiş bir form alanı dönüşüm oranını doğrudan düşürür.

3. Hangi durumlarda tetiklenir?

  1. Etiketsiz alan: <input type="text" name="email"> tek başına; yanında bir <label> yok.
  2. for/id eşleşmesi tutmuyor: <label for="mail"> ama input'ta id="email". Görsel olarak yan yana gösterilse de tarayıcı bunu etiket sayar.
  3. Sadece placeholder var, etiket yok: En yaygın anti-pattern. Placeholder kullanıcı yazmaya başladığı anda kaybolur ve geriye hatırlatıcı kalmaz.
  4. Etiket görünmüyor ama bağlanmış: Geliştirici display: none uygulamış. Görsel olarak gizli, ekran okuyucu için de gizli; iki taraf da kaybetti.
  5. Aynı id'ye birden fazla label bağlı: Bu durum WCAG'ın form-field-multiple-labels kuralını tetikler ve okuyucuda kafa karışıklığı yaratır.

4. Doğru çözümler

4.1 for/id ile bağlama (önerilen)

En güvenli ve en geniş uyumluluğa sahip yöntem. Etiket tıklandığında alan odaklanır; ekran okuyucu doğru sırayla okur.

Yanlış / WrongEtiketsiz
<input type="email" name="email" placeholder="E-posta">
Doğru / Right
<label for="email">E-posta</label>
<input id="email" type="email" name="email">

4.2 Sarmalayan label (implicit)

for/id ilişkisi kurmak istemezseniz <label> içine alanı doğrudan sarabilirsiniz. Daha kısadır ama bazı yardımcı teknolojilerde for/id kadar tutarlı desteklenmez. Yine de geçerli bir yoldur.

Doğru / Right
<label>
  E-posta
  <input type="email" name="email">
</label>

4.3 Görsel olarak gizli etiket

Tasarım gereği etiketin yazılı görünmesini istemediğiniz durumlarda (arama kutuları gibi), etiketi görsel olarak gizleyin ama erişilebilirlik ağacında bırakın. display:none kullanmayın — o etiketi tamamen kaybeder.

Doğru / Rightsr-only sınıfı + ikon görsel olarak rolü açıklar
<form role="search">
  <label for="search-q" class="sr-only">Sitede ara</label>
  <input id="search-q" type="search" name="q" placeholder="Ara…">
  <button type="submit" aria-label="Ara">
    <svg aria-hidden="true">...</svg>
  </button>
</form>

<style>
  .sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }
</style>

4.4 Placeholder etiketin yerini almaz

Yanlış / Wrong
<input type="email" placeholder="E-posta adresiniz">
Doğru / RightEtiket görünür kalır, placeholder örnek değer gösterir
<label for="email">E-posta adresi</label>
<input
  id="email"
  type="email"
  placeholder="[email protected]"
>

4.5 Bir grup form alanı (radyo, checkbox)

Birden fazla alanın aynı soruyu yanıtladığı durumlarda her alanın etiketi yetmez — grubun da bir adı olmalıdır. <fieldset> ve <legend> bu işin standart yoludur.

Doğru / Right
<fieldset>
  <legend>Kargo seçeneği</legend>

  <label>
    <input type="radio" name="ship" value="standard">
    Standart (3-5 gün) — Ücretsiz
  </label>

  <label>
    <input type="radio" name="ship" value="express">
    Hızlı (1-2 gün) — 49 TL
  </label>
</fieldset>

4.6 React Hook Form / Formik

React form kütüphaneleri etiketleri otomatik üretmez; htmlFor (React'te for'un karşılığı) ve id'yi sizin eşleştirmeniz gerekir.

Doğru / RightReact Hook Form örneği
function EmailField() {
  const { register, formState: { errors } } = useFormContext();
  return (
    <div>
      <label htmlFor="email">E-posta adresi</label>
      <input
        id="email"
        type="email"
        aria-invalid={errors.email ? "true" : "false"}
        aria-describedby={errors.email ? "email-error" : undefined}
        {...register("email", { required: true })}
      />
      {errors.email && (
        <p id="email-error" role="alert">
          E-posta zorunlu.
        </p>
      )}
    </div>
  );
}

Hata mesajını da aria-describedby ile alana bağlayın. Böylece kullanıcı alana odaklandığında ekran okuyucu hem etiketi hem hatayı sırayla okur.

5. Zorunlu alanlar ve hata mesajları

Bir alanın zorunlu olduğunu sadece kırmızı bir yıldız ile göstermek yetmez; ekran okuyucu bunu duyamaz. required niteliğini ya da aria-required="true"'yi kullanın.

Doğru / RightGörsel + programatik zorunluluk göstergesi
<label for="phone">
  Telefon
  <span aria-hidden="true" class="text-red-600">*</span>
</label>
<input
  id="phone"
  type="tel"
  required
  aria-describedby="phone-help"
>
<p id="phone-help" class="text-sm text-slate-600">
  Zorunlu alan
</p>

6. Gözden kaçan durumlar

  • Çoklu label: Aynı id'ye iki <label> bağlamak ekran okuyucuda iki sesli okumaya sebep olur. Tek bir kanonik etiket bırakın.
  • Submit butonu “Gönder” değil: Genel buton metinleri form bağlamını kaçırır. Daha açıklayıcı olmaları gerekir: “Hesabımı oluştur”, “Bültene abone ol”, “Mesajı gönder” gibi.
  • Custom select bileşenleri: Kendi yazdığınız dropdown'lar <select> değildir; role="combobox" ve aria-labelledby ile etiketle birlikte tasarlanmaları gerekir.
  • Date / time pickerlar: Çoğu özel takvim bileşeni gerçek input'u gizler ve görselleri gösterir. Etiket gerçek input'a bağlanmalıdır.
  • Captcha alanı: reCAPTCHA gibi widget'lar kendi iframe'leri içinde çalışır; ana sayfanın label kuralından muaftır ama yine de kendi tarafında erişilebilir olmalıdır.

7. Nasıl test edilir?

  1. Tab ile gezinti: Mouse'u bırakın. Tab tuşuyla forma girip ekran okuyucuya kulak verin. “Edit” veya “blank” gibi tek kelimelik duyumlar varsa o alanın etiketi eksik.
  2. Etikete tıklama: Etikete tıkladığınızda ilgili alan odaklanmıyorsa for/id eşleşmesi kırılmıştır.
  3. axe DevTools / Lighthouse: Form alanlarındaki etiket eksikliklerini anında raporlar.
  4. Keysonar SEO Tools: Site genelinde tüm formları otomatik tarar, label, link-name ve button-name kurallarını birlikte raporlar.

8. Hızlı kontrol listesi

  • Her form alanına bir <label>, aria-label veya aria-labelledby bağlandı.
  • for/id eşleşmesi her alanda doğru.
  • Placeholder, etiketin yerine değil, örnek değer olarak kullanıldı.
  • Görsel olarak gizli etiketler için display:none yerine sr-only sınıfı kullanıldı.
  • Radyo/checkbox grupları <fieldset>+<legend> ile sarmalandı.
  • Zorunlu alanlar required veya aria-required ile işaretlendi (sadece görsel * yetmez).
  • Hata mesajları aria-describedby ile alana bağlandı.
  • Submit butonları form bağlamını yansıtan açıklayıcı metin taşıyor.
  • Custom dropdown / date picker bileşenleri label/role/aria ile erişilebilir hale getirildi.

9. Referanslar

  • WCAG 2.1 SC 1.3.1 — Info and Relationships — Level A
  • WCAG 2.1 SC 3.3.2 — Labels or Instructions — Level A
  • WCAG 2.1 SC 4.1.2 — Name, Role, Value — Level A
  • HTML Living Standard — The label element
  • WAI-ARIA Authoring Practices: Form patterns

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