I am writing a page where I need an html table to maintain a set size. I need the headers at the top of the table to stay there at all times but I also need the body of the table to scroll no matter how many rows are added to the table.
I want it to look like method 2 in this url: http://www.cssplay.co.uk/menu/tablescroll.html
I have tried doing this but no scrollbar appears:
tbody {
height: 80em;
overflow: scroll;
}
_x000D_
<table border=1 id="qandatbl" align="center">
<tr>
<th class="col1">Question No</th>
<th class="col2">Option Type</th>
<th class="col1">Duration</th>
</tr>
<tbody>
<tr>
<td class='qid'></td>
<td class="options"></td>
<td class="duration"></td>
</tr>
</tbody>
</table>
_x000D_
This question is related to
html
css
scroll
html-table
overflow
just add on table
style="overflow-x:auto;"
<table border=1 id="qandatbl" align="center" style="overflow-x:auto;">_x000D_
<tr>_x000D_
<th class="col1">Question No</th>_x000D_
<th class="col2">Option Type</th>_x000D_
<th class="col1">Duration</th>_x000D_
</tr>_x000D_
_x000D_
<tbody>_x000D_
<tr>_x000D_
<td class='qid'></td>_x000D_
<td class="options"></td>_x000D_
<td class="duration"></td>_x000D_
</tr>_x000D_
</tbody>_x000D_
</table>
_x000D_
style="overflow-x:auto;"`
The accepted answer provided a good starting point, but if you resize the frame, change the column widths, or even change the table data, the headers will get messed up in various ways. Every other example I've seen has similar issues, or imposes some serious restrictions on the table's layout.
I think I've finally got all these problems solved, though. It took a lot of CSS, but the final product is about as reliable and easy to use as a normal table.
Here's an example that has all the required features to replicate the table referenced by the OP: jsFiddle
The colors and borders would have to be changed to make it identical to the reference. Information on how to make those kinds of changes is provided in the CSS comments.
Here's the code:
/*the following html and body rule sets are required only if using a % width or height*/_x000D_
/*html {_x000D_
width: 100%;_x000D_
height: 100%;_x000D_
}*/_x000D_
body {_x000D_
box-sizing: border-box;_x000D_
width: 100%;_x000D_
height: 100%;_x000D_
margin: 0;_x000D_
padding: 0 20px 0 20px;_x000D_
text-align: center;_x000D_
background: white;_x000D_
}_x000D_
.scrollingtable {_x000D_
box-sizing: border-box;_x000D_
display: inline-block;_x000D_
vertical-align: middle;_x000D_
overflow: hidden;_x000D_
width: auto; /*if you want a fixed width, set it here, else set to auto*/_x000D_
min-width: 0/*100%*/; /*if you want a % width, set it here, else set to 0*/_x000D_
height: 188px/*100%*/; /*set table height here; can be fixed value or %*/_x000D_
min-height: 0/*104px*/; /*if using % height, make this large enough to fit scrollbar arrows + caption + thead*/_x000D_
font-family: Verdana, Tahoma, sans-serif;_x000D_
font-size: 15px;_x000D_
line-height: 20px;_x000D_
padding: 20px 0 20px 0; /*need enough padding to make room for caption*/_x000D_
text-align: left;_x000D_
}_x000D_
.scrollingtable * {box-sizing: border-box;}_x000D_
.scrollingtable > div {_x000D_
position: relative;_x000D_
border-top: 1px solid black;_x000D_
height: 100%;_x000D_
padding-top: 20px; /*this determines column header height*/_x000D_
}_x000D_
.scrollingtable > div:before {_x000D_
top: 0;_x000D_
background: cornflowerblue; /*header row background color*/_x000D_
}_x000D_
.scrollingtable > div:before,_x000D_
.scrollingtable > div > div:after {_x000D_
content: "";_x000D_
position: absolute;_x000D_
z-index: -1;_x000D_
width: 100%;_x000D_
height: 100%;_x000D_
left: 0;_x000D_
}_x000D_
.scrollingtable > div > div {_x000D_
min-height: 0/*43px*/; /*if using % height, make this large enough to fit scrollbar arrows*/_x000D_
max-height: 100%;_x000D_
overflow: scroll/*auto*/; /*set to auto if using fixed or % width; else scroll*/_x000D_
overflow-x: hidden;_x000D_
border: 1px solid black; /*border around table body*/_x000D_
}_x000D_
.scrollingtable > div > div:after {background: white;} /*match page background color*/_x000D_
.scrollingtable > div > div > table {_x000D_
width: 100%;_x000D_
border-spacing: 0;_x000D_
margin-top: -20px; /*inverse of column header height*/_x000D_
/*margin-right: 17px;*/ /*uncomment if using % width*/_x000D_
}_x000D_
.scrollingtable > div > div > table > caption {_x000D_
position: absolute;_x000D_
top: -20px; /*inverse of caption height*/_x000D_
margin-top: -1px; /*inverse of border-width*/_x000D_
width: 100%;_x000D_
font-weight: bold;_x000D_
text-align: center;_x000D_
}_x000D_
.scrollingtable > div > div > table > * > tr > * {padding: 0;}_x000D_
.scrollingtable > div > div > table > thead {_x000D_
vertical-align: bottom;_x000D_
white-space: nowrap;_x000D_
text-align: center;_x000D_
}_x000D_
.scrollingtable > div > div > table > thead > tr > * > div {_x000D_
display: inline-block;_x000D_
padding: 0 6px 0 6px; /*header cell padding*/_x000D_
}_x000D_
.scrollingtable > div > div > table > thead > tr > :first-child:before {_x000D_
content: "";_x000D_
position: absolute;_x000D_
top: 0;_x000D_
left: 0;_x000D_
height: 20px; /*match column header height*/_x000D_
border-left: 1px solid black; /*leftmost header border*/_x000D_
}_x000D_
.scrollingtable > div > div > table > thead > tr > * > div[label]:before,_x000D_
.scrollingtable > div > div > table > thead > tr > * > div > div:first-child,_x000D_
.scrollingtable > div > div > table > thead > tr > * + :before {_x000D_
position: absolute;_x000D_
top: 0;_x000D_
white-space: pre-wrap;_x000D_
color: white; /*header row font color*/_x000D_
}_x000D_
.scrollingtable > div > div > table > thead > tr > * > div[label]:before,_x000D_
.scrollingtable > div > div > table > thead > tr > * > div[label]:after {content: attr(label);}_x000D_
.scrollingtable > div > div > table > thead > tr > * + :before {_x000D_
content: "";_x000D_
display: block;_x000D_
min-height: 20px; /*match column header height*/_x000D_
padding-top: 1px;_x000D_
border-left: 1px solid black; /*borders between header cells*/_x000D_
}_x000D_
.scrollingtable .scrollbarhead {float: right;}_x000D_
.scrollingtable .scrollbarhead:before {_x000D_
position: absolute;_x000D_
width: 100px;_x000D_
top: -1px; /*inverse border-width*/_x000D_
background: white; /*match page background color*/_x000D_
}_x000D_
.scrollingtable > div > div > table > tbody > tr:after {_x000D_
content: "";_x000D_
display: table-cell;_x000D_
position: relative;_x000D_
padding: 0;_x000D_
border-top: 1px solid black;_x000D_
top: -1px; /*inverse of border width*/_x000D_
}_x000D_
.scrollingtable > div > div > table > tbody {vertical-align: top;}_x000D_
.scrollingtable > div > div > table > tbody > tr {background: white;}_x000D_
.scrollingtable > div > div > table > tbody > tr > * {_x000D_
border-bottom: 1px solid black;_x000D_
padding: 0 6px 0 6px;_x000D_
height: 20px; /*match column header height*/_x000D_
}_x000D_
.scrollingtable > div > div > table > tbody:last-of-type > tr:last-child > * {border-bottom: none;}_x000D_
.scrollingtable > div > div > table > tbody > tr:nth-child(even) {background: gainsboro;} /*alternate row color*/_x000D_
.scrollingtable > div > div > table > tbody > tr > * + * {border-left: 1px solid black;} /*borders between body cells*/
_x000D_
<div class="scrollingtable">_x000D_
<div>_x000D_
<div>_x000D_
<table>_x000D_
<caption>Top Caption</caption>_x000D_
<thead>_x000D_
<tr>_x000D_
<th><div label="Column 1"></div></th>_x000D_
<th><div label="Column 2"></div></th>_x000D_
<th><div label="Column 3"></div></th>_x000D_
<th>_x000D_
<!--more versatile way of doing column label; requires 2 identical copies of label-->_x000D_
<div><div>Column 4</div><div>Column 4</div></div>_x000D_
</th>_x000D_
<th class="scrollbarhead"/> <!--ALWAYS ADD THIS EXTRA CELL AT END OF HEADER ROW-->_x000D_
</tr>_x000D_
</thead>_x000D_
<tbody>_x000D_
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>_x000D_
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>_x000D_
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>_x000D_
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>_x000D_
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>_x000D_
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>_x000D_
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>_x000D_
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>_x000D_
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>_x000D_
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>_x000D_
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>_x000D_
<tr><td>Lorem ipsum</td><td>Dolor</td><td>Sit</td><td>Amet consectetur</td></tr>_x000D_
</tbody>_x000D_
</table>_x000D_
</div>_x000D_
Faux bottom caption_x000D_
</div>_x000D_
</div>_x000D_
_x000D_
<!--[if lte IE 9]><style>.scrollingtable > div > div > table {margin-right: 17px;}</style><![endif]-->
_x000D_
The CSS:
div{ overflow-y:scroll; overflow-x:scroll; width:20px; height:30px; } table{ width:50px; height:50px; }
You can make the table and the DIV around the table be any size you want, just make sure that the DIV is smaller than the table. You MUST contain the table inside of the DIV.
I resolved this problem by separating my content into two tables.
One table is the header row.
The seconds is also <table>
tag, but wrapped by <div>
with static height and overflow scroll.
Not sure why no one mentioned to just use the built-in sticky header style for elements. Worked great for me.
.tableContainerDiv {
overflow: auto;
max-height: 80em;
}
th {
position: sticky;
top: 0;
background: white;
}
Put a min-width on the in @media if you need to make responsive (or similar).
see Table headers position:sticky or Position Sticky and Table Headers
Very easy, just wrap the table in a div that has overflow-y:scroll;
and overflow-x:scroll
properties, and make the div have a width and length smaller than the table.
IT WILL WORK!!!
If you get to the point where all the mentioned solutions don't work (as it got for me), do this:
Like this, in your HTML
<div class="table-header-class">
<table>
<thead>
<tr>
<th>Ava</th>
<th>Alexis</th>
<th>Mcclure</th>
</tr>
</thead>
</table>
</div>
<div class="table-content-class">
<table>
<tbody>
<tr>
<td>I am the boss</td>
<td>No, da-da is not the boss!</td>
<td>Alexis, I am the boss, right?</td>
</tr>
</tbody>
</table>
</div>
Then style the second table's parent to allow vertical scroll, in your CSS
.table-content-class {
overflow-y: scroll; // use auto; or scroll; to allow vertical scrolling;
overflow-x: hidden; // disable horizontal scroll
}
You have to insert your <table>
into a <div>
that it has fixed size, and in <div>
style you have to set overflow: scroll
.
Worth noting, that depending on your purpose (mine was the autofill results of a searchbar) you may want the height to be changeable, and for the scrollbar to only exist if the height exceeds that.
If you want that, replace height: x;
with max-height: x;
, and overflow:scroll
with overflow:auto
.
Additionally, you can use overflow-x
and overflow-y
if you want, and obviously the same thing works horizontally with width : x;
Source: Stackoverflow.com