Abdulaziz Akyol

HTML5 anlamsal etiketler rehberi: header, main, article, section

HTML5 · Yazılım geliştirme
1 Ekim 2018 · 8 dk okuma · Abdulaziz Akyol

Anlamsal (semantic) HTML, içeriği görünüşüne göre değil ne olduğuna göre işaretlemektir: gezinme bağlantıları <nav>, sayfanın asıl içeriği <main>, tek başına anlamlı bir yazı <article> ile. Bu etiketler tarayıcıya, ekran okuyuculara ve arama motorlarına sayfanın yapısını açıkça anlatır; görünümü ise yine CSS belirler.

Bu rehber, 2018’de beş ayrı parça hâlinde yazdığım anlamsal web notlarının birleştirilmiş ve güncellenmiş hâlidir. Eski notlardaki bazı bilgiler artık yanlış: <dialog> bir ipucu balonu değil, iç içe <h1> kullanımı önerilmiyor, eski tarayıcılar için yazılan CSS yamalarına gerek kalmadı. Genel çerçeve için önce HTML5 nedir? yazısına göz atabilirsiniz.

Anlamsal etiket nedir, div’den farkı ne?

HTML5 öncesinde sayfa bölümleri şöyle ayrılıyordu:

<div id="header">Başlık</div>
<div id="content">İçerik</div>
<div id="footer">Alt bilgi</div>

Buradaki anlam yalnızca standart olmayan id değerinde yaşıyor; tarayıcı açısından üçü de anlamsız kutudur. <div> ve <span> bugün de geçerli etiketlerdir, ama yalnızca stil ya da yerleşim için sarmalayıcı gerektiğinde kullanılmalıdır.

Anlamsal etiketlerin asıl kazancı görünmez: her birinin tarayıcının erişilebilirlik ağacına aktarılan örtük bir rolü vardır. <nav> “gezinme”, <main> “ana içerik” olarak bildirilir. Ekran okuyucu kullanıcısı bu bölgeler arasında tek tuşla atlayabilir.

Sayfa iskeleti: yapısal etiketler nasıl birlikte kullanılır?

Tipik bir blog yazısı sayfasının doğru iskeleti şöyledir:

<body>
  <header>
    <a href="/">Site adı</a>
    <nav aria-label="Ana menü">
      <ul>
        <li><a href="/blog/" aria-current="page">Blog</a></li>
        <li><a href="/iletisim/">İletişim</a></li>
      </ul>
    </nav>
  </header>

  <main>
    <article>
      <header>
        <h1>Mevcut kameralarla görüntü analitiği</h1>
        <p>Yayın: <time datetime="2026-09-14">14 Eylül 2026</time></p>
      </header>

      <section aria-labelledby="zincir-baslik">
        <h2 id="zincir-baslik">Akıştan olaya zincir</h2>
        <p>Zincir beş halkadan oluşur...</p>
        <figure>
          <img src="/img/zincir.webp" width="800" height="450"
               alt="Kamera, GPU sunucusu ve olay çıkışını gösteren akış şeması">
          <figcaption>Şekil 1 – Akıştan olaya beş halka</figcaption>
        </figure>
      </section>

      <footer>
        <p>Yazar: Abdulaziz Akyol</p>
      </footer>
    </article>
  </main>

  <aside aria-label="İlgili yazılar">
    <h2>İlgili yazılar</h2>
    <ul>
      <li><a href="/blog/html-5-form/">HTML5 formlar</a></li>
    </ul>
  </aside>

  <footer>
    <p>&copy; 2026 Site adı</p>
  </footer>
</body>

Şimdi etiketleri tek tek, doğru ve yanlış kullanımlarıyla ele alalım.

<header>: giriş bölümü

<header>, sayfanın ya da bir bölümün giriş içeriğini taşır: logo, başlık, yazar ve tarih bilgisi, arama kutusu. Sayfada birden fazla olabilir; yukarıdaki örnekte biri sitenin, biri yazının başlığıdır. <head> ile karıştırılmamalıdır: <head> meta verileri, <header> görünür içeriği tutar. Doğrudan <body> bağlamındaki <header> ekran okuyuculara banner bölgesi olarak bildirilir; <article> ya da <section> içindeki ise bildirilmez.

<nav>, sitenin ya da sayfanın önemli gezinme bağlantılarını gruplar: ana menü, içindekiler, sayfalama, ekmek kırıntısı (breadcrumb). Alt bilgideki her bağlantı öbeği için <nav> gerekmez. Sayfada birden çok <nav> varsa her birine aria-label ile ayırt edici bir ad verin (“Ana menü”, “İçindekiler”). Bağlantıları eski notumdaki gibi dikey çizgiyle ayırmak yerine liste (<ul>) içinde verin; ekran okuyucu böylece “5 öğeli liste” diye bilgi verir.

<main>: sayfanın asıl içeriği

<main>, sayfayı diğer sayfalardan ayıran benzersiz içeriği kapsar; site başlığı, menü ve alt bilgi dışarıda kalır. Standarda göre bir belgede hidden olmayan yalnızca bir <main> bulunabilir ve <main>, <article>, <aside>, <header>, <footer> ya da <nav> içine yerleştirilemez. “İçeriğe geç” bağlantısının hedefi olarak <main id="icerik"> idealdir.

<article>: tek başına anlamlı içerik

<article>, sayfadan koparılıp başka bir yerde yayımlansa da anlamlı kalan içeriği temsil eder: blog yazısı, haber, forum iletisi, kullanıcı yorumu, ürün kartı. Kullandığım basit test şu: “Bu parça bir RSS akışında tek başına gösterilse anlaşılır mı?” Yorumlar, yazının <article>’ı içinde iç içe <article> olarak işaretlenebilir.

<section>: başlıklı tematik bölüm

<section>, genellikle bir başlığı olan tematik bir içerik grubudur: bir yazının “Kurulum” bölümü, bir ana sayfanın “Hizmetler” kısmı. En sık hata, <section>’ı stil sarmalayıcısı olarak kullanmaktır; o iş <div>’indir. <section> yalnızca erişilebilir bir adı olduğunda (örneğin aria-labelledby ile başlığına bağlandığında) region bölgesi olarak bildirilir.

<aside>: yan içerik

<aside>, ana içerikle ilgili ama ondan ayrılabilecek içeriği tutar: kenar çubuğu, ilgili yazılar, sözlük kutusu, yazar kartı. Eski notumdaki Ayder örneğinde <h4> etiketi </p> ile kapatılmıştı; doğru hâli <aside><h2>Ayder Kaplıcaları</h2><p>...</p></aside> biçimindedir. W3C’nin landmark önerilerine göre tamamlayıcı (complementary) bölgeler diğer bölgelerin içine değil, üst düzeye konmalıdır.

<footer>, en yakın <article>, <section> ya da sayfanın alt bilgisidir: yazar, telif, ilgili bağlantılar, iletişim. İletişim bilgisi için içinde <address> kullanılabilir. <body> bağlamındaki <footer> contentinfo bölgesi olarak bildirilir.

<figure> ve <figcaption>: başlıklı bağımsız içerik

<figure>, ana metinde atıf yapılan ve yeri değişse de akışı bozmayan içeriği kapsar: görsel, diyagram, kod listesi, tablo, alıntı. <figcaption> ilk ya da son çocuk olarak açıklamayı verir. Her görseli <figure>’a sarmak gerekmez. alt ile figcaption farklı işler görür: alt görseli göremeyen için onun yerine geçer, figcaption herkes için ek açıklamadır.

<search> ve <hgroup>

Yeni öğelerden <search>, arama ve filtreleme formlarını sarar ve search bölgesi olarak bildirilir; MDN’e göre Ekim 2023’ten beri tüm büyük tarayıcılarda çalışıyor. <hgroup> ise yeniden tanımlandı: artık bir başlık (h1–h6) ile onun alt başlığı ya da üst başlığı olan <p> öğelerini gruplar.

Başlık hiyerarşisi: “document outline” efsanesi

Eski HTML5 taslakları, iç içe <section>’larda her bölümün kendi <h1>’iyle başlayabileceğini ve seviyenin otomatik hesaplanacağını öngörüyordu. Bu “belge ana hattı algoritması” hiçbir tarayıcıda ve ekran okuyucuda uygulanmadı ve standarttan çıkarıldı. MDN’in belirttiğine göre iç içe bölümlerde birden çok <h1> artık uygunsuz sayılıyor; Mayıs 2025’te de bu tür <h1>’lerin küçültülerek gösterildiği varsayılan tarayıcı stili standarttan kaldırıldı.

Kural basit: sayfada tek <h1>, altında seviye atlamadan <h2>, <h3>. Başlık seviyesini görünüşe göre değil hiyerarşiye göre seçin; boyutu CSS ile ayarlayın.

Landmark’lar: ekran okuyucu kullanıcıları sayfada nasıl gezinir?

Ekran okuyucular kısayol tuşlarıyla ya da bölge listesiyle doğrudan belirli bir bölgeye atlamayı sağlar; eşleşmelerin resmî tablosu W3C’nin HTML-AAM belgesindedir. Bu bölgeleri (landmark) ayrıca ARIA yazmadan, doğru etiketle elde edersiniz:

Etiket Örtük ARIA rolü Koşul
<header> banner article, aside, main, nav, section içinde değilse
<nav> navigation Her zaman
<main> main Her zaman
<aside> complementary body ya da main düzeyinde; bir bölüm içindeyse erişilebilir adı varsa
<footer> contentinfo header ile aynı koşul
<section> region Erişilebilir adı varsa
<form> form Erişilebilir adı varsa
<search> search Her zaman

<nav role="navigation"> gibi örtük rolü tekrar yazmak gereksizdir; asıl önemli olan, aynı türden bölgeleri aria-label ile ayırt etmektir.

Metin düzeyinde anlamsal etiketler

Eski notlarda “yapısal olmayan anlamsal etiketler” diye ayırdığım bu grup, satır içi içeriğe anlam katar.

<time>: makinenin okuyabileceği tarih

<time>, insanın okuyacağı metni datetime özniteliğindeki standart biçimle eşler. Eski notumdaki 2013-12-18T21:00-22:00 değeri geçersizdi; saat dilimi +03:00 biçiminde yazılır:

<p>Toplantı <time datetime="2026-10-14T14:00+03:00">14 Ekim Çarşamba 14.00'te</time> başlıyor.</p>
<p>Yazı <time datetime="2026-09-25">25 Eylül 2026</time> tarihinde güncellendi.</p>
<p>Eğitim süresi: <time datetime="PT2H30M">iki buçuk saat</time></p>

<mark>: bağlama göre vurgulama

<mark>, metnin o anki bağlamda ilgili kısmını işaretler; tipik kullanım arama sonuçlarında aranan kelimeyi vurgulamaktır. Önem için <strong>, vurgu için <em> kullanın; ekran okuyucuların çoğu <mark>’ı varsayılan olarak duyurmaz.

<details> ve <summary>: JavaScript’siz aç-kapa

<details name="sss" open>
  <summary>Bu özellik hangi tarayıcılarda çalışır?</summary>
  <p>Güncel tüm büyük tarayıcılarda çalışır.</p>
</details>
<details name="sss">
  <summary>Klavye ile kullanılabilir mi?</summary>
  <p>Evet; summary odaklanabilir ve Enter ile açılıp kapanır.</p>
</details>

<summary> metni aç-kapa denetiminin etiketi olur ve klavye erişimi hazır gelir. Aynı name değerini taşıyan <details> öğelerinden aynı anda yalnızca biri açık kalır; bu özelliği desteklemeyen eski bir tarayıcıda panellerin hepsi açılabilir, yani geri düşüş zararsızdır.

<dialog>: gerçek modal pencere

Eski notumda <dialog> üzerine gelince açılan bir ipucu gibi anlatılmıştı; bu yanlış. <dialog>, showModal() ile açıldığında sayfanın geri kalanını etkisiz (inert) kılan, Esc ile kapanan, odağı yöneten gerçek bir modal penceredir:

<button type="button" id="ac">Ayrıntıları göster</button>

<dialog id="ayrinti" aria-labelledby="ayrinti-baslik">
  <h2 id="ayrinti-baslik">Kalibrasyon ayrıntıları</h2>
  <p>Ayarları kaydetmek istiyor musunuz?</p>
  <form method="dialog">
    <button value="iptal">Vazgeç</button>
    <button value="tamam" autofocus>Kaydet</button>
  </form>
</dialog>

<script>
  const dialog = document.getElementById("ayrinti");
  document.getElementById("ac").addEventListener("click", () => dialog.showModal());
  dialog.addEventListener("close", () => {
    console.log("Kullanıcının seçimi:", dialog.returnValue);
  });
</script>

method="dialog" olan form gönderildiğinde pencere kapanır ve basılan düğmenin value değeri returnValue’ya yazılır. Arka plan ::backdrop sözde öğesiyle biçimlendirilir. Aralık 2025’ten beri Baseline olan invoker commands ile <button commandfor="ayrinti" command="show-modal"> yazarak JavaScript’siz de açabilirsiniz; eski tarayıcıları da desteklemeniz gerekiyorsa yukarıdaki betiği koruyun.

<progress> ve <meter>: ilerleme ve ölçüm

İkisi birbirine benzer görünür ama anlamları farklıdır. <progress> bir görevin tamamlanma durumunu, <meter> bilinen bir aralıktaki ölçümü (disk doluluğu, parola gücü) gösterir:

<label for="yukleme">Dosya yükleniyor:</label>
<progress id="yukleme" max="100" value="0">%0</progress>

<label for="disk">Disk kullanımı:</label>
<meter id="disk" min="0" max="100" low="70" high="90" optimum="10" value="82">%82</meter>

<script>
  const bar = document.getElementById("yukleme");
  let yuzde = 0;
  const zamanlayici = setInterval(() => {
    yuzde += 10;
    bar.value = yuzde;
    bar.textContent = `%${yuzde}`;
    if (yuzde >= 100) clearInterval(zamanlayici);
  }, 300);
</script>

value verilmeyen <progress> belirsiz (süresi bilinmeyen) ilerleme olarak gösterilir. <meter>’da low, high ve optimum değerleri tarayıcının çubuğu hangi renkte göstereceğini belirler.

<bdi>: yön yalıtımı

<bdi>, yönü bilinmeyen metni çevresinden yalıtır. Eski notumdaki “Onur Can” örneği sorunu göstermiyordu, çünkü iki taraf da soldan sağa yazılıyor. Sorun sağdan sola yazılan bir ad araya girdiğinde çıkar:

<ul>
  <li>Kullanıcı <bdi>أحمد</bdi>: 3 yorum</li>
  <li>Kullanıcı <bdi>Ayşe</bdi>: 5 yorum</li>
</ul>

<bdi> olmadan tarayıcının çift yönlü metin algoritması, Arapça adın yanındaki “:” ve “3” karakterlerini yanlış tarafa dizebilir.

Diğerleri

<abbr title="..."> kısaltmayı açar, <data value="..."> makine değeri taşır, <wbr> uzun kelimelerde olası satır sonu noktası önerir, <ruby> ile <rt> Doğu Asya dillerinde okunuş notu ekler.

Anlamsal HTML SEO’yu nasıl etkiler?

Dürüst cevap: <div> yerine <article> yazmak tek başına sıralamayı yükseltmez. Ama arama motorlarının ve yapay zekâ asistanlarının işini kolaylaştıran şeyler anlamsal yapının içindedir: tek ve açıklayıcı bir <h1>, mantıklı başlık hiyerarşisi, <main> ile ayrılmış asıl içerik, <time datetime> ile açık tarih ve anlamlı bağlantı metinleri. Zengin sonuçlar için ayrıca JSON-LD yapısal verisi gerekir.

Sık yapılan hatalar

  • <section>’ı stil kabı olarak kullanmak. Başlığı olmayan, yalnızca CSS için eklenmiş <section> yerine <div> kullanın.
  • Birden fazla görünür <main>. Tek sayfa uygulamalarında eski görünümü hidden ile gizlemeyi unutmayın.
  • Her bağlantı grubunu <nav> yapmak. Bölge listesi kalabalıklaşır, işe yaramaz hâle gelir.
  • Başlık seviyesini görünüşe göre seçmek. Küçük olduğu için <h4> kullanmak hiyerarşiyi bozar.
  • Tıklanabilir <div>. Eylem için <button>, gezinme için <a href> kullanın.
  • Eski tarayıcı yamaları. article, section { display: block; } gibi CSS ve html5shiv betikleri bugün gereksizdir.

Formlardaki anlamsal yapı ve etiketleme için HTML5 formlar rehberine, medya öğelerini <figure> içinde kullanmak için HTML5 video ve audio rehberine bakabilirsiniz. <canvas> içeriği ekran okuyuculara görünmediği için ona nasıl alternatif metin verileceğini de Canvas rehberinde anlattım.

Kontrol listesi

  • Sayfada tek görünür <main> ve tek <h1> var; başlıklar seviye atlamıyor.
  • Site başlığı ve alt bilgisi <body> düzeyinde <header> ve <footer> içinde.
  • Birden fazla <nav> ya da <aside> varsa her birinin aria-label’ı var.
  • <section> yalnızca başlıklı tematik bölümler için; stil sarmalayıcıları <div>.
  • Tarihler <time datetime> ile, modal pencereler <dialog> ile, aç-kapa içerik <details> ile işaretli.

Sık sorulan sorular

section ile div arasındaki fark nedir?

section, kendi başlığı olan tematik bir içerik bölümünü temsil eder ve erişilebilir bir adı varsa ekran okuyuculara bölge (region) olarak bildirilir. div ise hiçbir anlam taşımayan genel bir kaptır. Yalnızca stil ya da yerleşim için bir sarmalayıcıya ihtiyacınız varsa div kullanın.

Bir sayfada birden fazla h1 kullanılabilir mi?

Standart birden fazla h1'e izin verir, ancak iç içe bölümlerde h1 kullanıp seviyenin otomatik hesaplanmasını beklemek artık uygunsuz kabul ediliyor. En iyi uygulama sayfada tek h1 kullanmak ve alt başlıkları seviye atlamadan h2, h3 diye sürdürmektir.

Anlamsal HTML SEO'ya etki eder mi?

Etiketin adı tek başına sıralamayı yükseltmez. Ancak net başlık hiyerarşisi, main ve article ile ayrılmış ana içerik ve anlamlı bağlantı metinleri, arama motorlarının ve yapay zekâ asistanlarının sayfayı doğru anlamasını kolaylaştırır. Zengin sonuçlar için ayrıca yapısal veri gerekir.

article ile section ne zaman kullanılır?

İçerik sayfadan koparılıp tek başına yayımlandığında anlamlı kalıyorsa article kullanın: blog yazısı, yorum, ürün kartı gibi. Bir bütünün başlıklı parçasıysa, örneğin bir yazının Kurulum bölümü ise section kullanın.

Kaynaklar

  1. WHATWG HTML Standard — Sections (header, nav, article, section, aside, footer, hgroup) html.spec.whatwg.org
  2. WHATWG HTML Standard — Grouping content (main, figure, figcaption) html.spec.whatwg.org
  3. W3C — HTML Accessibility API Mappings (HTML-AAM) w3.org
  4. W3C WAI-ARIA Authoring Practices — Landmark Regions w3.org
  5. MDN — Heading elements (h1–h6) developer.mozilla.org
  6. MDN — The dialog element developer.mozilla.org

HTML5Anlamsal HTMLLandmarkErişilebilirlikARIASEOMarkdown sürümü

İletişim

Konuşalım.