# 前提: 紀錄 table 標籤的正式規範
### **✔ 正式規範(HTML Standard)**
#### **一個 `<table>` 可以由以下任意組合構成:**
```
* <table>:表格本體(必須)
* <thead>:表頭區(可選)
* <tbody>:內容區(可選)-(若沒填寫時, 瀏覽器也會自動補)
* <tfoot>:表尾區(可選)
* <tr>:行(row)(必須)
* <th>:表頭欄位(header cell)(必須)
* <td>:一般欄位(data cell)(必須)
* <caption>
* <colgroup>
```
其中:
##### 👉 `<thead>、<tbody>、<tfoot>` 都是可選的
##### 👉 表格最少只需要 `<table><tr><td></td></tr></table>` 就能成立
---
### **✔ 那什麼時候需要`<thead>`?**
##### 👉建議加 `<thead>` 的情況:
* 有明確「表頭列」
* 想增加語意化(semantic)
* 想提升可及性(a11y)
* 想要更好的結構、維護性
* 需要固定表頭(sticky header)
* 要用 CSS 做 table layout 時更好控制
--
**例如:**
```
html.
<table>
<thead>
<tr>
<th>商品</th>
<th>數量</th>
<th>金額</th>
</tr>
</thead>
<tbody>
<tr>
<td>Apple</td>
<td>3</td>
<td>300</td>
</tr>
</tbody>
</table>
```
---
### **✔ 那什麼時候不需要 `<thead>`?**
**你也可以完全不寫:**
```
html.
<table>
<tr>
<th>商品</th>
<th>數量</th>
<th>金額</th>
</tr>
<tr>
<td>Apple</td>
<td>3</td>
<td>300</td>
</tr>
</table>
```
仍然合法。
---
### **✔ Bootstrap 需要 `<thead>` 嗎?**
Bootstrap 的 .table 語法:
* 不強制 `<thead>`
* 但 Bootstrap 的 table 樣式有針對 `<thead>` 做優化(字體、背景等)
**如果你不寫 `<thead>`,樣式也不會壞,只是少了表頭樣式。**
---
### **📌 正確觀念**
**一個最簡單、合法的 HTML table 只需要這樣:**
```
html.
<table>
<tr>
<td>資料</td>
</tr>
</table>
```
這是完全合法的 HTML。
---
### **❗ 那為什麼大家常加 `<tbody>` 和 `<thead>`?**
雖然不是必須,但以下情況強烈建議使用:
--
#### **⭐ 使用 `<thead>` 的理由**
* 語意化更清楚(表頭在哪一行)
* 螢幕閱讀器可理解欄位名稱
* CSS sticky header 很好做(position: sticky)
* 排序 plugin(DataTables, bootstrap-table)可正確辨識表頭
--
#### **⭐ 使用 `<tbody>` 的理由**
* 讓瀏覽器能建立更完整的 table model
* 多個 `<tbody>` 可以分區資料(不常用但合法)
* **操作 JS 時容易選取表身資料,例如:**
```
document.querySelector("tbody")
```
**若沒有 tbody,有些瀏覽器會自動補上,但你不一定能精準控制。**
--
#### **⭐ 使用 `<tfoot>` 的理由**
* 固定顯示總計、結尾欄位
* 在印表模式中會固定在每頁底部(很有用)
* CSS 可針對表尾做排版
---
## **🎯 最佳實務(如果你是做後台、管理頁)**
```
html.
<table>
<thead>
<tr>
<th>欄位1</th>
<th>欄位2</th>
</tr>
</thead>
<tbody>
<tr>
<td>資料1</td>
<td>資料2</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2">總計</td>
</tr>
</tfoot>
</table>
```
---
# 🔍 接著介紹一下 `<tr>` 的基本功能:
#### **🎯 `<tr>` 是什麼?**
`<tr>` = Table Row(表格的一列)
* 它是` <table> → <thead>/<tbody>/<tfoot> → <tr> → <th>/<td>`中間的「列」容器。
--
#### **🧩 1. `<tr>` 的合法父層(只能放在這些裡面)**
根據 HTML 規範:
`<tr>` 只能放在:
```
* <thead>
* <tbody>
* <tfoot>
* <table>(特殊情況下)
```
不合法的例子(會被瀏覽器修復錯位):
```
<div>
<tr> ❌ 錯誤
```
--
#### **🧩 2. `<tr>` 裡面能放什麼?**
只能放:
```
<th>
<td>
```
還有少數例外(rare):
```
<script>
<template>
```
不能放:
```
<div>
<span>
<p>
```
**瀏覽器會強制修正,自動移到外面。**
--
#### **🧩 3. `<tr>` 的預設顯示(重要)**
**預設:**
```
display: table-row;
```
### **⚠ 很重要的規則:**
你可以改成:
* block(不推薦)
* flex(不推薦)
* display: none(可用)
* grid(可用但不建議)
* inline(不建議)
你不能改成:
* table-header-group
* table-row-group
* table-column
* table-cell
**因為這會破壞 table model。**
---
#### **🧩 4. `<tr>` 現代常用語意(ARIA)**
**雖然 `<tr>` 沒有太多自帶功能,但可加入 ARIA:**
| 屬性 | 用途 |
| ---------------------- | --------------- |
| `role="row"` | 明確標示「這是列」 |
| `aria-selected="true"` | 表示該列被選取(例如點選列表) |
| `aria-expanded="true"` | 展開/收起的列 |
| `aria-label` | 描述該列內容 |
---
# 🔍 接著介紹一下 `<th>` 跟 `<td>` 的基本功能以及可用的所有屬性:
#### **🧩 1. `<th>` 的 scope — 表頭作用範圍(非常重要)**
**`scope` 是 `<th>` 專屬的屬性,用來描述:**
* ### **這個表頭(header)控制哪一個方向的資料(cells)。**
在可及性(A11y)與複雜表格中非常重要,也能提升 SEO。
--
**✔ `scope="col"`(最常用)**
表頭控制 **整欄(column)**。
```
<th scope="col">價格</th>
```
📌 用途:表格第一列欄位名稱
--
**✔ `scope="row"`**
表頭控制 **整列(row)**。
```
<tr>
<th scope="row">商品 A</th>
<td>30</td>
<td>5</td>
</tr>
```
--
**✔ `scope="colgroup"`**
控制**一整組欄(由 `<colgroup>` 划分)**。
```
<th scope="colgroup">2025 年</th>
```
通常用於跨欄表頭。
--
**✔ `scope="rowgroup"`**
控制**一整組列**。
```
<th scope="rowgroup">水果類</th>
```
### **🎯 scope 的結論**
| scope | 控制方向 |
| ---------- | ----- |
| `col` | 向下作用 |
| `row` | 向右作用 |
| `colgroup` | 控制整組欄 |
| `rowgroup` | 控制整組列 |
### **✔ 最常用的是 `col、row`。**
---
#### **🧩 2. `<th> / <td>` 的 colspan(跨欄位)**
讓 cell 橫向跨越多欄。
```
<th colspan="5">預約紀錄一覽</th>
```
注意:
##### * 只能用在 `<th>` 和 `<td>`
##### * `colspan` 的數字必須 ≤ (小於或等於) 該 "`<tr>`" 的欄數
##### * `colspan` 是橫向合併
---
#### **🧩 3. `<th> / <td>` 的 rowspan(跨列)**
讓 cell 縱向跨越多列。
```
<td rowspan="3">統一編號</td>
```
##### * 用於左側欄位合併常見
##### * 與 `colspan` 可同時使用
---
#### **🧩 4. `<th>` 的其他隱藏屬性(少見但很重要)**
**✔ `abbr`**
給表頭提供簡短縮寫(供螢幕閱讀器或窄螢幕使用)。
```
<th abbr="Qty">數量</th>
```
--
**✔ `headers`**
指定 `<td>` 所屬的 `<th>`,在複雜表格使用。
```
<th id="price">價格</th>
<td headers="price">300</td>
```
用途:
**讓複雜跨行跨列的表格也能保持可及性**
---
#### **🧩 5. `<td>` 可用的全部屬性(你問的「隱藏屬性」)**
其實 `<td>` 的內建屬性不多,但能做的事比你想像多。
--
**✔ `colspan`(橫向合併)**
```
<td colspan="3">合併 3 欄</td>
```
--
**✔ `rowspan`(縱向合併)**
```
<td rowspan="2">合併 2 列</td>
```
--
**✔ `headers`**
與 `<th id="">` 搭配,用於複雜表格。
```
<td headers="product price">100 元</td>
```
---
#### **🧩 6. `<td>` 的 ARIA 隱藏屬性(可選但實務很常用)**
這部分很少人知道,但對無障礙、動態表格非常重要。
--
**✔ `role="cell"`(標準 cell)**
通常不用自己加,瀏覽器會自動設定。
--
**✔ `aria-label`**
給 cell 一個可讀名稱(手機版表格常用)。
```
<td aria-label="價格">300</td>
```
--
#### **✔ `aria-labelledby`**
指向文字來源。
```
<td aria-labelledby="price-label">300</td>
```
--
#### **✔ `aria-sort`**
如果你做 sortable table,可以給表頭用。
```
<th aria-sort="ascending">價格</th>
```
**可用值:**
* `"none"`
* `"ascending"`
* `"descending"`
* `"other"`
---
#### **🧩 7. `<td>` 也能使用 data-*(非常常用)**
例如做手機版卡片表格:
```
html.
<td data-title="價格">300</td>
```
然後 CSS 顯示:
```
css.
td::before {
content: attr(data-title) ": ";
}
```
---
## 🎉 最終總整理(讓你完全記住)
✅ HTML 規範:哪些 table 元素是必須的?
| 元素 | 用途 | 常見嗎? | 必要嗎? |
| ------------ | ------- | ---- | ------------- |
| `<caption>` | 表格標題 | 中 | ❌ |
| `<colgroup>` | 欄位設定 | 低 | ❌ |
| `<thead>` | 表頭 | 高 | ❌(但強烈建議) |
| `<tbody>` | 表身 | 高 | ❌(瀏覽器會自動加) |
| `<tfoot>` | 表尾 | 中 | ❌ |
| `<tr>` | 資料列 | 必備 | ✔ |
| `<th>` | 表頭 cell | 高 | ❌(資料列不一定要 th) |
| `<td>` | 資料 cell | 必備 | ✔ |
--
## 🎯 完整總結 `<tr>` 你該知道的所有事
**✔ `<tr>` 的用途:**
* 表格的一列(row)
**✔ `<tr>` 的合法結構:**
* 只能包含 `<th> / <td>`
* 只能放在 `<thead> / <tbody> / <tfoot>`
**✔ `<tr>` 的 display:**
* 預設:`table-row`
* 可改成 none(隱藏)
* 可改成 block(做 RWD table)
* ❌ 不能改成 `table-header-group` 等
**✔ `<tr>` 常用的現代屬性:**
##### * aria-selected
##### * aria-expanded
##### * role="row"
✔ `<tr>` 做 RWD 的最佳用法:
```
<tr class="d-none d-lg-table-row">
```
--
## 🎯 完整總結`<th>` 有的屬性(最完整)
| 屬性 | 用途 |
| ----------------- | --------------------------------------- |
| `scope` | 指定表頭方向(col / row / colgroup / rowgroup) |
| `colspan` | 合併欄 |
| `rowspan` | 合併列 |
| `abbr` | 表頭簡寫 |
| `headers` | 指定 id 參照,用於複雜表格 |
| `aria-sort` | 排序狀態用 |
| `aria-label` | 語意文字 |
| `aria-labelledby` | 語意引用 |
--
## 🎯 完整總結`<td>` 有的屬性(最完整)
| 屬性 | 用途 |
| ---------------------------------- | --------------- |
| `colspan` | 合併欄 |
| `rowspan` | 合併列 |
| `headers` | 指向 `<th id="">` |
| `data-*` | RWD 表格常用 |
| ARIA(aria-label / aria-labelledby) | 無障礙提升 |
--
## 🎯 在 table 中: 各個標籤的預設 display
| 元素 | 預設 display |
| --------------- | ------------------ |
| `<thead>` | table-header-group |
| `<tbody>` | table-row-group |
| `<tfoot>` | table-footer-group |
| `<tr>` | table-row |
| `<th>` / `<td>` | table-cell |
---
## ⭐ 建議最佳實務(前端工程師版本)
**✔ 1. 永遠加 `<thead>` 與 `<tbody>`**
理由:
* 排序外掛正常
* sticky header 容易做
* 可及性(A11y)更好
* 結構清楚
**✔ 2. 表頭一定要用 `<th scope="col">`**
* 提升語意
* 有利於 SEO
* 有利於讀屏工具正確朗讀
**✔ 3. 一律避免改 `<th> / <td>` 的 display(除非必要)**
否則:
* colspan 會壞
* row height 會變怪
* alignment 無法預測
**✔ 4. `<tfoot>` 放不放可視需求**
* 印表時非常有用。