紀錄工作經驗、相關知識,解決技術相關問題。

HTML, 新手 Jamp Holes

新手必知的 HTML hgroup 標籤演進史:從 W3C 移除到 WHATWG 標準重定義的規範解析

新手必知的 HTML hgroup 標籤演進史:從 W3C 移除到 WHATWG 標準重定義的規範解析 特色圖片

在查閱前端技術教材或維護既有專案時,不少工程師都曾對 hgroup 標籤(<hgroup>)感到困惑:為什麼早期的 HTML5 書籍與教學明確標註它「已被 W3C 標準廢除」,但翻開最新的 MDN Web Docs 與 WHATWG HTML Living Standard 卻又看到它被列為正式規範?這篇技術筆記將從瀏覽器實作與標準組織演進的角度,帶你還原 hgroup 標籤從 2009 年誕生、2013 年被 W3C 除名到 2022 年重定義內容模型(Content Model)的完整歷程,並釐清現代專案中 <hgroup> 與 <header> 的職責邊界。

核心速查:hgroup 標籤各時期規範與內容模型對照表

演進階段標準組織與規範狀態規範允許的子元素(Content Model)設計初衷與實務現況
2009–2012
(HTML5 草案時期)
WHATWG 於 2009 年 4 月加入,W3C HTML5 草案同步收錄1 個或多個 <h1> 至 <h6> 標題元素(不含 <p>)配合「文件大綱演算法(Document Outline Algorithm)」,以內部最高層級的標題代表整組標題;但圖形瀏覽器與輔助科技從未實作該演算法
2013–2022 年 6 月
(標準分歧期)
W3C HTML5 移除並列為過時(Obsolete);WHATWG 保留W3C:不再是合法元素;WHATWG:沿用多標題內容模型內部的 <h2> 等次要標題在無障礙樹中仍是獨立標題,W3C 建議副標題改放在 <p>
2022 年 7 月至今
(現行標準)
WHATWG HTML Living Standard(PR #7829)0 個或多個 <p> + 唯一 1 個 <h1>–<h6> + 0 個或多個 <p>廢除多標題寫法,改為將「單一主標題」與「前置導言/後置副標題 <p>」綁定為語意群組

一、為什麼 hgroup 標籤會經歷「標準除名」與「重定義回歸」?

元素在 W3C 版本被列為過時(Obsolete)後,又以新定義留在 WHATWG 現行標準裡,要理解 hgroup 標籤為何經歷這番波折,必須先回到 HTML5 初期試圖解決的「文件大綱演算法(Document Outline Algorithm)」問題。

HTML hgroup 標籤從 2009 到 2022 年的規範演進時間軸

1. 2009 年的設計初衷:屏蔽副標題對文件大綱的干擾

在 HTML5 規範起草初期,規範制定者希望透過 <section>、<article> 等區段元素自動計算標題層級(即 Document Outline Algorithm)。當時遇到一個常見排版問題:如果文章同時有「主標題 <h1>」與「副標題 <h2>」,大綱演算法會把 <h2> 當成下一個子章節的開始。

為了解決這個問題,WHATWG 在 2009 年 4 月把原本的 <header> 定義改名為 <hgroup>,專門用來包住主標題與副標題:<hgroup> 內可以放多個 <h1>–<h6>,整組的層級取內部層級最高的那一個標題,其餘標題視為副標題或替代標題,不會在大綱中另開章節:

<!-- ⚠️ 2009 年舊版草案寫法(現行標準已判定為語法錯誤!) -->
<hgroup>
  <h1>分散式系統架構要點</h1>
  <h2>從 CAP 定理到共識演算法的工程實踐</h2>
</hgroup>

2. 2013 年 W3C 除名原因:缺乏實作與使用情境

理想很豐滿,但現實是:當年的規範本身就註明,圖形瀏覽器與輔助科技都沒有實作 HTML5 文件大綱演算法,只有驗證器等工具實作,因此不能依賴它向使用者傳達文件結構。當開發者寫出上述包含 <h1> 與 <h2> 的舊版 <hgroup> 時:

  • 無障礙樹(Accessibility Tree)未屏蔽次要標題:瀏覽器依 <h1>–<h6> 本身的數字層級對應標題角色,<hgroup> 裡的 <h2> 在無障礙樹中依然是一個二級標題(以 Chrome 156 的無障礙樹為例,上面的範例會出現 level 1 與 level 2 兩個 heading)。螢幕閱讀器使用者用標題清單或快捷鍵跳轉時,會把這句副標題當成獨立的章節標題。
  • W3C 決定將其移除:2013 年 4 月,W3C HTML 工作小組依主席決議提出移除 <hgroup>(Bug 21563),編輯在 2013 年 4 月 25 日以「缺乏實作、缺乏使用情境(lack of implementation, lack of use cases)」為理由接受變更。2014 年 10 月的 W3C HTML5 推薦標準把 hgroup 列在過時元素中,建議把副標題放進主標題後面的 <p>。

3. 2022 年 7 月 WHATWG PR #7829:徹底翻新內容模型

2019 年 5 月,W3C 與 WHATWG 簽署合作備忘錄,約定 HTML 與 DOM 主要在 WHATWG 以 Living Standard 流程發展;到了 2022 年 7 月 1 日,WHATWG 合併了關鍵的 Pull Request #7829(commit 標題為「Replace the outline algorithm with one based on heading levels」):

  1. 以標題層級取代舊的大綱演算法:區段元素不再影響文件大綱,大綱改由文件中所有 <h1>–<h6> 依數字層級組成。
  2. 重定義 hgroup 標籤的內容模型(Content Model):不再於 <hgroup> 內放置多個 <h1>–<h6>,改為只允許包含單一一個 <h1>–<h6> 主標題,搭配零個或多個 <p> 段落元素(可用於放置主標題上方的分類眉批 Kicker,或主標題下方的補充副標題 Subtitle)。

二、現行 WHATWG 標準下 hgroup 標籤的合法結構與語法實作

根據最新 WHATWG HTML Standard §4.3.7 The hgroup element 規範,hgroup 標籤代表「一個標題及其相關內容(a heading and related content)」,例如副標題、替代標題或標語。

其合法的內容模型(Content Model)必須嚴格滿足以下順序:

  1. 前置段落(選填):0 個或多個 <p> 元素(常用於系列專欄名稱、Eyebrow / Kicker 眉批)。
  2. 核心主標題(必填且唯一):恰好 1 個 <h1>、<h2>、<h3>、<h4>、<h5> 或 <h6> 元素。
  3. 後置段落(選填):0 個或多個 <p> 元素(常用於副標題、文章摘要標語)。
  4. 腳本支援元素(選填):<script> 或 <template>,可穿插在上述元素之間。

實務範例:文章頁首的「眉批 + 主標題 + 副標題」結構

<article class="post-container">
  <header class="post-header">
    <!-- hgroup 專責將「眉批、主標題、副標題」綁定為單一語意標題群組 -->
    <hgroup class="post-title-group">
      <p class="post-kicker">Web Standards 系列專欄 · 第 25 篇</p>
      <h1>新手必知的 HTML hgroup 標籤演進史</h1>
      <p class="post-subtitle">從 2013 年 W3C 除名到 2022 年 WHATWG 重定義內容模型的完整規範解析</p>
    </hgroup>

    <!-- 發布時間、作者與分類導覽屬於頁首中繼資料,應置於 header 內、hgroup 外 -->
    <div class="post-meta">
      <span>作者:Sean</span>
      <time datetime="2026-10-28">2026 年 10 月 28 日</time>
    </div>
  </header>

  <p>在查閱前端技術教材或維護既有專案時...</p>
</article>

搭配現代 CSS 選取器,我們不需要為 <p> 額外命名繁瑣的 Class,也能精準區分「位於主標題上方的眉批」與「位於主標題下方的副標題」:

.post-title-group {
  margin-block-end: 1.5rem;
}

/* 選取緊接在 h1 之前的 p(前置眉批 Kicker) */
.post-title-group p:has(+ h1) {
  font-size: 0.875rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  color: #2563eb;
  margin-block-end: 0.5rem;
  text-transform: uppercase;
}

.post-title-group h1 {
  font-size: clamp(1.75rem, 3vw, 2.25rem);
  line-height: 1.25;
  color: #0f172a;
  margin-block: 0;
}

/* 選取緊接在 h1 之後的 p(後置副標題 Subtitle) */
.post-title-group h1 + p {
  font-size: 1.125rem;
  line-height: 1.6;
  color: #475569;
  margin-block-start: 0.75rem;
}

三、結構邊界釐清:什麼時候用 hgroup?什麼時候用 header?

許多初學者在學會 hgroup 標籤後,最常提出的疑問是:「既然 <header> 也能放標題跟段落,那 <hgroup> 與 <header> 到底差在哪裡?可以互相取代嗎?」

答案是:兩者的語意顆粒度與允許的子元素範圍完全不同,經常是分層協作的關係,通常為 <header> 包裹 <hgroup>,而非二選一的互斥關係。

HTML hgroup 與 header 標籤的職責邊界與內容模型決策樹

hgroup 與 header 的核心差異對照表

比較維度<hgroup>(標題群組容器)<header>(頁首/區段導言容器)
核心職責僅負責將「單一標題(h1–h6)」與其附屬的「副標題/眉批(<p>)」綁定為一個整體容納整個頁面或區段的導言資訊(包含標題群組、Logo、導覽列、作者資訊、發布日期、搜尋框)
允許的子元素極度嚴格:僅限 1 個 <h1>–<h6> 與 0 個或多個 <p>(外加 <script> / <template>)廣泛(Flow Content):可包含 <hgroup>、<h1>–<h6>、<nav>、<img>、<time>、<form> 等(但後代不可再出現 <header> 或 <footer>)
HTML-AAM 對應角色role="group"(群組角色)不在 <main> 或 <article>、<aside>、<nav>、<section> 內時對應 role="banner" 地標;位於這些元素內時,現行 HTML-AAM 對應 sectionheader(舊版為 generic)
何時可單獨使用?當文章或區塊頂部只有「主標題 + 副標題 <p>」,沒有任何日期、作者或按鈕時,可直接只寫 <hgroup> 省略外層 <header>當頁首只有單一一個 <h1>(沒有副標題 <p>),但有搭配 <nav> 或 <time> 時,只需使用 <header> 即可

四、常見錯誤與 W3C 驗證器踩坑排查(Pitfalls & Troubleshooting)

當你使用 W3C Nu HTML Checker 進行標準檢驗時,關於 hgroup 標籤最常觸發的語法錯誤有以下三種:

1. 錯誤一:沿用 2009 年舊習慣,在 hgroup 內放入兩個以上的標題標籤

這是最常見的歷史遺留問題。在現行 WHATWG 標準下,<hgroup> 內若出現第二個 <h1>–<h6>,W3C 驗證器會直接拋出 Element “h2” not allowed as child of element “hgroup” in this context. 錯誤。

  • ❌ 錯誤寫法(違反 2022 年後 WHATWG 內容模型):
    <hgroup>
      <h1>TypeScript 5.x 型別體系詳解</h1>
      <h2>深入理解條件型別與 infer 關鍵字</h2>
    </hgroup>
  • ✅ 正確寫法(將次要標題改為 <p> 段落元素):為什麼這樣改更好? 因為這句副標題並不是文章的第一個子章節,若誤用 <h2> 會汙染整篇文章的目錄大綱(Table of Contents),改用 <p> 並交由 <hgroup> 包裹,既能表達它是主標題的附屬說明,又不會破壞 <h1> ➔ <h2> ➔ <h3> 的章節階層。
    <hgroup>
      <h1>TypeScript 5.x 型別體系詳解</h1>
      <p>深入理解條件型別與 infer 關鍵字</p>
    </hgroup>

2. 錯誤二:把發布日期 time、作者頭像 img 或標籤列塞進 hgroup

切記 <hgroup> 的內容模型是白名單制,除了單一標題與 <p>(以及 <script>、<template>)之外,任何 <div>、<span>、<time>、<img>、<a> 直接作為 <hgroup> 的子元素(Child Element)都是非法的(註:<a> 或 <span> 可以寫在 <h1> 或 <p> 裡面作為行內元素,但不能直接放在 <hgroup> 第一層)。下面的錯誤寫法會得到 Element “time” not allowed as child of element “hgroup” in this context.。

  • ❌ 錯誤寫法(將非標題元素直接放入 <hgroup> 第一層):
    <hgroup>
      <h1>高併發快取設計模式</h1>
      <p>Redis 實務手冊</p>
      <time datetime="2026-10-28">2026-10-28</time>
    </hgroup>
  • ✅ 正確寫法(外層使用 <header> 容納中繼資料):
    <header>
      <hgroup>
        <h1>高併發快取設計模式</h1>
        <p>Redis 實務手冊</p>
      </hgroup>
      <time datetime="2026-10-28">2026-10-28</time>
    </header>

3. 錯誤三:只有單一一個 h1、完全沒有副標題時卻多套一層 hgroup

如果你的區塊只有一個 <h1> 或 <h2>,沒有任何前置眉批或後置副標題 <p>,請直接撰寫 <h1> 或 <h2>,不需要多此一舉包裹 <hgroup>,以免在無障礙樹中產生多餘的 role="group" 容器節點。


五、總結與官方規範參考資源

回顧 hgroup 標籤這十多年來的演進,其實正是 Web 標準「從理想化演算法走向務實語意表達」的縮影:

  1. 告別多標題舊語法:永遠不要在 <hgroup> 裡面同時放置 <h1> 與 <h2>。
  2. 記住黃金公式:<hgroup> =(選填前置 <p>)+ 唯一 1 個 <h1>–<h6> +(選填後置 <p>)。
  3. 職責分明:<hgroup> 管「主副標題綁定」,<header> 管「整個頁首區塊(含日期、作者、導覽)」。

想進一步了解 <hgroup> 在無障礙樹中的映射、螢幕閱讀器的標題導覽行為與搭配 aria-labelledby 的寫法,可以接著看〈善用 HTML hgroup 提升無障礙體驗〉。

官方權威參考文獻

參考資料與延伸閱讀

發佈留言