You are currently viewing 《 CSS 程式筆記 1》How to make HTML table body scrollable?

《 CSS 程式筆記 1》How to make HTML table body scrollable?

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也無效,那該如何處理呢?


解決方法

  1. 第一種方法:在<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; 
}
  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 說明非常詳盡,推薦想探水深的朋友們。


參考資料