htmljquerycssasp.net-mvcbootstrap-table

How to keep sticky-header bootstrap table inside a div with dynamic data?


I am using bootstrap-table and dynamically adding my datas into the table (including headers)

I have checked below and other related posts but there's no luck.:

how-to-implement-fixed-header-for-table-in-bootstrap

And I tried out bootstrap-table's sticky-header extension which works when I'm scrolling the whole document, but when I want my table to be inside a div container, it's not working anymore.

My Codepen : example

Note: I placed data for examples, but in reality I am using ajax to call all the data, then initialize table after that, which is why I don't write anything inside the table in the html at all, and I need it to stay that way.

But after init, the header does not stick anymore.

I'm new to stackoverflow so I'm not sure if I'm doing this right, I couldn't make it into a fiddle but here's my code, thanks in advance.

$(document).ready(function () {
  var columns = [
    {
      field: "name",
      title: "Name"
    },
    {
      field: "age",
      title: "Age"
    },
    {
      field: "city",
      title: "City"
    }
  ];

  var data = [
    { name: "John Doe", age: 28, city: "New York" },
    { name: "Jane Smith", age: 34, city: "Los Angeles" },
    { name: "Jane Smith", age: 34, city: "Los Angeles" },
    { name: "Jane Smith", age: 34, city: "Los Angeles" },
    { name: "Jane Smith", age: 34, city: "Los Angeles" },
    { name: "Mike Johnson", age: 45, city: "Chicago" },
    { name: "Sarah Lee", age: 30, city: "Miami" }
  ];

  // init table
  $("#RealTable").bootstrapTable({
    data: data,
    columns: columns
  });
});
.divA {
  width: 100%;
  max-height: 200px; /* 設定 divA 高度為 50vh */
  overflow: auto; /* 允許內部內容捲動 */
  background-color: #e0e0e0;
  padding: 20px;
  position: relative; /* 需要這個來使 sticky 正常工作 */
}

/* 讓整個 table 設置 sticky */
#RealTable {
  position: relative;
  z-index: 1; /* 確保表格始終顯示 */
  border-collapse: separate; 
  border-spacing:0; 
  text-align:center;
}

.sticky-header th {
  position: sticky !important;
  top: 0;
  background-color: turquoise;
  color: white;
  z-index: 30 !important; /* 確保標題始終位於其他內容上方 */
}
.sticky-header th .th-inner {
  position: sticky !important;
  top: 0;
}

th,
td {
  padding: 10px;
  border: 1px solid #ddd;
  text-align: center;
}

.content {
  padding: 0px 0px 50px 0px;
}

.table {
  width: 100%;
  border: 1px solid #ddd;
  text-align: center;
}
<html lang="zh-Hant">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Sticky Header with Bootstrap Table</title>

  <!-- 引入 Bootstrap CSS -->
  <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">

  <!-- 引入 bootstrap-table 的 CSS -->
  <link href="https://unpkg.com/bootstrap-table/dist/bootstrap-table.min.css" rel="stylesheet">
</head>

<body>
  <div class="section">
    <h1>title</h1>
    <p>qweqwewq</p>
  </div>
  <div class="divA">
    <div class="row table-responsive">
      <table id="RealTable" class="table table-hover text-nowrap">
        <thead class="sticky-header">
        </thead>
        <tbody>
          <!-- dynamic added -->
        </tbody>
      </table>
    </div>
  </div>

  <div class="section">
    <h1>title2</h1>
    <p>qweqwewq</p>
    <p>qweqwewq</p>
    <p>qweqwewq</p>
  </div>

  <!--  jQuery -->
  <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>

  <!--  Bootstrap JS -->
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.bundle.min.js"></script>

  <!--  bootstrap-table 的 JS -->
  <script src="https://unpkg.com/bootstrap-table/dist/bootstrap-table.min.js"></script>

</body>

</html>

Current work (non-sticky header):

enter image description here

Desirder result I want (sticky header inside table):

enter image description here


Solution

  • Going through some of the comments in this question, I figured out that position sticky doesn't work if any of the parent elements has property like overflow: hidden or overflow: auto.

    In your case also it is the same issue. So adding the below css rules will solve your issue.

    .table-responsive {
      overflow-x: initial !important;
      margin-top: 20px;
    }
    
    .bootstrap-table .fixed-table-container .fixed-table-body {
      overflow: initial !important;
    }
    
    /* Added this extra style, otherwise scrolled content appears above the header */
    .divA {
      padding-top: 0;
    }
    

    Please check this working snippet:

    $(document).ready(function () {
      var columns = [
        {
          field: "name",
          title: "Name"
        },
        {
          field: "age",
          title: "Age"
        },
        {
          field: "city",
          title: "City"
        }
      ];
    
      var data = [
        { name: "John Doe", age: 28, city: "New York" },
        { name: "Jane Smith", age: 34, city: "Los Angeles" },
        { name: "Jane Smith", age: 34, city: "Los Angeles" },
        { name: "Jane Smith", age: 34, city: "Los Angeles" },
        { name: "Jane Smith", age: 34, city: "Los Angeles" },
        { name: "Mike Johnson", age: 45, city: "Chicago" },
        { name: "Sarah Lee", age: 30, city: "Miami" }
      ];
    
      // init table
      $("#RealTable").bootstrapTable({
        data: data,
        columns: columns
      });
    });
    .divA {
      width: 100%;
      max-height: 300px; /* 設定 divA 高度為 50vh */
      overflow: auto; /* 允許內部內容捲動 */
      background-color: #e0e0e0;
      padding: 20px;
      padding-top: 0;
      position: relative; /* 需要這個來使 sticky 正常工作 */
    }
    
    .table-responsive {
      overflow-x: initial !important;
      margin-top: 20px;
    }
    
    .bootstrap-table .fixed-table-container .fixed-table-body {
      overflow: initial !important;
    }
    
    /* 讓整個 table 設置 sticky */
    #RealTable {
      position: relative;
      z-index: 1; /* 確保表格始終顯示 */
      border-collapse: separate; 
      border-spacing:0; 
      text-align:center;
    }
    
    .sticky-header th {
      position: sticky !important;
      top: 0;
      background-color: turquoise;
      color: white;
      z-index: 30 !important; /* 確保標題始終位於其他內容上方 */
    }
    .sticky-header th .th-inner {
      position: sticky !important;
      top: 0;
    }
    
    th,
    td {
      padding: 10px;
      border: 1px solid #ddd;
      text-align: center;
    }
    
    .content {
      padding: 0px 0px 50px 0px;
    }
    
    .table {
      width: 100%;
      border: 1px solid #ddd;
      text-align: center;
    }
    <html lang="zh-Hant">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Sticky Header with Bootstrap Table</title>
    
      <!-- 引入 Bootstrap CSS -->
      <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
    
      <!-- 引入 bootstrap-table 的 CSS -->
      <link href="https://unpkg.com/bootstrap-table/dist/bootstrap-table.min.css" rel="stylesheet">
    </head>
    
    <body>
      <div class="section">
        <h1>title</h1>
        <p>qweqwewq</p>
      </div>
      <div class="divA">
        <div class="row table-responsive">
          <table id="RealTable" class="table table-hover text-nowrap">
            <thead class="sticky-header">
            </thead>
            <tbody>
              <!-- dynamic added -->
            </tbody>
          </table>
        </div>
      </div>
    
      <div class="section">
        <h1>title2</h1>
        <p>qweqwewq</p>
        <p>qweqwewq</p>
        <p>qweqwewq</p>
      </div>
    
      <!--  jQuery -->
      <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
    
      <!--  Bootstrap JS -->
      <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.bundle.min.js"></script>
    
      <!--  bootstrap-table 的 JS -->
      <script src="https://unpkg.com/bootstrap-table/dist/bootstrap-table.min.js"></script>
    
    </body>
    
    </html>