cover

結論先講

語意化標籤(Semantic HTML)不是 <div> 的花俏版。它是:

  • SEO 的基礎 — Google 爬蟲靠標籤判斷內容結構,<article><div class="article"> 對爬蟲完全不同
  • 無障礙的基礎 — 螢幕閱讀器靠 <nav><main><aside> 幫視障使用者跳到頁面的正確區塊
  • 維護性的基礎 — 半年後回頭看自己的 code,<article> 立刻知道是內容區,<div class="a"> 要查 CSS 才知道

用語意化標籤不是「美德」,是成本最低的專業表現。你改 class 名稱要改 100 次,改 <div><article> 一次搞定,還順便解決了 SEO 和 a11y。


為什麼有 <div> 還要搞這一堆標籤

早年 HTML 只有 <div> 跟 class 命名這條路。結果是:

<!-- 2010 年的網頁長這樣 -->
<div class="header">
  <div class="nav">...</div>
</div>
<div class="main-content">
  <div class="article">
    <div class="title">...</div>
    <div class="body">...</div>
  </div>
  <div class="sidebar">...</div>
</div>
<div class="footer">...</div>

每個團隊 class 命名都不一樣:有人用 header、有人用 site-header、有人用 top-bar。爬蟲跟螢幕閱讀器看到這堆 <div> 完全不知道哪個是導覽、哪個是主內容

HTML5 給了一組語意標籤,強制統一語彙

<!-- 現在應該長這樣 -->
<header>
  <nav>...</nav>
</header>
<main>
  <article>
    <h1>...</h1>
    <section>...</section>
  </article>
  <aside>...</aside>
</main>
<footer>...</footer>

標籤名稱就是意圖,不用猜 class。


頁面結構六大標籤

記住這六個就解決 80% 的語意化問題:

標籤用途一頁幾個
<header>區塊的頁首(不只是網頁頁首,<article> 也可以有自己的 header)多個
<nav>主要導覽連結區通常 1~2 個
<main>頁面主要內容(扣掉 header/nav/sidebar/footer 之後的那塊)1 個
<article>可獨立存在的內容(部落格文章、留言、商品卡)多個
<section>主題相關的內容區塊(需要有標題)多個
<aside>跟主內容不直接相關的旁邊內容(側欄、廣告、相關文章)多個
<footer>區塊的頁尾多個

關鍵原則

  • <main> 一頁只能有一個(且不能被 <article><aside><header><footer><nav> 包起來)
  • <header> / <footer> 可以有多個(網頁一個、每個 <article> 也可以各自一個)
  • <section> 必須有標題<h1>~<h6>),不然就用 <div>

<article> vs <section> vs <div> 決策樹

這是最多人搞錯的地方。用這棵樹判斷:

這個區塊可以獨立存在嗎?(單獨拿出來仍有意義,像 RSS 訂閱一篇文)
├── 是 → <article>
└── 否
    └── 這個區塊在語意上是一個主題的獨立段落嗎?
        ├── 是,且有自己的標題 → <section>
        └── 否 → <div>(純粹為了 CSS 或 JS 需要的容器)

實例對照

情境用哪個為什麼
部落格單篇文章<article>可以獨立訂閱、分享
留言板的每則留言<article>每則留言可獨立呈現
電商商品卡<article>可獨立分享、加購物車
頁面的「關於我們」區段<section>頁面的一個主題段落,但不能獨立存在
「最新消息」區段<section>同上
純 CSS 排版容器(例如 flex 的 wrapper)<div>沒有語意,純版面需要

常見誤用

全部都用 <section>:很多人把 <section> 當萬用 <div>。如果你的區塊沒有 <h1>~<h6> 標題,用 <div> 就好。

整個頁面包一個 <article><article> 是「內容單元」,不是「頁面」。一篇部落格文章是 <article>,但一個「部落格列表頁」不是。

<header> 只用在網頁最上面:每個 <article> 都可以有自己的 <header> 放作者、發文日期、標籤。


標題階層 <h1> ~ <h6>

語意化另一個重點:標題要有階層

舊規則(HTML4):一頁只能一個 <h1>

這是為了 SEO。Google 把 <h1> 當主題。

HTML5 爭議:每個 <article><section> 可以自己有 <h1>

HTML5 規範想導入「outlining 演算法」,讓每個 sectioning element 都自成一個標題層級。但瀏覽器沒真的實作這個演算法,螢幕閱讀器大多也沒跟進。

實戰建議

保守派做法(推薦)

  • 一個頁面只有一個 <h1>(通常是 <main> 裡的主標題)
  • <article> 的標題用 <h2>
  • <article> 內部的分段用 <h3><h4>

這種做法跟 SEO、螢幕閱讀器都相容,不需要賭 outlining 演算法會不會被實作。


文字語意標籤

這組很容易被當成「CSS 樣式」使用。別這樣做。

標籤語意常被誤用成
<strong>重要性純粹加粗(應該用 CSS font-weight
<em>語意強調(讀出來會加重音)純粹斜體(應該用 CSS font-style
<b>視覺加粗(不帶重要性,例如產品名)應該用 CSS
<i>視覺斜體(不帶強調,例如外來語)應該用 CSS
<mark>螢光筆標記(搜尋結果高亮)
<code>程式碼片段
<kbd>鍵盤按鍵

判斷原則

  • 「這段文字重要」→ <strong>
  • 「這段文字要強調讀出來」→ <em>
  • 「我只想要視覺上粗體/斜體」→ 用 CSS

列表與圖片語意

列表

  • <ul> — 無序列表(項目順序不重要)
  • <ol> — 有序列表(步驟、排名、順序很重要)
  • <dl> — 定義列表(專有名詞 + 解釋,用 <dt> 當 term、<dd> 當 description)

範例:

<dl>
  <dt>HTML</dt>
  <dd>HyperText Markup Language</dd>
  <dt>CSS</dt>
  <dd>Cascading Style Sheets</dd>
</dl>

圖片

<figure>
  <img src="..." alt="...">
  <figcaption>圖 1:前端架構五層示意圖</figcaption>
</figure>

<figure> 是「有語意的圖片容器」,<figcaption> 是圖片說明。這組合 SEO 跟 a11y 都會好。


表單語意(完整細節見 F01-03 表單原生行為

快速 checklist:

  • <label> 必須連結 <input>(用 for 或用 label 包起來)
  • 相關的 input 用 <fieldset> + <legend> 包起來
  • 用對 <input type="...">(email、tel、url、date、number),別全用 text

實戰 Checklist

拿這個清單對照你的網頁:

  • 頁面有且只有一個 <main>
  • 所有導覽連結都在 <nav>
  • 每篇內容獨立的區塊用 <article>
  • 所有 <section> 都有標題
  • 標題階層沒有跳級(<h1><h3> 不跳過 <h2>
  • <strong> / <em> 是有語意地用,不是為了樣式
  • 所有圖片有 alt(空的 alt="" 也比沒有好,代表裝飾圖)
  • <label> 都關聯到對應的 <input>

工具:檢查自己做得好不好

  1. Chrome DevTools 的 Accessibility tab — 直接看 landmark 結構(<main><nav><aside> 等區域)
  2. Lighthouse A11y 稽核 — 跑一次,95 分以下就要看哪裡缺語意
  3. 螢幕閱讀器實測 — Mac 內建 VoiceOver(Cmd+F5),用鍵盤跑一遍你的網站
  4. WAVE 擴充套件 — 視覺化顯示每個區塊的語意

相關文章