💡 文章重點摘要:在前端切版與 Code Review 時,最常聽到兩個極端派別的爭論:一派認為「HTML5 header 字面上就是標題,裡面只能放
<h1>~<h6>」;另一派則把整個頁面的側邊欄、彈出視窗甚至頁尾連結通通塞進<header>。究竟<header>的標準內部結構長怎樣?本文將依據 WHATWG 最新規範,帶你一次掌握品牌 Logo、<nav>主導覽列、現代<search>搜尋標籤與<hgroup>副標題群組的黃金組合!
如果你已經讀過前一篇《HTML header 標籤與 head 的致命混淆》,相信你已經明白 <header> 是位於 <body> 內部的視覺與語意門面。但在實際動手切版時,許多工程師面對 HTML5 header 內部該放哪些元素依然充滿疑問:「全站搜尋框放進 <header> 合規嗎?」、「文章的副標題跟作者日期寫在 <header> 裡該用 <h2> 還是 <p>?」、「為什麼把網站 Logo 包進 <h1> 會害慘內頁 SEO?」
今天我們就直接對照 WHATWG HTML Living Standard 與 W3C 無障礙規範,將 <header> 的內部解剖圖與合法巢狀邊界一次拆解到位!
⚡ 快速簡單使用(30 秒複製即用範本)
以下提供兩組最常使用的生產級 HTML5 header 標準範本(包含「全站頂部導覽橫幅」與「單篇文章標頭含副標題」),可直接複製至專案中修改套用:
<!-- 範本 A:全站頂部橫幅 Header(含 Logo、主導覽列 nav 與現代 HTML5 search 搜尋框) -->
<header class="site-header">
<!-- 1. 品牌識別區:內頁請直接用 <a> 包裹 Logo,把全頁唯一 <h1> 留給下方的文章主標題! -->
<a href="/" class="brand-logo" aria-label="Sean 技術筆記首頁">
<img src="/assets/logo.svg" alt="Sean 技術筆記" width="140" height="36">
</a>
<!-- 2. 主導覽列:使用 <nav> 建立導覽子地標 (role="navigation") -->
<nav aria-label="主選單">
<ul role="list">
<li><a href="/html" aria-current="page">HTML 專欄</a></li>
<li><a href="/css">CSS 實戰</a></li>
<li><a href="/seo">SEO 指南</a></li>
</ul>
</nav>
<!-- 3. 站內搜尋框:使用現代 HTML5 <search> 標籤自動建立搜尋子地標 (role="search") -->
<search aria-label="全站文章搜尋">
<form action="/search" method="get">
<label for="global-search" class="visually-hidden">搜尋技術文章</label>
<input type="search" id="global-search" name="q" placeholder="搜尋 HTML / SEO..." required>
<button type="submit">搜尋</button>
</form>
</search>
</header>
<!-- 範本 B:文章內部 Header(使用 <hgroup> 整合主標題與副標題,不破壞 H1->H2 階層) -->
<article>
<header class="article-header">
<hgroup>
<p class="eyebrow-tag">HTML5 語意化系列 · 實戰篇</p>
<h1>HTML5 header 內只能放標題嗎?剖析導覽列、搜尋框與巢狀結構的最佳實踐</h1>
<p class="subtitle">從 <search> 到 <hgroup>,打造符合 WHATWG 標準的現代標頭架構</p>
</hgroup>
<div class="article-meta">
<span>作者:Sean</span> ·
<time datetime="2026-10-24">2026 年 10 月 24 日</time>
</div>
</header>
<p>文章正文從這裡開始...</p>
</article>
一、 5 秒快速索引:header 內部元素合法性與無障礙角色速查表
根據 WHATWG HTML Living Standard (§4.3.7 The header element) 定義,<header> 代表「一組介紹性或導覽性的輔助內容(a group of introductory or navigational aids)」。它絕對不只能放標題!請參考下表快速判斷哪些元件應該放進 <header>,哪些則是嚴格禁止的語法紅線:
擬放入 <header> 的元件 | 是否合規? | 標準 HTML5 標籤寫法 | 在無障礙樹(Accessibility Tree)與 SEO 的作用 |
|---|---|---|---|
| 主標題/區段標題 | 🟢 強烈推薦 | <h1> ~ <h6> | 提供頁面或該 <article> / <section> 的核心主題大綱。 |
| 主標題 + 副標題/小標 | 🟢 強烈推薦 | <hgroup> 包裹 <h1> + <p> | 將主標題與副標題綁定為單一語意群組,避免誤用 <h2> 當副標題而產生假章節。 |
| 品牌 Logo 與首頁連結 | 🟢 強烈推薦 | <a href="/"><img alt="..."></a> | 在全站頂部 <header> 提供返回首頁入口;內頁切勿將全站 Logo 包進 <h1>。 |
| 全站主選單/文章目錄 | 🟢 強烈推薦 | <nav aria-label="..."> | 在 role="banner" 橫幅地標內建立 role="navigation" 導覽子地標。 |
| 站內搜尋表單 | 🟢 強烈推薦 | <search><form>...</form></search> | 使用現代 <search> 元素原生映射為 role="search" 搜尋地標(Baseline 2023+ 全面支援)。 |
| 作者、發布日期、分類標籤 | 🟢 合法常用 | <time datetime="...">、<p> | 在 <article> 的 <header> 內提供文章中繼資訊(Byline / Dateline)。 |
另一個 <header> 或 <footer> | 🔴 嚴格禁止 | ❌ 違反 WHATWG 內容模型 | HTML 驗證器直接報錯!<header> 的後代中絕對不可包含 <header> 或 <footer>。 |
| 全站側邊欄或正文內容 | 🔴 語意錯誤 | ❌ 應移至 <main> 或 <aside> | 把正文或無關側邊欄塞進 <header> 會讓螢幕閱讀器無法跳過導覽區。 |
二、 深度拆解:生產級全站 header 的四大黃金模組
一個現代化的企業官網、SaaS 儀表板或技術部落格,其頂層 <header class="site-header"> 通常由四大功能模組共同組成。我們先透過下圖檢視它們在 DOM 與無障礙樹中的階層關係:

模組 1:品牌識別區(Branding)—— 為什麼內頁不該把 Logo 包進 h1?
許多早期教學會示範在全站共用的 <header> 裡寫 <h1><a href="/">網站名稱</a></h1>。
這在網站「首頁」或許沒問題,但一旦套用到全站共用的 Layout 母版,就會導致每一篇技術文章頁都出現兩個 <h1>(一個是全站 Logo,一個是文章標題),甚至把文章主標題被迫降級為 <h2>!
- 最佳實踐:在文章內頁與功能頁中,全站
<header>內的品牌 Logo 請直接使用<a href="/">包裹<img alt="網站名稱" width="..." height="...">,將全頁唯一的<h1>100% 留給<main>裡面的文章主標題,確保單頁 SEO 主題權重高度集中。
模組 2:主導覽列(Global Navigation)—— nav 該放 header 裡面還是外面?
如我們在《HTML nav 標籤與一般 div 的本質差異》中所分析的,<nav> 代表主要導覽區塊。
- 什麼時候放進
<header>內? 當該導覽列屬於「全站主選單(Primary Navigation)」或「單篇文章開頭的章節快速跳轉目錄(Table of Contents)」時,將<nav>放在對應的<header>內部最符合視覺與語意邏輯。 - 什麼時候放在
<header>外? 像是頁尾的網站地圖連結(應放在<footer>內)或側邊欄的關聯文章分類導覽(應放在<aside>內),就不應塞進頂部<header>。
模組 3:站內搜尋艙(Site Search)—— 擁抱現代 HTML5 search 標籤!
過去十幾年,為了讓螢幕閱讀器識別 <header> 裡的搜尋框,開發者必須手動在 <form> 加上 ARIA 屬性:<form role="search">。
但在 WHATWG HTML Living Standard (§4.4.15 The search element) 中,官方正式新增了原生語意化標籤 <search>(已於 Chrome 118+、Firefox 118+、Safari 17.0+ 達成 Baseline Widely Available 全平台支援)!
- 只要將搜尋表單包裹在
<search> ... </search>內,瀏覽器就會自動將其映射為無障礙樹中的role="search"地標,不再需要手寫role="search",就算你的搜尋功能是由純 JavaScript 即時過濾(沒有<form>標籤的 SPA 搜尋組件)也能完美適用!
三、 WHATWG 內容模型與巢狀邊界:如何優雅處理「主標題 + 副標題」?
除了全站頂部導覽外,在 <article> 或 <section> 的內部 <header> 中,我們經常需要同時呈現「專欄分類小標(Eyebrow)+ 主標題(Heading)+ 副標題(Subtitle)」。這時該如何編寫 HTML 才不會踩中語法與 SEO 地雷?請看下圖的 WHATWG 官方決策樹:

1. 致命誤區:在 header 裡用 h1 + h2 寫主副標題
許多新手為了讓副標題字體稍微小一點,會在文章 <header> 裡這樣寫:
<!-- ❌ 錯誤反模式:把 <h2> 當成副標題使用! -->
<header>
<h1>深入淺出 WebAssembly 效能優化</h1>
<h2>從 C++ 編譯到瀏覽器執行期的完整實戰指南</h2>
</header>
🔥 為什麼這會破壞結構?
對 Googlebot 爬蟲、螢幕閱讀器以及 WordPress 的自動文章目錄外掛(如 Easy Table of Contents)而言,<h2> 代表「底下有一個獨立的第二層級章節內容」!如果你把副標題寫成 <h2>,緊接著卻直接出現另一個真正的章節 <h2>一、 什麼是 WebAssembly?</h2>:
- 自動目錄外掛會把你的副標題誤判為「沒有內文的空章節」列在目錄第一行;
- 視障使用者透過
H鍵巡覽標題時,會以為該<h2>下方有對應段落,往下讀卻發現直接跳到下一個標題。
2. 🟢 現代正解:使用復活升級的 hgroup 包裹 h1 與 p
根據 WHATWG HTML Living Standard (§4.3.6 The hgroup element) 最新規範,<hgroup> 的內容模型已經正式改版為:允許包含一個 <h1>~<h6> 主標題,搭配一個或多個 <p> 段落作為副標題或標語!
當你將 <hgroup> 放進 <header> 時,既能清楚表達「這段 <p> 是附屬於 <h1> 的副標題(而非正文第一段)」,又完全不會污染頁面的 <h1> ➔ <h2> ➔ <h3> 標題大綱樹!
四、 生產級實戰對決:從混亂巢狀重構為滿分響應式 header
下面我們將常見的四大錯誤寫法(包含非法嵌套 <header>、濫用 <h2> 副標、漏寫搜尋地標與無障礙標籤)與符合 WHATWG / WCAG 2.2 標準的生產級程式碼進行完整對照。
1. ❌ 常見翻車反模式(違反 WHATWG 內容模型與大綱階層)
<!-- ❌ 陷阱 1:在頂層 <header> 內又嵌套了另一個 <header>,違反 WHATWG 嚴格禁令! -->
<header class="top-wrapper">
<div class="announcement">全站限時免運中!</div>
<header class="main-nav-bar">
<!-- ❌ 陷阱 2:在文章內頁把網站 Logo 包進 <h1>,搶走文章主標題的唯一 <h1> 權重 -->
<h1><a href="/">極客商城</a></h1>
<!-- ❌ 陷阱 3:搜尋框沒有 <search> 或 role="search",且 <input> 缺少對應 <label> -->
<div class="search-box">
<input type="text" placeholder="找商品...">
<button>GO</button>
</div>
</header>
</header>
<main>
<article>
<header>
<!-- ❌ 陷阱 4:用 <h2> 充當文章副標題,造成大綱階層出現空章節 -->
<h1>2026 前端框架效能評測報告</h1>
<h2>React 19、Vue 3.5 與 Svelte 5 真實壓測數據</h2>
</header>
</article>
</main>
2. 🟢 生產級標準重構範例(HTML5 + CSS Flexbox + 結構自檢腳本)
<!DOCTYPE html>
<html lang="zh-Hant-TW">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML5 header 內部結構與巢狀最佳實踐</title>
<style>
.site-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1.5rem;
padding: 0.875rem 1.5rem;
background-color: #0f172a;
color: #f8fafc;
}
.nav-list {
display: flex;
gap: 1.25rem;
list-style: none;
margin: 0;
padding: 0;
}
.nav-list a {
color: #e2e8f0;
text-decoration: none;
}
.nav-list a[aria-current="page"] {
color: #38bdf8;
font-weight: 700;
border-bottom: 2px solid #38bdf8;
}
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
</style>
</head>
<body>
<!-- ✅ 頂層唯一的全站 <header> (role="banner"),絕不嵌套第二層 <header> -->
<header class="site-header">
<a href="/" class="brand-link">
<img src="https://example.com/logo.svg" alt="Sean 技術筆記首頁" width="132" height="32">
</a>
<nav aria-label="主導覽選單">
<ul class="nav-list" role="list">
<li><a href="/html" aria-current="page">HTML5 核心</a></li>
<li><a href="/a11y">無障礙開發</a></li>
<li><a href="/perf">渲染效能</a></li>
</ul>
</nav>
<!-- ✅ 使用現代 HTML5 <search> 元素建立原生搜尋地標 -->
<search aria-label="站內文章搜尋">
<form action="/search" method="get">
<label for="site-search-input" class="visually-hidden">輸入關鍵字搜尋文章</label>
<input type="search" id="site-search-input" name="q" placeholder="搜尋技術主題...">
<button type="submit">搜尋</button>
</form>
</search>
</header>
<main>
<article>
<!-- ✅ 文章專屬 <header> (位於 <article> 內,自動映射為 role="generic") -->
<header class="article-header">
<!-- ✅ 使用 <hgroup> 包裹專欄小標 <p>、唯一主標題 <h1> 與副標題 <p> -->
<hgroup>
<p class="eyebrow">HTML5 語意化架構深度剖析</p>
<h1>2026 前端框架效能評測報告</h1>
<p class="subtitle">React 19、Vue 3.5 與 Svelte 5 真實壓測數據與記憶體分析</p>
</hgroup>
<p class="byline">
作者:<strong>Sean</strong> · 發布於 <time datetime="2026-10-24">2026-10-24</time>
</p>
</header>
<section aria-labelledby="sec-benchmark">
<h2 id="sec-benchmark">一、 測試環境與基準指標</h2>
<p>這裡是第一章節的正文內容,與上方的 <h1> 形成完美的 H1 ➔ H2 階層...</p>
</section>
</article>
</main>
<script>
// 🔍 自動化查核腳本:檢測 <header> 是否違反 WHATWG 巢狀禁令並確認地標結構
function validateHeaderContentModel() {
const invalidNestedHeaders = document.querySelectorAll('header header, header footer, footer header, address header');
const hasSearchElement = document.querySelector('header search') !== null;
const hgroupSubtitles = document.querySelectorAll('header hgroup > p');
console.log('=== [HTML5 Header 內容模型檢驗報告] ===');
console.log('1. 非法巢狀 (header/footer/address 互包) 數量:', invalidNestedHeaders.length);
console.log('2. 頂部 Header 是否包含原生 <search> 地標:', hasSearchElement);
console.log('3. <hgroup> 內安全包裹的副標題 <p> 數量:', hgroupSubtitles.length);
}
validateHeaderContentModel();
</script>
</body>
</html>
Expected Output (預期 Console 輸出結果)
=== [HTML5 Header 內容模型檢驗報告] ===
1. 非法巢狀 (header/footer/address 互包) 數量: 0
2. 頂部 Header 是否包含原生 <search> 地標: true
3. <hgroup> 內安全包裹的副標題 <p> 數量: 2
五、 實務開發 4 大高頻踩坑雷區
在日常專案維護中,針對 <header> 內部元素的配置,請特別避開以下 4 個常見盲點:
- 為了做「雙層頂部列(公告列 + 導覽列)」而寫出
<header>包<header>:
許多電商網站最上方有一條「全站免運公告列(Top Utility Bar)」,下面緊接著「品牌 Logo 與主選單列」。新手常把外層包一個<header class="site-header">,裡面又寫一個<header class="main-bar">。- 正解:根據 WHATWG
<header>規範,<header>內部嚴禁出現另一個<header>!請在外層使用唯一的<header class="site-header">,內部的公告列與導覽列分別使用<div class="announcement-bar">與<nav class="main-nav">即可。
- 正解:根據 WHATWG
- 把「麵包屑導覽(Breadcrumbs)」跟「主選單」混在同一個
<nav>裡塞進<header>:
有些網站將麵包屑放在頂部<header>下緣,但卻沒有將它與主選單分開,導致螢幕閱讀器把兩組毫無關聯的連結當成同一條選單播報。- 正解:若
<header>內同時有主選單與麵包屑,請分別使用兩個獨立的<nav aria-label="主選單">與<nav aria-label="麵包屑導覽">(或將麵包屑放在<main>的開頭)。關於多重<header>在不同區段中的進階巢狀拆解,我們將在下一篇《多重 header 怎麼用?HTML5 區段內容與頁首標籤的巢狀階層拆解》深入探討。
- 正解:若
- 在
<header>的搜尋框只放放大鏡圖示按鈕,卻漏寫<label>或aria-label:
現代極簡 UI 常在<header>右側放一個沒有文字標籤的搜尋輸入框與 SVG 放大鏡按鈕。若未幫<input type="search">加上.visually-hidden的<label>(或aria-label="搜尋全站文章"),以及未幫純圖示<button type="submit">加上aria-label="執行搜尋",會在 Lighthouse 無障礙檢測中直接被扣分退件! - 把彈出式登入 Modal 或全站側邊抽屜(Drawer)的龐大 DOM 直接塞在
<header>裡:
雖然「登入按鈕」與「漢堡選單觸發鈕」位於<header>內,但點擊後彈出的「大型會員登入燈箱(<dialog>)」建議放在<body>末端(或透過 React Portal 掛載),避免讓頂部<header>地標內部塞滿與導覽無關的表單欄位。
六、 上線前 5 點自我檢驗清單 (Checklist)
在完成頁首與文章標頭切版後,請依序核對以下 5 項指標:
- ☐ 1. 無非法後代與祖先元素:確認頁面執行
document.querySelectorAll('header header, header footer, footer header, address header').length結果為0。 - ☐ 2. 內頁唯一
<h1>未被全站 Logo 佔用:在文章內頁與產品內頁中,全站<header>內的品牌 Logo 僅使用<a href="/">包裹,確保全頁唯一的<h1>留給正文主標題。 - ☐ 3. 副標題正確採用
<hgroup>+<p>:若<header>內有專欄小標(Eyebrow)或副標題,已使用<hgroup>包裹<h1>與<p>,而非誤用<h2>破壞標題階層。 - ☐ 4. 搜尋區具備
<search>地標與完整無障礙命名:<header>內的搜尋表單已使用<search>(或<form role="search">)包裹,且<input type="search">與純圖示提交<button>皆具備明確的無障礙名稱。 - ☐ 5. 導覽列標註
aria-label與當前頁面狀態:<header>內的<nav>已加上精準的aria-label="主選單"(不重複寫「導覽」二字),且當前所在頁面的<a>已標註aria-current="page"。
參考資料與延伸閱讀
- WHATWG HTML Living Standard: The
headerelement (§4.3.7) — 官方定義<header>的內容模型(Flow content,但禁止<header>與<footer>後代)與標準範例。 - WHATWG HTML Living Standard: The
hgroupelement (§4.3.6) — 官方規範如何使用<hgroup>將主標題<h1>~<h6>與一個或多個<p>副標題組合為單一標題群組。 - WHATWG HTML Living Standard: The
searchelement (§4.4.15) — 現代 HTML5 新增之原生搜尋地標元素規格與使用情境說明。 - W3C HTML Accessibility API Mappings (HTML-AAM 1.0):
headerandsearchroles — W3C 官方規範<header>(banner/generic)與<search>(search)在無障礙樹中的角色映射標準。 - MDN Web Docs:
<header>: The Header element — Mozilla 開發者社群針對<header>內部允許元素、無障礙地標行為與實務排版的完整指南。
發表迴響