需求:HTML <table> 表頭固定不動,<tbody> 內容垂直滾動,且表頭與內容欄寬嚴絲合縫對齊。本文提供三種主流方案優劣比較與實作細節。
| 方案 | 原理 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|---|
| 雙 Table + 固定寬度 | 分離 <thead> 與 <tbody> 為兩個 <table>,設定每欄固定 width | 實作簡單、相容性佳 | 需手動維護欄寬、滾動條寬度需扣除 | 欄位固定、數量少的後台表格 |
| CSS position: sticky | th { position: sticky; top: 0; } 於單一 Table 內 | 零 JS、單一 DOM、自動對齊 | IE 不支援、需容器有高度與 overflow | 現代瀏覽器專案、快速原型 |
| 四塊 Table 拼接(插件模式) | 拆解為:左上角、右上角、左下角、右下角四個 Table,同步滾動 | 支援橫向+縱向雙向固定 | 實作複雜、維護成本高 | 複雜報表、凍結行列並存 |
<div class="table-container" style="height: 400px; overflow-y: auto;">
<table class="sticky-header">
<thead>
<tr><th>ID</th><th>Name</th><th>Age</th></tr>
</thead>
<tbody>
<tr><td>1</td><td>Alice</td><td>25</td></tr>
<!-- 大量資料列 -->
</tbody>
</table>
</div>
<style>
.table-container { overflow-y: auto; max-height: 400px; }
.sticky-header th {
position: sticky;
top: 0;
background: #f5f5f5;
z-index: 1; /* 確保表頭浮在內容之上 */
border-bottom: 2px solid #ddd;
}
/* 可選:第一欄也固定 */
.sticky-header th:first-child,
.sticky-header td:first-child {
position: sticky;
left: 0;
background: #fff;
}
</style>
<div class="table-wrap">
<table id="headerTable"><thead><tr><th>ID</th><th>Name</th></tr></thead></table>
<div class="body-wrap" style="height:300px; overflow-y:auto;">
<table id="bodyTable"><tbody><tr><td>1</td><td>Alice</td></tr>...</tbody></table>
</div>
</div>
<script>
function syncColumnWidths() {
const hCells = $('#headerTable th');
const bCells = $('#bodyTable tbody tr:first td');
hCells.each(function(i) {
const w = $(bCells[i]).outerWidth();
$(this).outerWidth(w);
$(bCells[i]).outerWidth(w);
});
}
// 初始化 + 視窗變化時同步
$(window).on('load resize', syncColumnWidths);
// 若資料動態載入,在渲染完成後呼叫 syncColumnWidths()
</script>
<th style="width:17px"></th>。table { border-collapse: collapse; } 避免雙線。px 固定寬,避免百分比導致對齊偏差。scrollY + scrollX + fixedHeader 選項,功能最完整。sticky 屬性,開箱即用。position: sticky,最簡潔。掌握核心原理(DOM 結構分離或 CSS 定位),即可根據專案限制選擇最適合的固定表頭方案。