Peter
Peter

Reputation: 97

Bootstrap 4 table responsive tbody scroll

Using Bootstrap 4. I have a responsive table in which I would like to make a scrollable tbody. Table look like this:

<div class="table-responsive">
  <table class="table table-striped table-hover custom-table text-nowrap">
    <thead>
      <tr>
        <th>row1</th>
        <th>row2</th>
        <th>row2</th>
      </tr>
    </thead>
    <tbody>
      <!-- some rows -->
    </tbody>
  </table>

To scroll in tbody, I added a scss class .custom-table to table, it looks like this

.custom-table {
  tbody {
     height: 50px;
     overflow-y: auto;
     width: 100%;
     display: block;
  }
}

However, this style does not work correctly. All content in tbody moves to the left. I have a working JSFiddle example. What did I do wrong?

Upvotes: 0

Views: 5111

Answers (4)

SudoHaris
SudoHaris

Reputation: 61

Bootstrap 5 Table with fixed heading row & vertically scrollable tbody CSS Only

You have to put the table within a div

HTML:

 <!-- Table  -->
  <div class="container shadow-sm alarm-table">
    <table class="table">
      <thead class="table-primary">
        <tr>
          <th scope="col">ID</th>
          <th scope="col">Name</th>
          <th scope="col">Email</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>1</td>
          <td>John</td>
          <td>[email protected]</td>
        </tr>
        <tr>
          <td>1</td>
          <td>John</td>
          <td>[email protected]</td>
        </tr>
        <tr>
          <td>1</td>
          <td>John</td>
          <td>[email protected]</td>
        </tr>
        <tr>
          <td>1</td>
          <td>John</td>
          <td>[email protected]</td>
        </tr>
      </tbody>
    </table>
  </div>

CSS:

/* Makes table scrollable */
.alarm-table{
  height: 150px;
  overflow: auto;
}

/* Makes table heading-row stick to top when scrolling */
.container .table thead tr{
  position: sticky;
  top: 0;
}

Upvotes: 0

Ken Salter
Ken Salter

Reputation: 1

Using Udara Kasun's solution, but making the columns lines up:

.custom-table>tbody {
  display: block;
  height: 50px;
  overflow: auto;
}
.custom-table>thead,
tr {
  display: block;
  width: 100%;
}

.custom-table>thead {
  width: 100%
}

.custom-table {
  width: 100%;
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>

<div class="container-fluid">
  <div class="flex-group-1" style="overflow-y: auto">
    <table class="table table-striped table-hover custom-table table-bordered table-responsive ">
      <thead>
        <tr>
          <th width="100">col1</th>
          <th width="100">col2</th>
          <th width="100">col3</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td width="100">text1</td>
          <td width="100">text2</td>
          <td width="100">text3</td>
        </tr>
        <tr>
          <td width="100">text4</td>
          <td width="100">text5</td>
          <td width="100">text6</td>
        </tr>
        <tr>
          <td width="100">text7</td>
          <td width="100">text8</td>
          <td width="100">text9</td>
        </tr>
      </tbody>
    </table>
  </div>
</div>

Upvotes: 0

Αntonis Papadakis
Αntonis Papadakis

Reputation: 1240

Please check bellow, I prefer to use flexbox. I also use -webkit and -ms prefixes for more cross browser compatibility

  tbody , thead {
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    -ms-flex-wrap: wrap;
    flex-wrap: wrap;
  }

  tr {
    -ms-flex-preferred-size: 100%;
    flex-basis: 100%;
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
  }

  th,td {
    -webkit-box-flex: 1;
    -ms-flex: 1;
    flex: 1;
    text-align: center;
  }

  tbody {
     height: 50px;
     overflow-y: auto;
  }

  thead {
    padding-right: 20px;
  }

I set padding-right to thead because of the scrollbar on tbody.

Upvotes: 2

Udara Kasun
Udara Kasun

Reputation: 2216

Did you tried to like this?

Change your css like this

.custom-table> tbody {
    display:block;
    height:50px;
    overflow:auto;
}
.custom-table> thead, tbody tr {
    display:table;
    width:100%;         
}
.custom-table> thead {
    width:   100%   
}
.custom-table {
    width:100%;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

<div class="table-responsive">
  <table class="table table-striped table-hover custom-table text-nowrap">
    <thead>
      <tr>
        <th>row1</th>
        <th>row2</th>
        <th>row2</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>text1</td>
        <td>text2</td>
        <td>text3</td>
      </tr>
      <tr>
        <td>text4</td>
        <td>text5</td>
        <td>text6</td>
      </tr>
      <tr>
        <td>text7</td>
        <td>text8</td>
        <td>text9</td>
      </tr>
    </tbody>
  </table>
</div>

Upvotes: 1

Related Questions