本文將詳細解析 HTML hgroup 的核心規範、底層運作機制與實務配置要點,協助開發者在專案中快速排查常見問題並落實標準寫法。
在日常專案開發中,經常會遇到視覺設計稿要求在「核心主標題」上方加上一行系列專欄眉批(Kicker),並在下方搭配一段補充副標題(Subtitle)。許多初入前端領域的工程師為了快速套用現成字級,常直接連續塞入兩個 <h1>,或是為了縮小字體而在 <h1> 下方直接跳號放一個 <h3>。這篇技術筆記將從 W3C HTML-AAM 1.0 無障礙樹映射與 Google Search Central 標題結構要點的雙重視角,拆解標準 hgroup(<hgroup>)元素在螢幕閱讀器「線性閱讀」與「H 鍵跳轉」下的行為差異,並掌握結合 aria-describedby 與 aria-labelledby 的生產級實作模式。
⚡ 快速簡單使用(30 秒複製即用範本)
若你正在實作文章頁首或產品落地頁(Landing Page)的 Hero 主副標題區塊,並希望視障使用者無論使用「逐行閱讀」或「按 H 鍵跳轉標題」都能完整聽見副標題說明,請直接複製以下結合 <hgroup> 與 aria-describedby 的標準範本:
<header class="article-hero">
<hgroup class="title-group">
<p class="title-kicker">Web Accessibility 實戰系列</p>
<!-- 透過 aria-describedby 將主標題與後置副標題綁定,按 H 鍵跳轉時亦能播報副標題 -->
<h1 aria-describedby="article-subtitle">螢幕閱讀器與 SEO 的語意協作要點</h1>
<p id="article-subtitle" class="title-subtitle">
深入理解 W3C HTML-AAM 1.0 群組映射與標題階層權重設計
</p>
</hgroup>
</header>
一、hgroup 無障礙與 SEO 行為速查表(Quick Reference)
在深入底層規範前,我們先透過對照表快速比較三種常見「主副標題」寫法對無障礙樹(Accessibility Tree)、Lighthouse 自動化稽核與搜尋引擎爬蟲的實質影響:
| 評估維度 | 標準寫法:<hgroup> + <h1> + <p> | 反模式 A:<h1> 主標題 + <h1> 副標題 | 反模式 B:<h1> 主標題 + <h3> 副標題(為縮小字級跳號) |
|---|---|---|---|
| W3C HTML-AAM 角色映射 | 外層映射為 role="group",內部僅有唯一 1 個 level=1 標題節點 | 產生 2 個平行的 role="heading" (level=1) 節點 | 產生 level=1 與 level=3 兩個獨立標題節點 |
螢幕閱讀器 H 鍵導覽 | 僅將核心 <h1> 列入標題清單;搭配 aria-describedby 可把副標題設為標題的無障礙描述 | 視障用戶按 H 鍵會誤以為頁面有兩個獨立的主章節 | 副標題被當成子章節標題,且因缺少 <h2> 造成階層斷裂感 |
| Lighthouse / axe-core 稽核 | ✅ 完全通過 heading-order 標題階層連續性檢測 | ⚠️ 雖未跳號,但稀釋單頁主標題語意焦點 | ❌ 直接觸發 heading-order(Heading levels should only increase by one)警告 |
| SEO 與自動目錄(TOC)影響 | 頁面只有一個主標題,結構清楚;目錄外掛不會把副標題抓進文章大綱 | Google 表示標題數量與順序不影響搜尋,但頁面結構會出現兩個同級主標題 | 文章自動目錄(如 ez-toc)若收錄 <h3>,會把副標題當成內文子章節列出 |
二、為什麼傳統副標題寫法會破壞無障礙導覽與 SEO 結構?
在沒有使用 hgroup 的舊有專案中,工程師最常為了視覺字級而寫出以下兩種反模式程式碼:
<!-- ❌ 反模式 A:連續使用兩個 h1 -->
<div class="hero-header">
<h1>企業級微服務架構設計實務</h1>
<h1>從服務發現、熔斷機制到分散式追蹤的完整藍圖</h1>
</div>
<!-- ❌ 反模式 B:為了讓副標題字體變小,在 h1 下方直接放 h3(接著正文又放 h2) -->
<div class="hero-header">
<h1>企業級微服務架構設計實務</h1>
<h3>從服務發現、熔斷機制到分散式追蹤的完整藍圖</h3>
</div>
<h2>第一章:為什麼單體式架構需要拆分?</h2>
圖:傳統反模式(以 h1 + h3 充當主副標題)與標準實踐(hgroup + h1 + p)對大綱階層與 Lighthouse 稽核之影響對比
這兩種寫法在視覺畫面上或許與設計稿一致,但在底層語意卻會引發三個具體工程問題:
- 觸發 Lighthouse 與 axe-core 的
heading-order階層跳號失敗:
根據 Deque axe-coreheading-order規則(Deque 列為 Best Practice,影響程度 Moderate,不對應特定 WCAG 成功準則),頁面標題層級每次只應遞增一級(<h1> ➔ <h2> ➔ <h3>)。反模式 B 在<h1>下方直接放置<h3>充當副標題,緊接著正文第一章又回到<h2>,Lighthouse 的 Accessibility 稽核也會把heading-order列為未通過項目。 - 汙染螢幕閱讀器的標題導覽清單(Heading List):
根據 WebAIM Screen Reader User Survey #10(2023 年 12 月至 2024 年 1 月調查),在長網頁中尋找資訊時,71.6% 的受訪者第一步會透過頁面標題導覽(例如按快捷鍵H或叫出標題清單視窗)。當副標題被寫成<h1>、<h2>或<h3>時,每一個副標題都會變成一個偽章節入口,干擾視障使用者的導覽效率。 - 影響頁面大綱與目錄生成:
Google Search Central SEO 入門指南明確表示,標題依語意順序排列對螢幕閱讀器很有幫助,但從 Google 搜尋的角度來看,標題的數量與順序並不重要。因此副標題寫法的實際影響主要在讀者端:將冗長的補充敘述也標記為<h1>或<h2>,會讓頁面大綱變得混亂,並導致技術部落格的自動目錄外掛(Table of Contents)把副標題誤判為正文的第一個章節。
三、深度拆解:W3C HTML-AAM 無障礙樹映射與螢幕閱讀器真實行為
許多初學者常有一個誤解:「只要把 <h1> 跟 <p> 放進 <hgroup>,螢幕閱讀器在任何情況下都會自動把兩者合在一起唸出來。」
這其實是不準確的! 讓我們對照官方 W3C HTML Accessibility API Mappings (HTML-AAM) 1.0 — hgroup 規範,檢視瀏覽器與螢幕閱讀器在底層究竟做了什麼:
- 無障礙樹角色映射(Role Mapping):
<hgroup>在無障礙樹中被映射為role="group",各平台無障礙 API 皆沿用 WAI-ARIAgroup的對應方式,規範沒有為它另外定義角色描述(aria-roledescription)。 - 線性閱讀(Down Arrow)vs. 標題快捷鍵跳轉(
H鍵)的行為差異:- 當使用者使用「向下鍵(Down Arrow)」逐行線性閱讀時:螢幕閱讀器會依序朗讀前置
<p>、<h1>主標題與後置<p>副標題。由於<hgroup>對應的group沒有無障礙名稱,也沒有額外的角色描述,不能預期螢幕閱讀器會另外播報「標題群組」。 - 當使用者按下「
H鍵(跳至下一個標題)」時:螢幕閱讀器的焦點會直接跳到<hgroup>內部的<h1>元素上。由於<p>並不是<h1>的無障礙名稱(Accessible Name),若未做額外綁定,按H鍵停駐於<h1>時,標題本身只帶有<h1>的文字,下方的<p>副標題不在標題的名稱或描述之中。
- 當使用者使用「向下鍵(Down Arrow)」逐行線性閱讀時:螢幕閱讀器會依序朗讀前置
圖:W3C HTML-AAM 1.0 無障礙樹映射下,線性閱讀與按 H 鍵標題跳轉之朗讀差異,以及 aria-describedby 的補完機制
實務解決方案:在 h1 上搭配 aria-describedby 連結副標題
為了讓習慣按 H 鍵快速跳轉標題的視障使用者,在跳到主標題時也能聽見關鍵的副標題說明,同時又不讓副標題汙染 <h1> 本身的無障礙名稱(Accessible Name),最標準的做法是在主標題加上 aria-describedby 指向副標題 <p> 的 id:
<main>
<article>
<header>
<hgroup>
<p class="eyebrow">分散式資料庫實務 · 進階篇</p>
<!-- 主標題維持乾淨的 Accessible Name,並透過 aria-describedby 掛載副標題為 Accessible Description -->
<h1 aria-describedby="post-sub-desc">PostgreSQL 高可用叢集架構與讀寫分離要點</h1>
<p id="post-sub-desc">基於 Patroni、etcd 與 HAProxy 的零停機故障轉移(Failover)配置實錄</p>
</hgroup>
</header>
<section aria-labelledby="sec-arch">
<hgroup>
<h2 id="sec-arch" aria-describedby="sec-arch-sub">一、共識層與拓撲架構選型</h2>
<p id="sec-arch-sub">比較單主非同步複製與 Quorum 半同步複製的延遲與一致性取捨</p>
</hgroup>
<p>在規劃高可用資料庫叢集時,首要決策在於...</p>
</section>
</article>
</main>
這套寫法在 Chrome DevTools Accessibility 面板中的結果:
<h1>的 Accessible Name(無障礙名稱):"PostgreSQL 高可用叢集架構與讀寫分離要點"(簡潔扼要,在螢幕閱讀器的標題清單視窗中不會顯得冗長)。<h1>的 Accessible Description(無障礙描述):"基於 Patroni、etcd 與 HAProxy 的零停機故障轉移(Failover)配置實錄"(螢幕閱讀器停在這個標題時,可在唸完主標題後播報這段描述;是否播報與播報時機依螢幕閱讀器及其設定而定,例如 NVDA 的物件呈現設定有「Report Object descriptions」選項)。<section>透過aria-labelledby取得名稱"一、共識層與拓撲架構選型",在無障礙樹中成為region地標。
四、進階技巧:卡片與區段結合 aria-labelledby 時的命名計算陷阱
在開發文章列表卡片(<article>)或獨立章節區段(<section>)時,我們常會使用 aria-labelledby 為該容器命名,讓 <section> 在無障礙樹中升級為具備明確名稱的 region 地標。
但當容器內部使用了 <hgroup> 時,id 究竟該綁在 <hgroup> 上,還是綁在裡面的 <h2> / <h3> 上? 這是一個非常容易踩坑的細節!
❌ 常見誤區:將 aria-labelledby 指向整個 hgroup 容器
<!-- ⚠️ 不建議:把 id 綁在 hgroup 上 -->
<article class="post-card" aria-labelledby="card-group-1">
<hgroup id="card-group-1">
<p class="category">2026-10-28 · 前端架構</p>
<h3>善用 HTML hgroup 提升網頁語意化</h3>
<p class="subtitle">從 W3C HTML-AAM 1.0 無障礙樹映射看主副標題設計</p>
</hgroup>
</article>
根據 W3C Accessible Name and Description Computation (AccName) 1.2 演算法,當 aria-labelledby 指向一個群組容器(<hgroup id="card-group-1">)時,瀏覽器會遞迴串接該容器內所有子節點的文字。結果這個 <article> 的無障礙名稱會變成:"2026-10-28 · 前端架構 善用 HTML hgroup 提升網頁語意化 從 W3C HTML-AAM 1.0 無障礙樹映射看主副標題設計"——當螢幕閱讀器播報這張卡片的名稱時,會把日期、分類、主標題、副標題全部唸一遍,接著進入卡片內部讀到 <hgroup> 時,同樣的內容又會再唸一次。
✅ 最佳實踐:將 aria-labelledby 精準指向內部的 h2 / h3 標題元素
<!-- ✅ 解決思路:aria-labelledby 僅指向核心標題 h3,確保區段命名精煉不重複 -->
<article class="post-card" aria-labelledby="card-heading-1">
<hgroup>
<p class="category">2026-10-28 · 前端架構</p>
<h3 id="card-heading-1" aria-describedby="card-sub-1">
善用 HTML hgroup 提升網頁語意化
</h3>
<p id="card-sub-1" class="subtitle">
從 W3C HTML-AAM 1.0 無障礙樹映射看主副標題設計
</p>
</hgroup>
</article>
這樣一來,<article> 容器的無障礙名稱只會是乾淨的 "善用 HTML hgroup 提升網頁語意化",徹底消除雙重冗長朗讀的問題。
五、常見問題與踩坑排查清單(Troubleshooting Checklist)
在將 hgroup 導入團隊專案前,建議對照以下 4 點清單進行 Code Review:
- ☐ 確認
<hgroup>內部僅有唯一 1 個<h1>–<h6>:若內部同時出現<h1>與<h2>,違反 2022 年後 WHATWG 內容模型,請將次要標題改為<p>。 - ☐ 檢查是否為了縮小字級而跳號使用
<h3>作為副標題:透過 Chrome DevTools Lighthouse 執行 Accessibility 檢測,確認heading-order項目為綠燈通過。 - ☐ 關鍵頁面主標題補上
aria-describedby:針對落地頁或長文頁首的<h1>,確認已透過aria-describedby連結副標題<p id="...">,兼顧按H鍵跳轉的視障讀者體驗。 - ☐ 檢查
aria-labelledby目標節點:若外層<section>或<article>使用了aria-labelledby,確認其id是掛在<h2>/<h3>上,而非外層的<hgroup>上。
參考資料與延伸閱讀
- W3C HTML Accessibility API Mappings (HTML-AAM) 1.0 —
hgroupElement - WHATWG HTML Living Standard — §4.3.7 The
hgroupelement - W3C Accessible Name and Description Computation (AccName) 1.2
- Google Search Central — SEO Starter Guide: Things we believe you shouldn't focus on
- Deque University axe-core Rules —
heading-order: Heading levels should only increase by one - WebAIM — Screen Reader User Survey #10 Results
- MDN Web Docs —
<hgroup>: The Heading Group element - 延伸閱讀:HTML 語意化標籤整理:header、nav、main、article、section、aside 與 footer 架構解析
- 延伸閱讀:什麼是 DOM Tree?解析瀏覽器渲染機制與 Reflow / Repaint 效能優化實作


發佈留言