CSS 100% height layout with a scrollable table body - html

I have a 100% height layout split to three parts: header, content, footer.
I'd like to display a table inside a the content section with 100% height and i want the table body to have a vertical scroll bar for the table body content.
How can i do that?
it seems like i cannot set the tbody height to 100% and have a scrollbar?
html, body {
height: 100%;
padding: 0;
margin: 0;
}
#container {
display: table;
width: 100%;
height: 100%;
border: 1px solid red;
text-align: center;
}
#container > div {
display: table-row;
width: 100%;
}
#container > div > div {
display: table-cell;
width: 100%;
border-radius:10px;
}
#header > div {
height:50px;
border:solid 2px #aaa;
}
#content > div {
height: 100%;
background:#f0f4f0;
border:solid 2px #5a5;
}
#footer > div {
height:50px;
border:solid 2px #a55;
}
table {
table-layout:fixed;
margin:auto;
}
th, td {
padding:5px 10px;
border:1px solid #000;
}
thead, tfoot {
background:#f9f9f9;
display:table;
width:100%;
width:calc(100% - 18px);
}
tbody {
height:400px;
overflow:auto;
overflow-x:hidden;
display:block;
width:100%;
}
tbody tr {
display:table;
width:100%;
table-layout:fixed;
}
<div id="container">
<div id="header">
<div>header</div>
</div>
<div id="content">
<div>
<table>
<thead>
<tr>
<th scope="col">Header 1</th>
<th scope="col">Header 2</th>
<th scope="col">Header 3</th>
<th scope="col">Header 4</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell2 content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Footer 1</td>
<td>Footer 2</td>
<td>Footer 3</td>
<td>Footer 4</td>
</tr>
</tfoot>
</table>
</div>
</div>
<div id="footer">
<div>footer</div>
</div>
</div>

Your layout is a bit messed up. Too many containing div in my opinion. Did some changes using flex - so the table container will have
display: flex;
flex-direction: column;
overflow: auto;
and the table will have flex-grow: 1;
html,
body {
height: 100%;
padding: 0;
margin: 0;
}
#container {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
border: 1px solid red;
text-align: center;
}
#container>div {
width: 100%;
display: flex;
flex-direction: column;
}
#container>div>div {
width: 100%;
height: 100%;
border-radius: 10px;
overflow: auto;
}
#header {
flex-basis: 50px;
flex-grow: 0;
flex-shrink: 0;
}
#header>div {
height: 50px;
border: solid 2px #aaa;
}
#content {
flex-grow: 1;
}
#content>div {
height: 100%;
background: #f0f4f0;
border: solid 2px #5a5;
display: flex;
flex-direction: column;
}
#footer{
flex-basis: 50px;
flex-grow: 0;
flex-shrink: 0;
}
#footer>div {
height: 50px;
border: solid 2px #a55;
}
table {
flex-grow: 1;
table-layout: fixed;
margin: auto;
}
th,
td {
padding: 5px 10px;
border: 1px solid #000;
}
thead,
tfoot {
background: #f9f9f9;
display: table;
width: 100%;
width: calc(100% - 18px);
}
tbody {
overflow: auto;
overflow-x: hidden;
display: block;
width: 100%;
}
tbody tr {
display: table;
width: 100%;
table-layout: fixed;
}
<div id="container">
<div id="header">
<div>header</div>
</div>
<div id="content">
<div>
<table>
<thead>
<tr>
<th scope="col">Header 1</th>
<th scope="col">Header 2</th>
<th scope="col">Header 3</th>
<th scope="col">Header 4</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell2 content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Footer 1</td>
<td>Footer 2</td>
<td>Footer 3</td>
<td>Footer 4</td>
</tr>
</tfoot>
</table>
</div>
</div>
<div id="footer">
<div>footer</div>
</div>
</div>

I had to use javascript for this but maybe someone can come up with a pure CSS solution.
Main sections of the page
I'm using flexbox to position the header, main and footer sections of the page allowing the main to take up as much vertical space that it can:
body {
display: flex;
flex-direction: column;
}
main {
flex: 1;
}
The Table
I set the table to take up 100% of the height and width in the main section and set each tr element to display flex allowing all their direct child elements to take up equal amounts of space:
table {
width: 100%;
height: 100%;
}
tr {
display: flex;
}
tr > * {
flex: 1;
}
I've set the tbody element to display: block which will allow for content to be scrollable if it overflows:
tbody {
display: block;
overflow-y: scroll;
}
tbody tr {
height: 40vh; // for demonstrating the scrolling of the tbody
}
I then used some javascript to set the height of the tbody element, please find the documentation in the comments below:
setTbodyHeight();
window.addEventListener("resize", setTbodyHeight);
function setTbodyHeight() {
// get the viewport height
let viewportHeight = window.innerHeight;
// calculate how much of the height the main should consume
let headerHeight = getHeight("header");
let footerHeight = getHeight("footer");
let mainHeight = viewportHeight - (headerHeight + footerHeight);
// from the main height calcuate how much space would be available if you subtracted the tfoot/thead height
let theadHeight = getHeight("thead");
let tfootHeight = getHeight("tfoot");
let tbodyHeight = mainHeight - (theadHeight + tfootHeight);
// set the height of the tbody to this value
let tbody = document.querySelector("tbody");
tbody.style.height = tbodyHeight + "px";
function getHeight(elementName) {
let element = document.querySelector(elementName);
let elementCSS = window.getComputedStyle(element);
let height = parseInt(elementCSS.getPropertyValue("height"));
return height;
}
}
/* IGNORE RULES FROM HERE.....*/
html,
body {
height: 100%;
}
body {
font-family: sans-serif;
margin: 0;
}
header::after,
footer::after {
content: "." attr(class);
}
tbody tr:nth-child(even) {
background: firebrick;
color: white
}
td {
text-align: center;
}
/*.....TO HERE*/
body {
display: flex;
flex-direction: column;
}
main {
flex: 1;
}
table {
width: 100%;
height: 100%;
}
tr {
display: flex;
}
tr>* {
flex: 1;
}
tbody {
display: block;
overflow-y: scroll;
}
tbody tr {
height: 20vh;
}
tbody td {
line-height: 20vh;
}
<header class="header"></header>
<main class="main">
<table>
<thead>
<tr>
<th>Heading</th>
<th>Heading</th>
<th>Heading</th>
</tr>
</thead>
<tbody>
<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>
<tfoot>
<tr>
<td>Footer</td>
<td>Footer</td>
<td>Footer</td>
</tr>
</tfoot>
</table>
</main>
<footer class="footer"></footer>

Related

How to keep scrollbars of a table in tact after a page refresh

I have a table where the 1st column and 1st row and frozen and have horizontal and vertical scrollbars to go through the entire table within a 500x500 div
When the page refreshes, I lose the position of the 2 scrollbars and the table pops back to the top
Is it possible to preserve the scrollbars?
I have a table where the 1st column and 1st row and frozen and have horizontal and vertical scrollbars to go through the entire table within a 500x500 div
When the page refreshes, I lose the position of the 2 scrollbars and the table pops back to the top
Is it possible to preserve the scrollbars?
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
.intro {
max-width: 1280px;
margin: 1em auto;
}
.table-grid {
position: relative;
width: 100%;
z-index: 1;
margin: auto;
overflow: auto;
height: 350px;
}
.table-grid table {
width: 100%;
min-width: 1280px;
margin: auto;
border-collapse: separate;
border-spacing: 0;
}
.table-wrap {
position: relative;
}
.table-grid th,
.table-grid td {
padding: 5px 10px;
border: 1px solid #000;
background: #fff;
vertical-align: top;
}
.table-grid thead th {
background: #333;
color: #fff;
position: -webkit-sticky;
position: sticky;
top: 0;
}
/* safari and ios need the tfoot itself to be position:sticky also */
.table-grid tfoot,
.table-grid tfoot th,
.table-grid tfoot td {
position: -webkit-sticky;
position: sticky;
bottom: 0;
background: #666;
color: #fff;
z-index: 4;
}
th:first-child {
position: -webkit-sticky;
position: sticky;
left: 0;
z-index: 2;
background: #ccc;
}
thead th:first-child,
tfoot th:first-child {
z-index: 5;
}
/*Highlight rows*/
.table_grid tr:hover,
.table_grid tr:hover td {
background-color: rgba(220, 220, 220, 0.5);
}
/*Highlight rows including header
.table_grid tr:hover th,
.table_grid tr:hover td {
background-color: rgba(220, 220, 220, 0.5);
}
*/
.mvcode_right:hover .mvtooltip_right {
display: block;
}
.mvtooltip_right {
display: none;
background: black;
color: white;
margin-left: 100px;
padding: 10px;
position: absolute;
z-index: 1000;
border-radius: 6px;
opacity: 0.8;
}
<div class="table-grid">
<table>
<thead>
<tr>
<th>Header 1</th>
<th>Header 1</th>
<th>Header 1</th>
<th>Header 1</th>
<th>Header 1</th>
<th>Header 1</th>
<th>Header 1</th>
<th>Header 1</th>
</tr>
</thead>
<tbody>
<tr>
<th>
<div class="mvcode_right">
First top Column
</div>
</th>
<td>Cell content<br> test </td>
<td>Cell content longer</td>
<td>Cell content with more content and more content Cell </td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<th>
<div class="mvcode_right">
Second top Column
</div>
</th>
<td>Cell content<br> test </td>
<td>Cell content longer</td>
<td>Cell content with more content and more content Cell </td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<th>
<div class="mvcode_right">
Third top Column
</div>
</th>
<td>Cell content<br> test </td>
<td>Cell content longer</td>
<td>Cell content with more content and more content Cell </td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<th>
<div class="mvcode_right">
Forth top Column
</div>
</th>
<td>Cell content<br> test </td>
<td>Cell content longer</td>
<td>Cell content with more content and more content Cell </td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<th>
<div class="mvcode_right">
Fifth top Column
</div>
</th>
<td>Cell content<br> test </td>
<td>Cell content longer</td>
<td>Cell content with more content and more content Cell </td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<th>
<div class="mvcode_right">
Sixth top Column
</div>
</th>
<td>Cell content<br> test </td>
<td>Cell content longer</td>
<td>Cell content with more content and more content Cell </td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<th>
<div class="mvcode_right">
Seventh top Column
</div>
</th>
<td>Cell content<br> test </td>
<td>Cell content longer</td>
<td>Cell content with more content and more content Cell </td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
</table>
</div>
You can listen for scroll event and store scroll position in localStorage:
const table = document.querySelector(".table-grid");
table.scrollTop = localStorage.getItem("scrollTop");
table.scrollLeft = localStorage.getItem("scrollLeft");
table.addEventListener("scroll", e =>
{
localStorage.setItem("scrollTop", e.target.scrollTop);
localStorage.setItem("scrollLeft", e.target.scrollLeft);
});
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
.intro {
max-width: 1280px;
margin: 1em auto;
}
.table-grid {
position: relative;
width: 100%;
z-index: 1;
margin: auto;
overflow: auto;
height: 350px;
}
.table-grid table {
width: 100%;
min-width: 1280px;
margin: auto;
border-collapse: separate;
border-spacing: 0;
}
.table-wrap {
position: relative;
}
.table-grid th,
.table-grid td {
padding: 5px 10px;
border: 1px solid #000;
background: #fff;
vertical-align: top;
}
.table-grid thead th {
background: #333;
color: #fff;
position: -webkit-sticky;
position: sticky;
top: 0;
}
/* safari and ios need the tfoot itself to be position:sticky also */
.table-grid tfoot,
.table-grid tfoot th,
.table-grid tfoot td {
position: -webkit-sticky;
position: sticky;
bottom: 0;
background: #666;
color: #fff;
z-index: 4;
}
th:first-child {
position: -webkit-sticky;
position: sticky;
left: 0;
z-index: 2;
background: #ccc;
}
thead th:first-child,
tfoot th:first-child {
z-index: 5;
}
/*Highlight rows*/
.table_grid tr:hover,
.table_grid tr:hover td {
background-color: rgba(220, 220, 220, 0.5);
}
/*Highlight rows including header
.table_grid tr:hover th,
.table_grid tr:hover td {
background-color: rgba(220, 220, 220, 0.5);
}
*/
.mvcode_right:hover .mvtooltip_right {
display: block;
}
.mvtooltip_right {
display: none;
background: black;
color: white;
margin-left: 100px;
padding: 10px;
position: absolute;
z-index: 1000;
border-radius: 6px;
opacity: 0.8;
}
<div class="table-grid">
<table>
<thead>
<tr>
<th>Header 1</th>
<th>Header 1</th>
<th>Header 1</th>
<th>Header 1</th>
<th>Header 1</th>
<th>Header 1</th>
<th>Header 1</th>
<th>Header 1</th>
</tr>
</thead>
<tbody>
<tr>
<th>
<div class="mvcode_right">
First top Column
</div>
</th>
<td>Cell content<br> test </td>
<td>Cell content longer</td>
<td>Cell content with more content and more content Cell </td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<th>
<div class="mvcode_right">
Second top Column
</div>
</th>
<td>Cell content<br> test </td>
<td>Cell content longer</td>
<td>Cell content with more content and more content Cell </td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<th>
<div class="mvcode_right">
Third top Column
</div>
</th>
<td>Cell content<br> test </td>
<td>Cell content longer</td>
<td>Cell content with more content and more content Cell </td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<th>
<div class="mvcode_right">
Forth top Column
</div>
</th>
<td>Cell content<br> test </td>
<td>Cell content longer</td>
<td>Cell content with more content and more content Cell </td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<th>
<div class="mvcode_right">
Fifth top Column
</div>
</th>
<td>Cell content<br> test </td>
<td>Cell content longer</td>
<td>Cell content with more content and more content Cell </td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<th>
<div class="mvcode_right">
Sixth top Column
</div>
</th>
<td>Cell content<br> test </td>
<td>Cell content longer</td>
<td>Cell content with more content and more content Cell </td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
<tr>
<th>
<div class="mvcode_right">
Seventh top Column
</div>
</th>
<td>Cell content<br> test </td>
<td>Cell content longer</td>
<td>Cell content with more content and more content Cell </td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
</tbody>
</table>
</div>
https://jsfiddle.net/Lmdw538a/1/

Use sp_send_dbmail to have two horizontally aligned tables

I've referred to this question: HTML — Two Tables Horizontally Side by Side
In SQL I have tried the following:
1.
DECLARE #HTML NVARCHAR(2000);
SET #HTML =
N'
<table border=1 style=''display: inline-block''>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
</table>
<table border=1 style=''display: inline-block''>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
</table>
'
EXEC msdb..sp_send_dbmail
#recipients = 'me#blahblah.co.uk',
#subject = 'foo',
#body_format = 'html',
#body = #HTML
2.
DECLARE #HTML NVARCHAR(2000);
SET #HTML =
N'
<table border=1 style=''float: left''>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
</table>
<table border=1 style=''float: left''>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
</table>
'
EXEC msdb..sp_send_dbmail
#recipients = 'me#blahblah.co.uk',
#subject = 'foo',
#body_format = 'html',
#body = #HTML
Neither 1 or 2 aligns the tables side-by-side in the email. What am I doing wrong?
As per my understanding, you are missing the HTML tag try the below one.
Add second table float property to right and both table display property to inline-table.
DECLARE #HTML NVARCHAR(2000);
SET #HTML = N'<html> <body> <table border=1 style=''float: left; display: inline-table;''>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
</table>
<table border=1 style=''float: right; display: inline-table;''>
<tr>
<td>Cell content</td>
<td>Cell content</td>
<td>Cell content</td>
</tr>
</table>
</body>
</html>'

Auto wrap td every 4 columns

I have 8 td in my table and my problem is I would like to wrap the td every 4th column. So in short, I want the 5th td will display in new line. Please help me. Thanks.
<div id="schedule">
<table>
<tbody>
<tr>
<td>terdg</td>
<td>yhr6t</td>
<td>yhr6t</td>
<td>yhr6t</td>
<td>hgf</td>
<td>gdrg</td>
<td>tyht</td>
<td>drf</td>
</tr>
</tbody>
</table>
</div>
If you must retain the same HTML structure you can manage this with floats but it's likely that you will lose the "tableness" of the cells and you may have to adjust accordingly.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
::before,
::after {
box-sizing: inherit;
}
table {}
td {
float: left;
width: 25%;
padding: 1em;
border: 1px solid grey;
white-space: nowrap;
}
td:nth-child(4n + 1) {
clear: both;
}
<div id="schedule">
<table>
<tbody>
<tr>
<td>cell 1</td>
<td>cell 2</td>
<td>cell 3</td>
<td>cell 4</td>
<td>cell 5</td>
<td>cell 6</td>
<td>cell 7</td>
<td>cell 8</td>
<td>cell 9</td>
<td>cell 10</td>
<td>cell 11</td>
<td>cell 12</td>
</tr>
</tbody>
</table>
</div>
<div id="schedule">
<table>
<tbody>
<tr>
<td>terdg</td>
<td>yhr6t</td>
<td>yhr6t</td>
<td>yhr6t</td>
</tr>
<tr>
<td>hgf</td>
</tr>
<tr>
<td>gdrg</td>
<td>tyht</td>
<td>drf</td>
</tr>
</tbody>
</table>
</div>

HTML+CSS: Scrolling inside a div taking remaining screen height

How can I make a table in a div (that takes the remaining screen height) scrollable without scrolling the whole page?
I know how to make it scrollable inside the div by wrapping it like this
<div style="overflow: auto; height: 300px;">
<table>...</table>
</div>
but how can I make the div's height use all of the remaining screen height?
EDIT: here is my code so far:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Table</title>
<link rel=stylesheet href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>
<div class="col-md-12">
<div class="panel panel-default">
<!-- Header -->
<div class="panel-heading">Panel Heading<button class="pull-right" onclick="myFunction();">
<span class="glyphicon glyphicon-filter"></span>
</button>
</div>
<div class="panel-body row" id="filter" style="display: none; padding-top: 0;">
<div class="col-md-6">
<div class="col-sm-6 column" style="height: auto; margin-top: 1em">
<!-- filter selector -->
</div>
</div>
</div>
<!-- Table -->
<div class="panel-body" style="overflow: auto; height: 300px;">
<table class="table">
...
</table>
</div>
</div>
</div>
<script>
function myFunction() {
var x = document.getElementById('filter');
if (x.style.display === 'none') {
x.style.display = 'block';
} else {
x.style.display = 'none';
}
}
</script>
</body>
</html>
Use vh instead % : [100vh] vertical height
i set width 90%, you can change it.
table is always center because div.parent is margin: 0 auto
.parent {
background-color: #ccc;
width: 90%;
height: 100vh;
overflow: auto;
margin: 0 auto
}
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<div class="parent">
<table class="table">
<thead>
<tr>
<th>#</th>
<th>Column heading</th>
<th>Column heading</th>
<th>Column heading</th>
</tr>
</thead>
<tbody>
<tr class="active">
<th scope="row">1</th>
<td>Column content</td>
<td>Column content</td>
<td>Column content</td>
</tr>
<tr class="active">
<th scope="row">1</th>
<td>Column content</td>
<td>Column content</td>
<td>Column content</td>
</tr>
<tr class="active">
<th scope="row">1</th>
<td>Column content</td>
<td>Column content</td>
<td>Column content</td>
</tr>
<tr class="active">
<th scope="row">1</th>
<td>Column content</td>
<td>Column content</td>
<td>Column content</td>
</tr>
<tr class="active">
<th scope="row">1</th>
<td>Column content</td>
<td>Column content</td>
<td>Column content</td>
</tr>
<tr class="active">
<th scope="row">1</th>
<td>Column content</td>
<td>Column content</td>
<td>Column content</td>
</tr>
<tr class="active">
<th scope="row">1</th>
<td>Column content</td>
<td>Column content</td>
<td>Column content</td>
</tr>
<tr class="active">
<th scope="row">1</th>
<td>Column content</td>
<td>Column content</td>
<td>Column content</td>
</tr>
<tr class="active">
<th scope="row">1</th>
<td>Column content</td>
<td>Column content</td>
<td>Column content</td>
</tr>
<tr class="active">
<th scope="row">1</th>
<td>Column content</td>
<td>Column content</td>
<td>Column content</td>
</tr>
<tr class="active">
<th scope="row">1</th>
<td>Column content</td>
<td>Column content</td>
<td>Column content</td>
</tr>
<tr class="active">
<th scope="row">1</th>
<td>Column content</td>
<td>Column content</td>
<td>Column content</td>
</tr>
<tr class="active">
<th scope="row">1</th>
<td>Column content</td>
<td>Column content</td>
<td>Column content</td>
</tr>
<tr class="active">
<th scope="row">1</th>
<td>Column content</td>
<td>Column content</td>
<td>Column content</td>
</tr>
<tr class="active">
<th scope="row">1</th>
<td>Column content</td>
<td>Column content</td>
<td>Column content</td>
</tr>
<tr class="active">
<th scope="row">1</th>
<td>Column content</td>
<td>Column content</td>
<td>Column content</td>
</tr>
<tr class="active">
<th scope="row">1</th>
<td>Column content</td>
<td>Column content</td>
<td>Column content</td>
</tr>
<tr class="active">
<th scope="row">1</th>
<td>Column content</td>
<td>Column content</td>
<td>Column content</td>
</tr>
<tr class="active">
<th scope="row">1</th>
<td>Column content</td>
<td>Column content</td>
<td>Column content</td>
</tr>
<tr class="active">
<th scope="row">1</th>
<td>Column content</td>
<td>Column content</td>
<td>Column content</td>
</tr>
<tr class="active">
<th scope="row">1</th>
<td>Column content</td>
<td>Column content</td>
<td>Column content</td>
</tr>
<tr class="active">
<th scope="row">1</th>
<td>Column content</td>
<td>Column content</td>
<td>Column content</td>
</tr>
<tr class="active">
<th scope="row">1</th>
<td>Column content</td>
<td>Column content</td>
<td>Column content</td>
</tr>
</tbody>
</table>
</div>
use viewport percentages but it will not affect old ie.
height: 100vh;
with the overview, you can do the following
<div style="
overflow-y: auto;
position: fixed;
top: 0;
right: 0;
bottom: 0;
width: n%;
border-left: 1px solid #000;
">
<table>...</table>
</div>
I'm leaving it on the right and I use the border-left so you can see that you need a reasonable width
EDIT: for edit html
you set parent tag position property with relative.
You using position: absolute; for div tag

<table><tbody> scrollable?

I would like to have a table with a scrollbar to the right.
I want to accomplish this without any plugins(jQuery) just with css.
The table header is supposed to stay fixed.
What do I need to do to get this working?
You have taken on a task that, if you succeed, will make you a hero. I tried this and the straightforward thing -- to position:fixed; the <thead> -- is impossible. I had to copy all of the <thead> into a new object. But when you do that, the horizontal spacing of the <th> elements all goes away so the headings don't line up with the <td>s anymore. I ended up doing something like this:
First of all, abandon ie6 and ie7. There's no hope for those guys.
Make two copies of the table, one where the body is invisible and the <thead> is visible, and the other where it's vice-versa.
Give z-index:1; to the table with the visible <thead>.
Give z-index:0; to the table with the visible <tbody>.
Deal with horizontal scrolling, but not until after you find that onScroll isn't an ie8 event (not to mention ie6), so that you have to take a setInterval break every tenth of a second or so just to handle scrolling the <thead> left and right in ie8.
This will give you a table body of infinite scroll in both axes, with a table head that scrolls in the x axis only. Pretty much works in FF, Chrome, and Safari. But is shaky in ie8. A real pita.
Good luck, and please write if you get this to work!
Only the Firefox and IE6-7 browsers support the built-in <tbody> scrolling:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Scrolling</title>
<style type="text/css">
div.content
{
border: #000000 1px solid;
height: 400px;
overflow-y: auto;
width: 800px;
}
.fixedHeader
{
white-space: nowrap;
}
.fixedHeader tr
{
height: auto;
position: relative;
}
.fixedHeader tr td
{
background-color: #778899;
border: #000000 1px solid;
text-align: center;
}
tbody.scrollContent
{
overflow-x: hidden;
overflow-y: auto;
height: 370px;
}
.scrollContent tr td
{
background-color: #C0C0C0;
border: #000000 1px solid;
padding-right: 22px;
vertical-align: top;
}
</style>
<!--[if IE]>
<style type=text/css>
div.content
{
overflow-x: hidden;
overflow-y: auto;
}
</style>
<![endif]-->
</head>
<body>
<div>
<div class="content">
<table cellspacing="0">
<thead class="fixedHeader">
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
<td>Cell 4</td>
</tr>
</thead>
<tbody class="scrollContent">
<tr>
<td>Pages can be displayed either with or without tabs. Pages can be displayed either with or without tabs. Pages can be displayed either with or without tabs. Pages can be displayed either with or without tabs. Pages with tabs are preferred for a standard user interface, and pages without tabs are preferred for a wizard. If tabs are omitted, you must provide a way of moving through the pages. For instance, Back and Next buttons can be implemented. Pages can be displayed either with or without tabs. Pages with tabs are preferred for a standard user interface, and pages without tabs are preferred for a wizard. If tabs are omitted, you must provide a way of moving through the pages. For instance, Back and Next buttons can be implemented. Pages can be displayed either with or without tabs. Pages with tabs are preferred for a standard user interface, and pages without tabs are preferred for a wizard. If tabs are omitted, you must provide a way of moving through the pages. For instance, Back and Next buttons can be implemented.</td>
<td>Pages can be displayed either with or without tabs. Pages can be displayed either with or without tabs. </td>
<td>Pages can be displayed either with or without tabs. </td>
<td>Pages can be displayed either with or without tabs. Pages can be displayed either with or without tabs. Pages can be displayed either with or without tabs. Pages can be displayed either with or without tabs. Pages with tabs are preferred for a standard user interface, and pages without tabs are preferred for a wizard. If tabs are omitted, you must provide a way of moving through the pages. For instance, Back and Next buttons can be implemented. Pages can be displayed either with or without tabs. Pages with tabs are preferred for a standard user interface, and pages without tabs are preferred for a wizard. If tabs are omitted, you must provide a way of moving through the pages. For instance, Back and Next buttons can be implemented. Pages can be displayed either with or without tabs. Pages with tabs are preferred for a standard user interface, and pages without tabs are preferred for a wizard. If tabs are omitted, you must provide a way of moving through the pages. For instance, Back and Next buttons can be implemented.</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
Here is the solution,
Table fixed header and the content inside the table can be scrollable.
HTML Part
<div class="table_wrapper">
<div class="header">
<div class="head1">Left</div>
<div class="head2">Center</div>
<div class="head3">Right Column</div>
</div>
<div class="tbody">
<table>
<tbody><tr><td class="td1">1</td><td class="td2">2</td><td class="td3">3</td></tr>
<tr><td class="td1">1</td><td>2</td><td class="td3">3</td></tr>
<tr><td class="td1">2</td><td>second</td><td class="td3">third</td></tr>
<tr><td class="td1">3</td><td>second</td><td class="td3">third</td></tr>
<tr><td class="td1">first</td><td>second</td><td class="td3">third</td></tr>
<tr><td class="td1">first</td><td>second</td><td class="td3">third</td></tr>
<tr><td class="td1">first</td><td>second</td><td class="td3">third</td></tr>
<tr><td class="td1">first</td><td>second</td><td class="td3">third</td></tr>
<tr><td class="td1">first</td><td>second</td><td class="td3">third</td></tr>
<tr><td class="td1">first</td><td>second</td><td class="td3">third</td></tr>
<tr><td class="td1">first</td><td>second</td><td class="td3">third</td></tr>
</tbody></table>
</div>
</div>
CSS Part
.table_wrapper {background:tomato;border:1px double olive;float:left;}
.tbody{height:80px;overflow-y:auto;width:400px;background:yellow;}
table{border-collapse:collapse; width:100%;}
td{border-right:1px solid red;border-bottom:1px solid red;padding:1px 5px;}
.td3{border-right-width:0;}
.header{ width:400px;background:DodgerBlue;border-bottom:1px solid red;}
.header div{padding:1px 5px;float:left;border-right:1px solid orange;}
.header .head3{float:none;border-right-width:0;}
.head3 span{padding-left:5px;}
.td1{width:100px;}
.td2{width:140px;}
.header .head1{width:100px;}
.header .head2{width:140px;}
This simple CSS should do the trick:
table.table-scroll-body {
position: relative;
height: 200px; }
table.table-scroll-body tbody {
position: absolute;
width: 100%;
max-height: 150px;
overflow: auto; }
And the HTML if you need it..
<table class="table-scroll-body">
<thead>
<th>Header 1</th>
<th>Header 2</th>
</thead>
<tbody>
<tr>
<td>Some content..</td>
<td>Some content..</td>
</tr>
<tr>
<td>Some content..</td>
<td>Some content..</td>
</tr>
<tr>
<td>Some content..</td>
<td>Some content..</td>
</tr>
</tbody>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<style>
table
{
width: 320px;
display: block;
border:solid black 1px;
}
thead
{
display: inline-block;
width: 100%;
height: 20px;
}
tbody
{
height: 200px;
display: inline-block;
width: 100%;
overflow: auto;
}
th, td
{
width: 100px;
text-align:center;
}
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
</tr>
</tbody>
</table>
</body>
</html>
branching off of astrandr's answer.. here is how I did it, using their example:
css:
.transactHistory table
{
width: 320px;
display: block;
}
.transactHistory thead
{
display: inline-block;
}
.transactHistory tbody
{
height: 133px;
display: inline-block;
width: 100%;
overflow: auto;
}
.transactHistory th
{
width: 100px;
text-align:center;
}
.transactHistory tr
{
width: 100px;
text-align:center;
}
.transactHistory td
{
width: 100px;
text-align:center;
}
Table:
<div class="transactHistory">
(..table code)
</div>
This works, took it right off my website:
#news_box {
overflow: scroll;
overflow-x: hidden;
}
EDIT:
I also just found this with a nice example:
http://www.imaputz.com/cssStuff/bigFourVersion.html
Here's another good article on it:
http://www.scientificpsychic.com/blogentries/html-and-css-scrolling-table-with-fixed-heading.html