Reputation: 2948
I have searched a lot of times to get a right solution to make the table header (thead) as fixed when we scroll down the body (tbody) section. So many solutions are right there, but nothing help me.
Some of tried links:
Most of the links are using a fixed width for each tr td
but I need it without specify any width to elements, because the table is generating dynamically. Title & contents are might be long or short, so the width is depending upon the content.
Have any other solution to align th
and td
properly?
.fixed_headers {
width: 100%;
table-layout: fixed;
border-collapse: collapse;
}
.fixed_headers thead tr {
display: block;
position: relative;
}
.fixed_headers tbody {
display: block;
overflow: auto;
width: 100%;
max-height: 200px;
}
<table class="fixed_headers" border="1" cellpadding="5" cellspacing="0">
<thead>
<tr>
<th>Lorem Ipsums</th>
<th>ipsum dolor sit amet</th>
<th>consectetur adipiscing</th>
<th>do eiusmod tempor incididunt</th>
</tr>
</thead>
<tbody>
<tr>
<td>Sed ut perspiciatis unde omnis iste natus error sit voluptatem</td>
<td>accusantium doloremque laudantium</td>
<td>consequuntur magni dolores eos qui ratione voluptatem</td>
<td>quis nostrum exercitationem</td>
</tr>
<tr>
<td>quis nostrum exercitationem</td>
<td>Sed ut perspiciatis unde omnis iste natus error sit voluptatem</td>
<td>accusantium doloremque laudantium</td>
<td>consequuntur magni dolores eos qui ratione voluptatem</td>
</tr>
<tr>
<td>consequuntur magni dolores eos qui ratione voluptatem</td>
<td>quis nostrum exercitationem</td>
<td>Sed ut perspiciatis unde omnis iste natus error sit voluptatem</td>
<td>accusantium doloremque laudantium</td>
</tr>
<tr>
<td>consequuntur magni dolores eos qui ratione voluptatem</td>
<td>Sed ut perspiciatis unde omnis iste natus error sit voluptatem</td>
<td>accusantium doloremque laudantium</td>
<td>quis nostrum exercitationem</td>
</tr>
<tr>
<td>accusantium doloremque laudantium</td>
<td>consequuntur magni dolores eos qui ratione voluptatem</td>
<td>Sed ut perspiciatis unde omnis iste natus error sit voluptatem</td>
<td>quis nostrum exercitationem</td>
</tr>
<tr>
<td>Sed ut perspiciatis unde omnis iste natus error sit voluptatem</td>
<td>accusantium doloremque laudantium</td>
<td>consequuntur magni dolores eos qui ratione voluptatem</td>
<td>quis nostrum exercitationem</td>
</tr>
<tr>
<td>consequuntur magni dolores eos qui ratione voluptatem</td>
<td>Sed ut perspiciatis unde omnis iste natus error sit voluptatem</td>
<td>accusantium doloremque laudantium</td>
<td>quis nostrum exercitationem</td>
</tr>
<tr>
<td>accusantium doloremque laudantium</td>
<td>consequuntur magni dolores eos qui ratione voluptatem</td>
<td>Sed ut perspiciatis unde omnis iste natus error sit voluptatem</td>
<td>quis nostrum exercitationem</td>
</tr>
<tr>
<td>Sed ut perspiciatis unde omnis iste natus error sit voluptatem</td>
<td>accusantium doloremque laudantium</td>
<td>consequuntur magni dolores eos qui ratione voluptatem</td>
<td>quis nostrum exercitationem</td>
</tr>
</tbody>
</table>
Upvotes: 0
Views: 286
Reputation: 48600
It's not the best, but you can force the width of the first three columns in the head of the table and the first row's cells in the table body. You will need to provide some heuristic on how the columns will be laid-out.
I modified a stylesheet I found on Google.
I added an optional JavaScript script below that calculates the width of the columns, in case you do not want to explicitly set them.
var cols = document.querySelectorAll('.fixed-header tr th'),
rows = document.querySelectorAll('.scroll-content tr'),
numOfCols = cols.length, // Number for columns in table
colRatio = 100 / numOfCols, // Percentage width of a single column
scrollWidth = 18, // Width of the scroll bar
tableWidth = document.querySelector('.table-container').clientWidth,
widthDiff = percentDiff(tableWidth, tableWidth + scrollWidth, numOfCols);
cols.forEach((col, index) => {
if (index < numOfCols - 1) {
col.setAttribute('width', (colRatio - widthDiff) + '%');
}
});
rows.forEach((row, i) => {
if (i === 0) {
row.querySelectorAll('td').forEach((cell, j) => {
if (j < numOfCols - 1) {
cell.setAttribute('width', colRatio + '%');
}
});
}
row.className += (i % 2 === 1) ? ' alternate-row' : 'normal-row';
});
function percentDiff(n, m, p) {
return (Math.abs(n - m) / ((n + m) / 2) * 100) / p;
}
/* define height and width of scrollable area. Add 16px to width for scrollbar */
div.table-container {
clear: both;
border: 1px solid #963;
height: 285px;
overflow: auto;
width: 618px; /* Add width for scrollbar */
}
/* Reset overflow value to hidden for all non-IE browsers. */
html>body div.table-container {
overflow: hidden;
width: 600px; /* Width of the table */
}
/* define width of table. IE browsers only */
div.table-container table {
float: left;
/* width: 740px */
}
/* define width of table. Add 16px to width for scrollbar. */
/* All other non-IE browsers. */
html>body div.table-container table {
/* width: 756px */
}
/* set table header to a fixed position. WinIE 6.x only */
/* In WinIE 6.x, any element with a position property set to relative and is a child of */
/* an element that has an overflow property set, the relative value translates into fixed. */
/* Ex: parent element DIV with a class of tableContainer has an overflow property set to auto */
thead.fixed-header tr {
position: relative;
}
/* set THEAD element to have block level attributes. All other non-IE browsers */
/* this enables overflow to work on TBODY element. All other non-IE, non-Mozilla browsers */
/* make the TH elements pretty */
thead.fixed-header th {
background: #C96;
border-left: 1px solid #EB8;
border-right: 1px solid #B74;
border-top: 1px solid #EB8;
font-weight: normal;
padding: 4px 3px;
text-align: left
}
html>body tbody.scroll-content {
display: block;
height: 262px;
overflow: auto;
width: 100%
}
html>body thead.fixed-header {
display: table;
overflow: auto;
width: 100%
}
/* make TD elements pretty. Provide alternating classes for striping the table */
/* http://www.alistapart.com/articles/zebratables/ */
tbody.scroll-content td,
tbody.scroll-content tr.normal-row td {
background: #FFF;
border-bottom: none;
border-left: none;
border-right: 1px solid #CCC;
border-top: 1px solid #DDD;
padding: 2px 3px 3px 4px
}
tbody.scroll-content tr.alternate-row td {
background: #EEE;
border-bottom: none;
border-left: none;
border-right: 1px solid #CCC;
border-top: 1px solid #DDD;
padding: 2px 3px 3px 4px
}
<div class="table-container">
<table border="0" cellpadding="0" cellspacing="0" class="scroll-table">
<thead class="fixed-header">
<tr>
<!-- width="24.667px" --> <th>Lorem Ipsums</th>
<!-- width="24.667px" --> <th>ipsum dolor sit amet</th>
<!-- width="24.667px" --> <th>consectetur adipiscing</th>
<th>do eiusmod tempor incididunt</th>
</tr>
</thead>
<tbody class="scroll-content">
<tr>
<!-- width="25px" --> <td>Sed ut perspiciatis unde omnis iste natus error sit voluptatem</td>
<!-- width="25px" --> <td>accusantium doloremque laudantium</td>
<!-- width="25px" --> <td>consequuntur magni dolores eos qui ratione voluptatem</td>
<td>quis nostrum exercitationem</td>
</tr>
<tr>
<td>quis nostrum exercitationem</td>
<td>Sed ut perspiciatis unde omnis iste natus error sit voluptatem</td>
<td>accusantium doloremque laudantium</td>
<td>consequuntur magni dolores eos qui ratione voluptatem</td>
</tr>
<tr>
<td>consequuntur magni dolores eos qui ratione voluptatem</td>
<td>quis nostrum exercitationem</td>
<td>Sed ut perspiciatis unde omnis iste natus error sit voluptatem</td>
<td>accusantium doloremque laudantium</td>
</tr>
<tr>
<td>consequuntur magni dolores eos qui ratione voluptatem</td>
<td>Sed ut perspiciatis unde omnis iste natus error sit voluptatem</td>
<td>accusantium doloremque laudantium</td>
<td>quis nostrum exercitationem</td>
</tr>
<tr>
<td>accusantium doloremque laudantium</td>
<td>consequuntur magni dolores eos qui ratione voluptatem</td>
<td>Sed ut perspiciatis unde omnis iste natus error sit voluptatem</td>
<td>quis nostrum exercitationem</td>
</tr>
<tr>
<td>Sed ut perspiciatis unde omnis iste natus error sit voluptatem</td>
<td>accusantium doloremque laudantium</td>
<td>consequuntur magni dolores eos qui ratione voluptatem</td>
<td>quis nostrum exercitationem</td>
</tr>
<tr>
<td>consequuntur magni dolores eos qui ratione voluptatem</td>
<td>Sed ut perspiciatis unde omnis iste natus error sit voluptatem</td>
<td>accusantium doloremque laudantium</td>
<td>quis nostrum exercitationem</td>
</tr>
<tr>
<td>accusantium doloremque laudantium</td>
<td>consequuntur magni dolores eos qui ratione voluptatem</td>
<td>Sed ut perspiciatis unde omnis iste natus error sit voluptatem</td>
<td>quis nostrum exercitationem</td>
</tr>
<tr>
<td>Sed ut perspiciatis unde omnis iste natus error sit voluptatem</td>
<td>accusantium doloremque laudantium</td>
<td>consequuntur magni dolores eos qui ratione voluptatem</td>
<td>quis nostrum exercitationem</td>
</tr>
</tbody>
</table>
</div>
Upvotes: 1
Reputation: 4938
You can use the position:sticky
for fixed headers like this
table
with a relative
div with the height you want to fix.sticky
. Because sticky works only on th
and td
inside a tableth
, otherwise it will appear transparent.th
will disppeear once header fixes on top (for some reason I dont know)..fixed-headers {
width: 100%;
position: relative;
overflow-y: scroll;
height: 300px;
}
.fixed-headers table {
table-layout: fixed;
width: 100%;
}
.fixed-headers thead tr th {
position: sticky;
top: 0px;
background-color: white;
}
<div class="fixed-headers">
<table border="1" cellpadding="5" cellspacing="0">
<thead>
<tr>
<th>Lorem Ipsums</th>
<th>ipsum dolor sit amet</th>
<th>consectetur adipiscing</th>
<th>do eiusmod tempor incididunt</th>
</tr>
</thead>
<tbody>
<tr>
<td>Sed ut perspiciatis unde omnis iste natus error sit voluptatem</td>
<td>accusantium doloremque laudantium</td>
<td>consequuntur magni dolores eos qui ratione voluptatem</td>
<td>quis nostrum exercitationem</td>
</tr>
<tr>
<td>quis nostrum exercitationem</td>
<td>Sed ut perspiciatis unde omnis iste natus error sit voluptatem</td>
<td>accusantium doloremque laudantium</td>
<td>consequuntur magni dolores eos qui ratione voluptatem</td>
</tr>
<tr>
<td>consequuntur magni dolores eos qui ratione voluptatem</td>
<td>quis nostrum exercitationem</td>
<td>Sed ut perspiciatis unde omnis iste natus error sit voluptatem</td>
<td>accusantium doloremque laudantium</td>
</tr>
<tr>
<td>consequuntur magni dolores eos qui ratione voluptatem</td>
<td>Sed ut perspiciatis unde omnis iste natus error sit voluptatem</td>
<td>accusantium doloremque laudantium</td>
<td>quis nostrum exercitationem</td>
</tr>
<tr>
<td>accusantium doloremque laudantium</td>
<td>consequuntur magni dolores eos qui ratione voluptatem</td>
<td>Sed ut perspiciatis unde omnis iste natus error sit voluptatem</td>
<td>quis nostrum exercitationem</td>
</tr>
<tr>
<td>Sed ut perspiciatis unde omnis iste natus error sit voluptatem</td>
<td>accusantium doloremque laudantium</td>
<td>consequuntur magni dolores eos qui ratione voluptatem</td>
<td>quis nostrum exercitationem</td>
</tr>
<tr>
<td>consequuntur magni dolores eos qui ratione voluptatem</td>
<td>Sed ut perspiciatis unde omnis iste natus error sit voluptatem</td>
<td>accusantium doloremque laudantium</td>
<td>quis nostrum exercitationem</td>
</tr>
<tr>
<td>accusantium doloremque laudantium</td>
<td>consequuntur magni dolores eos qui ratione voluptatem</td>
<td>Sed ut perspiciatis unde omnis iste natus error sit voluptatem</td>
<td>quis nostrum exercitationem</td>
</tr>
<tr>
<td>Sed ut perspiciatis unde omnis iste natus error sit voluptatem</td>
<td>accusantium doloremque laudantium</td>
<td>consequuntur magni dolores eos qui ratione voluptatem</td>
<td>quis nostrum exercitationem</td>
</tr>
</tbody>
</table>
</div>
Upvotes: 1