How to create a fixed header and a scrollable body?
問題發想
最近在實作 HTML table 的時候發現了一個小問題,為什麼不能夠去設定<table>
、<tbody>
的高度呢,這個問題可能不精確,而是為什麼設定了卻沒有效果呢?
Demo on the codepen
The question is…
從上面的程式碼中,看到我分別在以下多處都有設定高度,但奇怪的是,有的有用,像是.table__header
、.table__cell
,好好的撐開了高度;反之,.table__body
則是讓內容無情的衝破雲端:
- 有效果
/* 掛在 <thead> */
.table__header {
background-color: #E2DED0;
height: 30px;
line-height: 30px;
}
/* 掛在 <th> */
.table__cell{
text-align: center;
border: 1px solid #3B3B3B ;
height: 30px;
line-height: 30px;
}
- 沒效果
table {
height: 100px;
}
.table__body {
height: 150px;
overflow-y: hidden; /*完全沒用啊@@*/
}
解決問題
想瞭解問題,我們先來知己知彼瞭解目標的特性;再來對症下藥,找出解方。
標的特性
在厲害的排版神器一維 Flex、二維 Grid 問世之前,table Tag 是很重要的,所以還是要先來看看 MDN 瞭解 <table>
、<tbody>
的預設屬性:
- HTML
<table>
Tag:HTML table element represents tabular data — that is, information presented in a two-dimensional table comprised of rows and columns of cells containing data.- 多數瀏覽器的
<table>
預設 CSS 為:
- 多數瀏覽器的
table {
display: table;
border-collapse: separate;
border-spacing: 2px;
border-color: gray;
}
- HTML
tbody
Tag:HTML tbody element encapsulates a set of table rows (<tr>
elements), indicating that they comprise the body of the table.- 多數瀏覽器的
<tbody>
預設 CSS 為:
- 多數瀏覽器的
tbody {
display: table-row-group;
vertical-align: middle;
border-color: inherit;
}
display: table
家族屬性的特色在於若沒有指定(或是指定的高度或寬度小於內容)它的寬度、高度會隨著內容而變化。
他就像 block-level 元素,元素之間會換行;但是實際的寬度卻僅跟內容相符。
所以,我們遇到的問題不是指定的高度沒以效果,而是我們指定的高度小於內容本身,他預設會衝出限制,這不是我們要的,設定了overflow-y
也無效,那該如何處理呢?
解決方法
- 第一種方法:在
<table>
的外層用<div>
包裹,給<div>
一個高度,並用overflow
呈現出 scroll 的效果。為了讓 table header 固定,還要設定 header 的position
。
/* div區塊 */
.container {
border: 1px solid #3B3B3B ;
height: 300px;
overflow-y: scroll;
}
/* thead區塊 */
.table__header {
position: sticky;
top: 0;
z-index: 1;
}
- 第二種方法:在沒有辦法加 wrapper 的時候,就只能從原本的 tag 下手。我們試著修改
<thead>``<tbody>
的 display 屬性,加上高度與 overflow,產生 scroll 的效果。
thead,
tbody {
display: block;
}
tbody {
height: 300px;
overflow-y: scroll;
}
第 2 種方法要注意的是,因為 display 改成 block,table 格式不再,因此寬高都要重新去設定。
小結
我查到的大部份資料都說 table tag 在現在 mobile-first 的時代,不太方便進行 RWD 的設計,但,另一方面, table 仍然時常運用在資料處理的實作中,還有很多值得熟練與探究學習的地方,下面的參考資料 3 說明非常詳盡,推薦想探水深的朋友們。