Skip to main content

[BS4] Bootstrap4 Customize Responsive Table(客制化表格寬度)

tags: table, table-responsive, customization#

Table 是報表、數據等資料很常使用的程式方式。在 Bootstrap4 中 Table 的結構其實還蠻單純的,但是有些時候直接套用的表格卻不是這麼的「好看」,它會隨著內容的寬度而對每個欄寬造成不同的影響,進而使得版面變得不太好看,因此,讓我們來試著深入一些些瞭解 Bootstrap Table ,看可以做哪些操作,客制化成我們想要的好看表格。

這篇文章主要說明如何把 Bootstrap 的表格調整成自己想要的樣式,關於 Bootstrap 表格的基本架構可以參考中文官方文件

以下內容建議搭配 範例程式碼 @ CodePen 閱讀。

基本架構#

Bootstrap 4 表格的基本架構如下,其他 <th> 標籤可以搭配 scope 屬性使用,屬性值可以是 col, row, colgroup, rowgroup,主要是用來說明這個 th 是屬於某欄或某列的標頭。

另外,Bootstrap 4 還提供其他可套用的 class:

  • <table>: .table-dark, .table-sm, .table-striped, .table-bordered, .table-hover
  • <thead>: .thead-light, .thead-dark
  • <tr>, <td>: .table-active, .table-primary, .table-secondary, .table-success, .table-danger, .table-warning, .table-info, .table-light, .table-dark

HTML \<th> scope Attribute @ w3schools

<!-- HTML --><table class="table">  <thead>    <tr>      <th scope="col">#</th>      <th scope="col">First Name</th>      <th scope="col">Last Name</th>      <th scope="col">Username</th>    </tr>  </thead>  <tbody>    <tr>      <th scope="row">1</th>      <td>Mark</td>      <td>Otto</td>      <td>@mdo</td>    </tr>    <tr>      <th scope="row">2</th>      <td>Jacob</td>      <td>Thornton</td>      <td>@fat</td>    </tr>    <tr>      <th scope="row">3</th>      <td>Larry</td>      <td>the Bird</td>      <td>@twitter</td>    </tr>  </tbody></table>

響應式表格#

.table-responsive 的使用#

要達到響應式表格,最直覺想到的是使用在 Bootstrap4 中提供 .table-responsive 這個 class 可以套用在 <table> 外層的 <div> 上:

<!-- HTML --><div class="table-responsive">  <table class="table table-bordered table-striped">    <caption>      List of users    </caption>    <thead>      <tr>        <th scope="col">#</th>        <!-- ... -->        <th scope="col">Remark</th>      </tr>    </thead>    <tbody>      <tr>        <th scope="row">1</th>        <!-- ... -->        <td>          Lorem ipsum is placeholder text commonly used in the graphic, print, and publishing          industries        </td>      </tr>      <tr>        <th scope="row">2</th>        <!-- ... -->        <td>          Lorem ipsum is placeholder text commonly used in the graphic, print, and publishing          industries        </td>      </tr>    </tbody>  </table></div>

一般來說只要 Table 內容相較於螢幕尺寸「太多」時,就會自動長出橫軸的 scroll-bar 讓使用者可以拖拉:

Imgur

另外也提供不同尺寸的 .table-responsive 可以使用,如 .table-responsive-sm, .table-responsive-md, .table-responsive-lg, .table-responsive-xl,它們會在該尺寸以下時可以左右滾動;該尺寸以上時則無法(使用的是 max-width)。

.table-responsive-md 為例,當螢幕尺寸 <768px 時,只要表格內容多過螢幕尺寸,就會出現水平捲軸可以滾動;當螢幕尺寸 >= 768px 時,這個水平的滾動捲軸就會消失。

.table-responsive 的作用#

從 Bootstrap 的原始碼中,可以看到 .table-responsive 的主要作用是把表格變成 display: block;,當寬度超過時,就以 overflow-x: auto; 來出現水平捲軸:

/* .table-responsive 的作用 */.table-responsive {  display: block;  width: 100%;  overflow-x: auto;  -webkit-overflow-scrolling: touch;  -ms-overflow-style: -ms-autohiding-scrollbar;}

.table-responsive 不足之處#

然而,這個基本的 responsive-table 在實際使用上有一些不方便之處,如下圖所示:

  1. 有些表格的標頭會自己換行
  2. 每個欄的寬度不同,看起來不整齊,而且有些欄當中的內容較多時,會一直換行

Imgur

解決文字換行的問題#

第一個問題比較容易解決,可以用 Bootstrap 中提供的 .text-nowrap 來避免表格欄位標頭換行即可。

<th scope="col" class="text-nowrap">First Name</th><th scope="col" class="text-nowrap">Last Name</th>

客制化表格(Customization Bootstrap Table)#

第二個問題則需要透過客制化的表格來處理,根據實際的內容調整表格寬度,做出最合適的表格:

  1. 在原本的 .col 這行加上 .custom-table-width(名字可以自己取),並且設為 overflow-x: auto;
<!-- HTML --><div class="col custom-table-width">  <table class="table">    ...  </table>  <div></div></div>
.custom-table-width {  overflow-x: auto;  ...;}

2.雖然設定了 overflow: auto;,但是原本在 .col 中預設 padding 的空間一樣會顯示內容出來,造成表格的寬度和上下文的寬度有 15px 的差異,因此我們需要使用 margin 把原本左右的空間推回來:

// SCSS$grid-gutter-width: 30px;
.custom-table-width {  overflow-x: auto;  margin-right: $grid-gutter-width / 2; // 利用 margin 推回去原本 padding 的空間  margin-left: $grid-gutter-width / 2;  padding-right: 0;  padding-left: 0;}

Bootstrap 預設的 padding 寬度是 15px ,也就是欄間距(gutters)除以 2 的寬度( $grid-gutter-width / 2)。

3.可以把 .table-responsive 拿掉,因為裡面的 display: block 屬性可能使得表格無法按照給定的寬度顯示。 4.將 .table 設定 table-layoutmin-width 。 table-layout 的預設值是 auto,也就是表格和細格(cell)的寬度會根據內容而改變;為了要讓表格根據所設定的值而改變,要設成 fixed,設定後表格的各欄寬度就會相同。另外,為了確保字不會疊在一起,或不斷換行,需要為表格設定最小寬度(min-width),這裡可以根據表格內容多寡設定一個適合的最小寬度:

.table {  table-layout: fixed; // 表格和欄寬將根據所給定的寬度來顯示  min-width: 1440px; // 避免因寬度不足而字疊在一起(根據表格內容設定寬度)}

Imgur

設定了 table-layout: fixed 後,表格各欄就會等寬(table-layout @ MDN)。

5.最後要設定表格中各欄的寬度,這裡一種作法是直接在 <th width="10%"> 加上 width 屬性,但 MDN 並不建議這種作法,因為 width 屬性在 HTML 5 中已被移除,建議還是在 CSS 中定義各欄寬,寬度可以設定%, px, em, rem 等等都可以,如果想要給到比較精確的話可以使用 pxem/rem

HTML th element @ MDN

// 流水號 #thead th:first-child,tbody td:first-child {  width: 2em;}
// Timethead th:nth-child(10),tbody td:nth-child(10) {  width: 13em;}
// Remarkthead th:last-child,tbody td:last-child {  width: 20%;}

完整範例程式碼#

HTML#

<!-- HTML --><div class="container">  <div class="row">    <div class="col custom-table-width">      <h4>Table with custom width</h4>      <table class="table table-bordered table-striped">        <caption>List of users</caption>        <thead>          <tr>            <th scope="col">#</th>            <th scope="col">First Name</th>            <th scope="col">Last Name</th>            <th scope="col">Username</th>            <th scope="col">Height</th>            <th scope="col">Width</th>            <th scope="col">Degree</th>            <th scope="col">Country</th>            <th scope="col">Major</th>            <th scope="col">Time</th>            <th scope="col">Remark</th>          </tr>        </thead>        <tbody>          <tr>            <th scope="row">1</th>            <td>Mark</td>            <td>Otto</td>            <td>@mdo</td>            <td>171</td>            <td>64</td>            <td>Master</td>            <td>Taiwan</td>            <td>Psychology</td>            <td>2017-10-21 16:43:20</td>            <td>Lorem ipsum is placeholder text commonly used in the graphic, print, and publishing industries </td>          </tr>          <tr>            <th scope="row">2</th>            <td>Jacob</td>            <td>Thornton</td>            <td>@fat</td>            <td>171</td>            <td>64</td>            <td>Master</td>            <td>Taiwan</td>            <td>Psychology</td>            <td>2017-10-21 16:43:20</td>            <td>Lorem ipsum is placeholder text commonly used in the graphic, print, and publishing industries </td>          </tr>          <tr>            <th scope="row">3</th>            <td>Larry</td>            <td>the Bird</td>            <td>@twitter</td>            <td>171</td>            <td>64</td>            <td>Master</td>            <td>Taiwan</td>            <td>Psychology</td>            <td>2017-10-21 16:43:20</td>            <td>Lorem ipsum is placeholder text commonly used in the graphic, print, and publishing industries </td>          </tr>        </tbody>      </table>    </div>  </div></div>

SCSS#

// 定義各欄位的寬度$grid-gutter-width: 30px;.custom-table-width {  overflow-x: auto;  margin-right: $grid-gutter-width / 2; // 利用 margin 推回去原本 padding 的空間  margin-left: $grid-gutter-width / 2;  padding-right: 0;  padding-left: 0;
  .table {    table-layout: fixed; // 表格和欄寬將根據所給定的寬度來顯示(預設等寬)    min-width: 1440px;   // 避免因寬度不足而字疊在一起  }
  // 流水號 #  thead th:first-child,  tbody td:first-child {    width: 2em;  }
  // Time  thead th:nth-child(10),  tbody td:nth-child(10) {    width: 13em;  }
  // Remark  thead th:last-child,  tbody td:last-child {    width: 20%;  }}

如此就可以客制化出自己想要的表格寬度和欄寬:

Imgur

其他客制化內容#

表格內容垂直置中#

.table th,.table td {  vertical-align: middle;}

標頭邊框寬#

當我們使用 .table-bordered 時,會發現標頭 <thead><tbody> 之間的邊框稍微比較寬一些,這是因為在 Bootstrap 中預設標頭的邊框底寬是 2px ,如果你希望它的寬度不要不一樣,可以使用:

.table-bordered thead th,.table-bordered thead td {  border-bottom-width: 1px;}

Imgur

關於本文若有錯誤,敬請告知,避免錯誤或不正確的資訊傳播。若有其他建議的作法,也歡迎告知一同討論。

延伸閱讀#