HTML’in En İyi Saklanan Sırrı: <output> Etiketi

HTML’in En İyi Saklanan Sırrı: <output> Etiketi

Her geliştirici \’ı bilir. Web’in iş atı odur.

Peki \? Çoğu hiç dokunmamıştır. Hatta varlığından haberi olmayanlar bile vardır.

Bu biraz yazık. Çünkü yıllardır \ ve ARIA ile yamaladığımız bir şeyi çözüyor: değeri değiştikçe ekran okuyuculara varsayılan olarak duyurulan dinamik sonuçlar.

Yıllardır spesifikasyonda. Ama gözümüzün önünde saklanıyor.

HTML5 spesifikasyonu şöyle diyor:

> \ elementi uygulama tarafından yapılan bir hesaplamanın ya da bir kullanıcı eyleminin sonucunu temsil eder.

Erişilebilirlik ağacında role="status" olarak eşlenir. Basitçe söylemek gerekirse, değeri değiştiğinde sanki üzerinde aria-live="polite" aria-atomic="true" varmış gibi duyurulur.

Pratikte bu şu anlama gelir: güncellemeler kullanıcıyı bölmez. Kısa bir süre sonra okunur ve sadece değişen parça değil, tüm içerik seslendirilir. İsterseniz kendi ARIA özelliklerinizle bu davranışı ezebilirsiniz.

Kullanımı son derece basit:

html
<output>Dinamik değer buraya gelir</output>

Hepsi bu. Yerleşik yardımcı teknoloji desteği. Ezberlenecek ek öznitelikler yok. HTML’in tasarlandığı gibi çalışması.

Keşif anım

\’u çok adımlı bir form içeren bir erişilebilirlik projesinde keşfettim. Formdaki alanlar değiştikçe bir risk puanı güncelleniyordu. Tarayıcıda her şey kusursuz görünüyordu ama ekran okuyucu kullanıcıları puanın değiştiğini fark edemiyordu.

Bir ARIA live region eklemek sorunu çözdü. Ama ben her zaman önce semantik HTML’e uzanmayı savundum ve live region’lar çoğu zaman bir yama gibi gelir.

Sonra spesifikasyonu didikledim ve \ gözüme çarptı. Form olmadan da “formu” anlıyordu ve değişiklikleri yerel olarak duyuruyordu. Meğer en basit çözüm en başından beri spesifikasyondaymış.

Neden kullanmıyoruz?

Çünkü unuttuk. Çoğu eğitimde geçmiyor. Gösterişli görünmüyor. GitHub’daki açık kaynak depolarda aradığımda neredeyse hiç yoktu.

Desenlerde ve bileşen kütüphanelerinde de çoğu kez es geçiliyor. Bu da bir geri besleme döngüsü oluşturuyor: kimse öğretmiyorsa kimse kullanmıyor.

Bilmeniz gereken birkaç şey

  • for özniteliği vardır: \ gibi, for="" özniteliğine sonucun bağlı olduğu \ öğelerinin id’lerini boşlukla ayırarak yazarsınız:

html
<input id="a" type="number" /> + <input id="b" type="number" /> =
<output for="a b"></output>

Çoğu kullanıcı için görsel olarak bir şey değişmez. Ama erişilebilirlik ağacında semantik bir bağ kurar; yardımcı teknoloji kullanıcıları girdiler ile hesaplanan sonuç arasındaki ilişkiyi kavrar.

  • \ gerektirmez: Kullanıcı girdilerine dayalı olarak sayfada dinamik metin güncellediğiniz her yerde kullanılabilir.
  • Varsayılan olarak satır içidir: Dolayısıyla düzeninize uygun şekilde \ ya da \ gibi stillendirmeniz gerekebilir.
  • 2008’den beri spesifikasyonda: Tarayıcılar ve ekran okuyucular arasında desteği çok iyidir. React veya Vue gibi herhangi bir framework ile de gayet uyumlu çalışır.
  • Güncelleme 7 Eki 2025: Bazı ekran okuyucuların \ güncellemelerini her zaman duyurmadığı gözlemlendi. Destek iyileşene kadar role="status" özniteliğini özellikle vurgulamak iyi bir fikir olabilir: \.
  • Bildirimler için değil: \ kullanıcı girdilerine/eylemlerine bağlı sonuçlar içindir; “toast” gibi genel sistem bildirimleri için değil. Bunlar, hesaplanmış bir çıktı değil “sistem geri bildirimi” olduğundan, generic bir öğe üzerinde role="status" veya role="alert" ile daha iyi yönetilir.

Gerçek dünya örnekleri

Basit hesap makinesi

20 dakikalık bir kodlama egzersizinde sonuçları göstermek için \ kullandım. Tek bir ARIA rolü eklemeden ekran okuyucu her güncellemeyi anında duyurdu. Hile yok, yama yok.

Aralık kaydırıcısı (range) biçimlendirme

Volvo Cars’ta, slider değerlerini kullanıcı dostu biçimde gösterdik. İçeride slider 10000 tutarken, çıktıda 10,000 miles/year gösteriliyordu. Slider ve \’u role="group" olan bir kapsayıcıda ve paylaşılan bir etiketle sardık; ortaya tutarlı bir React bileşeni çıktı:

jsx
<div role="group" aria-labelledby="mileage-label">
  <label id="mileage-label" htmlFor="mileage">
    Annual mileage
  </label>
  <input
    id="mileage"
    name="mileage"
    type="range"
    value={mileage}
    onChange={(e)=> setMileage(Number(e.target.value))}
  />
  <output name="formattedMileage" htmlFor="mileage">
    {mileage.toLocaleString()} miles/year
  </output>
  {/ Not: Bazı ekran okuyucular için güvenli tarafta kalmak adına /}
  {/ <output role="status" name="formattedMileage" htmlFor="mileage"> ... </output> /}
  {/ da kullanılabilir. /}
</div>

Form doğrulama geri bildirimi

Şifre gücü göstergeleri ve gerçek zamanlı doğrulama mesajları \ ile harika çalışıyor.

html
<label for="password">Şifre</label>
<input type="password" id="password" name="password" />
<output for="password">
  Şifre gücü: Güçlü
  <!-- Not: Daha geniş uyumluluk için <output role="status"> da tercih edilebilir. -->
</output>

Sunucuda hesaplanan çıktı? Sorun değil.

\ modern kalıplara da cuk oturur: API’lerden fiyat çekip vergi hesaplamak veya sunucu-üretimli öneriler göstermek gibi.

Aşağıda, bir kargo ücreti hesaplayıcı \’u güncelliyor; ücret hesaplandığında kullanıcıyı bilgilendiriyor:

jsx
import { useEffect, useState } from "react";

export function ShippingCalculator() {
  const [weight, setWeight] = useState("");
  const [price, setPrice] = useState("");

  useEffect(() => {
    if (weight) {
      // Paket ağırlığına göre sunucudan kargo ücretini çek
      fetch(/api/shipping?weight=${weight})
        .then((res) => res.json())
        .then((data) => setPrice(data.price))
        .catch(() => setPrice(""));
    }
  }, [weight]);

  return (
    <form>
      <label>
        Paket ağırlığı (kg):
        <input
          type="number"
          name="weight"
          value={weight}
          onChange={(e)=> setWeight(e.target.value)}
        />
      </label>

      <output name="price" htmlFor="weight" role="status">
        {price ? Tahmini kargo: $${price} : "Hesaplanıyor..."}
      </output>
    </form>
  );
}

---

Web platform özellikleri, frontend mimarisi, performans ve erişilebilir arayüzler hakkında yazıyorum. Ayda bir e-posta, spam yok.

Memnuniyet garantisi

Bir işi için tasarlanmış yerel bir HTML elementini kullanmak tatmin edici; özellikle daha az kodla daha erişilebilir bir arayüz sağlıyorsa.

\ belki de HTML’in en iyi saklanan sırrı. Ve böyle keşifler, spesifikasyonda hâlâ ne kadar değer saklı olduğunu gösteriyor.

Bazen en iyi araç, varlığından bile haberdar olmadığınız o araçtır.

Makale Bilgileri

Yazar: İsmail Hakkı Eren
İlgili Yazılar