CSS 表格排版 display table:用樣式做出表格結構
display 的 table 系列值,可以讓任何元素表現得像 HTML 表格 一樣:整列等高、儲存格寬度自動分配、內容可以垂直置中。差別在於 它只借用表格的排版行為,不帶表格的語意。
對應關係
| display 的值 | 對應的表格元素 |
|---|---|
table | <table> |
table-row | <tr> |
table-cell | <td> |
table-row-group | <tbody> |
table-header-group | <thead> |
table-footer-group | <tfoot> |
table-column | <col> |
table-caption | <caption> |
inline-table | 行內版本的 <table> |
html
<div class="row">
<div class="cell">左欄</div>
<div class="cell">右欄的內容比較長,會把整列撐高</div>
</div>css
.row {
display: table;
width: 100%;
table-layout: fixed;
}
.cell {
display: table-cell;
padding: 16px;
}兩欄會自動等高,這正是 float 做不到、而 table 天生就有的行為。
垂直置中
vertical-align 用在 table-cell 上,對齊的是整格的內容,因此高度不確定的內容也能穩定置中:
css
.box {
display: table-cell;
height: 200px;
vertical-align: middle;
text-align: center;
}小提醒
同樣的 vertical-align 用在一般的行內元素上,只會對齊該行的基線,不會讓元素在容器中垂直置中。這是兩者最常被搞混的地方。
table-layout
| 值 | 說明 |
|---|---|
auto | 依內容決定欄寬(預設),內容多的欄位會變寬 |
fixed | 依第一列與設定的寬度決定,渲染較快、欄寬也較可預期 |
匿名表格
沒有把三個層級寫齊時,瀏覽器會自動補上缺少的那層:
css
/* 沒有 table-row,瀏覽器仍會自行建立一列 */
.wrapper { display: table; }
.item { display: table-cell; }能運作,但結構明確寫出來,日後維護比較不會誤判元素之間的關係。
現在還適合用嗎
大部分的版面已由 彈性盒子 flex 與 格線系統 grid 接手,它們更靈活、也支援換行與間距設定。table 值仍有兩個實用場合:
- 一列之中要 多欄等高,且不想處理額外設定。
- 高度不確定的區塊要 垂直置中,需要極佳的舊瀏覽器相容性。
小提醒
table 系列的元素不會換行,在窄螢幕上容易擠成一團,做 響應式設計 時要特別留意,通常會在小尺寸改回 display: block。
常見問題
用 display 的 table 值排版,跟直接寫 table 標籤有什麼不同?
只有外觀行為相同,語意完全不同。<table> 代表這是一份二維資料,螢幕閱讀器會照欄列念出來;用樣式做出來的表格只是排版,內容本身仍是一般的區塊。資料就用標籤,排版才用樣式。
table-cell 為什麼可以做到垂直置中?
因為 vertical-align 在儲存格上的行為是對齊整格的內容,而不是像行內元素那樣只對齊一行文字。把 vertical-align 設成 middle,內容就會落在儲存格的垂直中央。
沒有寫 table-row 也能運作嗎?
可以。瀏覽器會自動補上缺少的層級,也就是所謂的 匿名表格。不過結構若明確寫出來,日後維護時比較不會誤判元素之間的關係。