CSS-Only Scrollable Table with fixed headers
This answer will be used as a placeholder for the not fully supported position: sticky
and will be updated over time. It is currently advised to not use the native implementation of this in a production environment.
See this for the current support: https://caniuse.com/#feat=css-sticky
Use of position: sticky
An alternative answer would be using position: sticky
. As described by W3C:
A stickily positioned box is positioned similarly to a relatively positioned box, but the offset is computed with reference to the nearest ancestor with a scrolling box, or the viewport if no ancestor has a scrolling box.
This described exactly the behavior of a relative static header. It would be easy to assign this to the <thead>
or the first <tr>
HTML-tag, as this should be supported according to W3C. However, both Chrome, IE and Edge have problems assigning a sticky position property to these tags. There also seems to be no priority in solving this at the moment.
What does seem to work for a table element is assigning the sticky property to a table-cell. In this case the <th>
cells.
Because a table is not a block-element that respects the static size you assign to it, it is best to use a wrapper element to define the scroll-overflow.
The code
div { display: inline-block; height: 150px; overflow: auto}
table th { position: -webkit-sticky; position: sticky; top: 0;}
/* == Just general styling, not relevant :) == */
table { border-collapse: collapse;}
th { background-color: #1976D2; color: #fff;}
th,td { padding: 1em .5em;}
table tr { color: #212121;}
table tr:nth-child(odd) { background-color: #BBDEFB;}
<div> <table border="0"> <thead> <tr> <th>head1</th> <th>head2</th> <th>head3</th> <th>head4</th> </tr> </thead> <tr> <td>row 1, cell 1</td> <td>row 1, cell 2</td> <td>row 1, cell 2</td> <td>row 1, cell 2</td> </tr> <tr> <td>row 2, cell 1</td> <td>row 2, cell 2</td> <td>row 1, cell 2</td> <td>row 1, cell 2</td> </tr> <tr> <td>row 2, cell 1</td> <td>row 2, cell 2</td> <td>row 1, cell 2</td> <td>row 1, cell 2</td> </tr> <tr> <td>row 2, cell 1</td> <td>row 2, cell 2</td> <td>row 1, cell 2</td> <td>row 1, cell 2</td> </tr> <tr> <td>row 2, cell 1</td> <td>row 2, cell 2</td> <td>row 1, cell 2</td> <td>row 1, cell 2</td> </tr> </table></div>
Table fixed header and scrollable body
Here is the working solution:
table { width: 100%;}
thead, tbody, tr, td, th { display: block; }
tr:after { content: ' '; display: block; visibility: hidden; clear: both;}
thead th { height: 30px;
/*text-align: left;*/}
tbody { height: 120px; overflow-y: auto;}
thead { /* fallback */}
tbody td, thead th { width: 19.2%; float: left;}
<link href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"/>
<table class="table table-striped"> <thead> <tr> <th>Make</th> <th>Model</th> <th>Color</th> <th>Year</th> </tr> </thead> <tbody> <tr> <td class="filterable-cell">Ford</td> <td class="filterable-cell">Escort</td> <td class="filterable-cell">Blue</td> <td class="filterable-cell">2000</td> </tr> <tr> <td class="filterable-cell">Ford</td> <td class="filterable-cell">Escort</td> <td class="filterable-cell">Blue</td> <td class="filterable-cell">2000</td> </tr> <tr> <td class="filterable-cell">Ford</td> <td class="filterable-cell">Escort</td> <td class="filterable-cell">Blue</td> <td class="filterable-cell">2000</td> </tr> <tr> <td class="filterable-cell">Ford</td> <td class="filterable-cell">Escort</td> <td class="filterable-cell">Blue</td> <td class="filterable-cell">2000</td> </tr> </tbody></table>
How can I make a Table with a Scroll and fixed Header with CSS code, which looks good in any circumstance and on the cellphone too?
You can use the style table-responsive
with bootstrap.
<div class="table-responsive-sm tablealign">
...
Then change table-layout
to auto
, and assign the mine-width
to .table th
. Then change the .table
width and srollbar's width. Here is all the style.
<style>
* {
box-sizing: border-box;
}
.wrapper2 {
height: 30vw;
overflow-y: scroll;
}
.card {
background-color: #fff;
border-radius: 10px;
margin: 10% auto;
position: relative;
padding: 34px;
color: #444;
cursor: pointer;
overflow-x: auto;
}
.card:before {
display: block;
position: absolute;
background-color: #ccc;
z-index: -1;
box-shadow: 0 0 40px #999999;
transition: box-shadow .2s ease-in-out;
}
.card.level-3:hover:before {
box-shadow: 0 0 80px #999999;
}
.table {
border-collapse: collapse;
width: 95%;
}
.table td {
overflow: hidden;
word-break: normal;
text-align: center;
}
.table th {
text-align: center;
word-break: normal;
min-width: 100px;
}
.tablealign {
float: right;
width: 100%;
height: 100%;
border-radius: 3px;
padding-bottom: 50px;
}
tbody {
overflow-y: auto;
overflow-x: hidden;
height: 336px;
display: block;
}
tbody::-webkit-scrollbar {
width: 0;
}
thead {
display: table;
width: calc(100% - 17px);
table-layout: auto;
}
tbody tr {
table-layout: fixed;
display: table;
width: 100%;
}
div.c {
line-height: 1%;
}
</style>
Table with Fixed Header Row and Scrollable Content
<!DOCTYPE HTML>
<html lang="en-us">
<head>
<meta charset="utf-8">
<title>Table</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
table {
border-collapse: collapse;
width: 1000px;
table-layout: fixed;
}
td,th {
padding: 5px;
min-width: 200px;
border-right: 1px solid #ccc
}
thead tr {
background: #888;
color: #eee;
display: block;
position: relative;
}
tbody {
display: block;
height: 200px;
width: 100%;
overflow-y: auto;
overflow-x: hidden;
}
tbody tr:nth-child(even) {
background: #ddd;
}
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
<th>Column 4</th>
<th>Column 5</th>
</tr>
</thead>
<tbody>
<tr>
<td>Content</td>
<td>Content</td>
<td>Content</td>
<td>Content</td>
<td>Content</td>
</tr>
<tr>
<td>Content</td>
<td>Content</td>
<td>Content</td>
<td>Content</td>
<td>Content</td>
</tr>
<tr>
<td>Content</td>
<td>Content</td>
<td>Content</td>
<td>Content</td>
<td>Content</td>
</tr>
<tr>
<td>Content</td>
<td>Content</td>
<td>Content</td>
<td>Content</td>
<td>Content</td>
</tr>
<tr>
<td>Content</td>
<td>Content</td>
<td>Content</td>
<td>Content</td>
<td>Content</td>
</tr>
<tr>
<td>Content</td>
<td>Content</td>
<td>Content</td>
<td>Content</td>
<td>Content</td>
</tr>
<tr>
<td>Content</td>
<td>Content</td>
<td>Content</td>
<td>Content</td>
<td>Content</td>
</tr>
<tr>
<td>Content</td>
<td>Content</td>
<td>Content</td>
<td>Content</td>
<td>Content</td>
</tr>
<tr>
<td>Content</td>
<td>Content</td>
<td>Content</td>
<td>Content</td>
<td>Content</td>
</tr>
<tr>
<td>Content</td>
<td>Content</td>
<td>Content</td>
<td>Content</td>
<td>Content</td>
</tr>
<tr>
<td>Content</td>
<td>Content</td>
<td>Content</td>
<td>Content</td>
<td>Content</td>
</tr>
<tr>
<td>Content</td>
<td>Content</td>
<td>Content</td>
<td>Content</td>
<td>Content</td>
</tr>
<tr>
<td>Content</td>
<td>Content</td>
<td>Content</td>
<td>Content</td>
<td>Content</td>
</tr>
</tbody>
</table>
</body>
</html>
table with fixed thead and scrollable tbody
This solution fulfills all 5 requirements:
table { width: 100%;}
table, td { border-collapse: collapse; border: 1px solid #000;}
thead { display: table; /* to take the same width as tr */ width: calc(100% - 17px); /* - 17px because of the scrollbar width */}
tbody { display: block; /* to enable vertical scrolling */ max-height: 200px; /* e.g. */ overflow-y: scroll; /* keeps the scrollbar even if it doesn't need it; display purpose */}
th, td { width: 33.33%; /* to enable "word-break: break-all" */ padding: 5px; word-break: break-all; /* 4. */}
tr { display: table; /* display purpose; th's border */ width: 100%; box-sizing: border-box; /* because of the border (Chrome needs this line, but not FF) */}
td { text-align: center; border-bottom: none; border-left: none;}
<table> <thead> <tr> <th>Table Header 1</th> <th>Table Header 2</th> <th>Table Header 3</th> </tr> </thead> <tbody> <tr> <td>Data1111111111111111111111111</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data2222222222222222222222222</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data3333333333333333333333333</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> <tr> <td>Data</td> <td>Data</td> <td>Data</td> </tr> </tbody></table>
table with sticky header and horizontal scroll
As per the MDN documentation:
a sticky element "sticks" to its nearest ancestor that has a "scrolling mechanism" (created when
overflow
ishidden
,scroll
,auto
, oroverlay
), even if that ancestor isn't the nearest actually scrolling ancestor.
There's an active GitHub issue discussing this on the W3C repo, which has been running since 2017. There have been various workarounds suggested, but they all seem to rely on adding a fixed height to the table / table container, or using Javascript as in this answer.
At least for the moment, this is not something that's supported natively.
Related Topics
Flexbox Not Giving Equal Width to Elements
Hide Vertical Scrollbar in ≪Select≫ Element
How to Disable Google Translate from HTML in Chrome
Youtube Embedded Video: Autoplay Feature Not Working in Iphone
How to Make a Whole 'Div' Clickable in HTML and CSS Without JavaScript
Size of Font in CSS with Slash
Why Are Button's Discouraged from Navigation
Why Doesn't CSS Ellipsis Work in Table Cell
Inline <Style> Tags VS. Inline CSS Properties
Highlight Words in HTML Using Regex & JavaScript - Almost There
Why Media Queries Has Less Priority Than No Media Queries Css
Is Html5 Localstorage Asynchronous
How to Close ≪Img≫ Tag Properly
Multiple Radio Button Groups in One Form
What Do ≪ and ≫ Stand For