
結論先講
語意化標籤(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>
工具:檢查自己做得好不好
- Chrome DevTools 的 Accessibility tab — 直接看 landmark 結構(
<main>、<nav>、<aside>等區域) - Lighthouse A11y 稽核 — 跑一次,95 分以下就要看哪裡缺語意
- 螢幕閱讀器實測 — Mac 內建 VoiceOver(Cmd+F5),用鍵盤跑一遍你的網站
- WAVE 擴充套件 — 視覺化顯示每個區塊的語意
相關文章
- HTML 結構基礎 — 入門層 HTML 介紹
- Technical SEO — 語意化標籤如何影響 SEO
- AEO 結構化資料 — JSON-LD Schema 跟語意化標籤的關係
- Frontend Roadmap — 回前端總索引
