MIM
MIM

Reputation: 519

How to freeze thead section of the table

I have a table contains two header rows Demo.

<thead>
    <tr>
       <th colspan="4"><big>Variable Details</big></th>
    </tr>
    <tr>               
       <th>Variable Name</th>
       <th>Starting Value</th>
       <th>Default Value</th>
       <th>Description</th>
     </tr>
 </thead>

I want to freeze the top two header rows (thead section of the table). Any thoughts.

Upvotes: 2

Views: 7607

Answers (3)

Mr. Polywhirl
Mr. Polywhirl

Reputation: 48620

If you want to freeze the <thead>, you can give it a sticky positon.

Note: In order to the border on the <thead> not to disappear, I had to try this strategy:

Border style do not work with sticky position element (Make sure that you don't collapse borders)

const tableContainer = document.querySelector('.table-container');
const tbody = tableContainer.querySelector('tbody');

fetch('https://jsonplaceholder.typicode.com/todos')
  .then((res) => res.json())
  .then((todos) => {
    todos.forEach(({ id, title, completed }) => {
      tbody.insertAdjacentHTML('beforeend', `
        <tr>
          <td style="text-align:right">${id}</td>
          <td>${title}</td>
          <td style="text-align:center">${completed}</td>
        </tr>
      `);
    });
  });
/* General setup */
*, *::before, *::after {
  box-sizing: border-box;
}
:root {
  --table-header-color: #4A4;
  --table-row-even-color: #DFD;
  --table-row-odd-color: #FFF;
  --table-border-color: #040;
}
body {
  font-size: smaller;
}

/* Core table wrapper setup */
.table-container {
  width: 100%;
  height: 126px; /* Change this to whatever you want */
  overflow-y: auto;
}
.table-container table {
  width: 100%;
}
.table-container thead {
  position: sticky; /* Important */
  top: 0;
  z-index: 10;
}
.table-container th, .table-container td {
  padding: 0.125rem 0.25rem;
}

/* Borders (need to specify left/right and top/bottom) */
.table-container {
  border: thin solid var(--table-border-color);
}
.table-container table {
  border-collapse: separate; /* Do not collapse! */
  border-spacing: 0;
}
.table-container th, .table-container td {
  border-right: thin solid var(--table-border-color);
}
.table-container th {
  border-bottom: thin solid var(--table-border-color);
}
.table-container th:last-child, .table-container td:last-child {
  border-right: none;
}
.table-container tbody tr td {
  border-bottom: thin solid var(--table-border-color);
}
.table-container tbody tr:last-child td {
  border-bottom: none;
}

/* Colors (does not require the wrapper) */
thead {
  background: var(--table-header-color);
}
tbody tr:nth-child(odd) {
  background: var(--table-row-odd-color);
}
tbody tr:nth-child(even) {
  background: var(--table-row-even-color);
}

/* Custom scrollbar */
::-webkit-scrollbar {
  width: 10px;
}
::-webkit-scrollbar-track {
  box-shadow: inset 0 0 5px grey; 
  border-radius: 5px;
}
::-webkit-scrollbar-thumb {
  background: var(--table-header-color); 
  border-radius: 5px;
}
::-webkit-scrollbar-thumb:hover {
  background: var(--table-header-color); 
}
<h2>Scrolling Table</h2>
<div class="table-container">
  <table>
    <thead>
      <tr>
        <th>ID</th>
        <th>Title</th>
        <th>Completed</th>
      </tr>
    </thead>
    <tbody></tbody>
  </table>
</div>

Upvotes: 0

BradTheBluefish
BradTheBluefish

Reputation: 156

Change the CSS property position to "sticky" in order to get a sticky table head. See below.

CSS:

thead { position: sticky; top: 0px; z-index: 10; }

NOTE: You may have to adjust your z-index depending on your other CSS properties.

Upvotes: 3

MIM
MIM

Reputation: 519

After referring many web-site links, I am able to fix two header rows using pure CSS. Updated fix.

<div id="header-wrap"><b>Variable Details</b>

     <table border=1 cellpadding=0 cellspacing=0 width=100% style="margin-top:5px">

            <thead>
            <tr>            
                  <td  background-color:#E0EBEB;"><b>Variable Name</b></td>
                 <td  background-color:#E0EBEB;"><b>Starting Value</b></td>
                  <td  background-color:#E0EBEB;"><b>Default Value</b></td>
                  <td  background-color:#E0EBEB;"><b>Description</b></td>
            </tr>      
            </thead>
            </table>
</div>

CSS:

#header-wrap { position: fixed; width: 100%; height: 55px; top: 0; text-align:center; background-color:#F0F0F0; margin-top:0px; margin-bottom:40px;}
             td {width:25% }

Upvotes: 2

Related Questions