Gridbox: Shrink contents of grid row to make two equal height rows - html

Assume I have a gridbox with 4 columns and 1 row. Parent container 1 & 2 are children of this gridbox. Parent container1 has a colspan of 3 and container2 has a colspan of 1 column. Both container have multiple child components, that are responsive and change size on window resize. Child 5 components has a table inside, that contains over 250+ records. The goal is to make this table scrollable, with perfectly equal content height of gridbox and without knowing any dimensions of parent or child containers.
So parent container2 has to be same height as parent container1, therefore something has to be done with child5
JSFiddle example
Expected layout: (Same row height and scrollable table)
Current layout: (Unequal content height, table is not scrollable)
I tried implementing flexbox for this scenario, but it seemed to make things harder. I also tried adding display: flex and flex: flex-shrink to the child5 container but with no results whatsoever.
I know I can programmatically take the height of container1 and calculate the needed height of child5 but I feel like there's more elegant solution using CSS + I don't wanna add too much event listeners on window resize.
Would love to take a look at your suggestions.

It is possible to apply display: flex for your .container1 class and use flex property:
*, html, body {
box-sizing: border-box;
margin: 0;
}
body {
font-family: sans-serif;
font-weight: 600;
}
.grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 5px;
border: 1px solid black;
padding: 5px;
}
.container1 {
grid-column: 1/4;
background: blue;
display: flex;
flex-direction: column;
height: 100%;
flex: 1;
}
.container1 div {
flex: 1;
}
.container2 {
background: red;
}
.child, .child1, .child3, .child5 {
border: 1px solid black;
padding: 15px;
background: gray
}
.container1, .container2 {
border: 1px solid black;
padding: 5px;
}
.table, th, td {
border: 1px solid black;
width: 100%;
}
.child1, .child3 {
padding: 40px 15px 40px 15px;
}
.child5 {
overflow-Y: scroll;
}
<div class="grid">
<div class="container1">
parent container 1
<div class="child1">
child 1
</div>
<div class="child">
child 2
</div>
<div class="child3">
child 3
</div>
</div>
<div class="container2">
parent container 2
<div class="child">
child 4
</div>
<div class="child5">
child 5
<table>
<tr>
<th>prop</th>
<th>value</th>
</tr>
<tr>
<th>prop</th>
<th>value</th>
</tr>
<tr>
<th>prop</th>
<th>value</th>
</tr>
<tr>
<th>prop</th>
<th>value</th>
</tr>
<tr>
<th>prop</th>
<th>value</th>
</tr>
<tr>
<th>prop</th>
<th>value</th>
</tr>
<tr>
<th>prop</th>
<th>value</th>
</tr>
<tr>
<th>prop</th>
<th>value</th>
</tr>
<tr>
<th>prop</th>
<th>value</th>
</tr>
<tr>
<th>prop</th>
<th>value</th>
</tr>
<tr>
<th>prop</th>
<th>value</th>
</tr>
<tr>
<th>prop</th>
<th>value</th>
</tr>
</table>
</div>
</div>
</div>

Related

HTML Table Layout, image included with markup for intended outcome

Here is the image of the HTML table design. Please help me out to convert this outline into HTML markup.
NOTE: Unfortunately, this must include a table layout.
Here is my markup:
<!DOCTYPE html>
<html>
<head>
<style>
table, th, td {
border: 1px solid black;
border-collapse: collapse;
text-align: center;
font-weight: 100;
}
</style>
</head>
<body>
<table style=" width: 400px;">
<tr>
<th colspan= "3">1</th>
</tr>
<tr>
<th colspan= "2">2</th>
<th rowspan= "2">3</th>
</tr>
<tr>
<th rowspan= "3">4</th>
<th colspan= "1">5</th>
</tr>
<tr>
<td>6</td>
<td>7</td>
</tr>
<tr>
<td>8</td>
<td>9</td>
</tr>
</table>
</body>
</html>
I want to do this exactly like the image which I've attached above.
display: grid
Using display: grid, you use your parent element to set your width and height, then define your grid-template-column and grid-template-rows in fractions and layout the children elements using the grid-template-areas rule in the parents css.
Then in your child elements, you define their grid-area as their class selectors. This is also dynamic because it fills the parents width and height using the unit of measure you choose.
In my example I use 1fr. So in the case of the columns, we have 5 measurements which each take up one fraction => 1fr, as it is 90vw in width, this means the 5 sections split the 90vw equally, basically 20%, 20%, 20%, 20%, 20% of 90vw gives us the overall width and each child will be 20% width of the parents 90vw. This works using the same principle for rows.
So using this method we can write the CSS to display a grid 5 fractions wide (columns) and 5 fractions high (rows) then set our grid-template-areas in the same pattern they will be displayed on the page.
grid-template-areas:
"one one one one one"
"two two two three three"
"four five five three three"
"four eight nine three three"
"four eight nine six seven";
Setting up the children of the display grid in that pattern, again we must define the childrens selectors grid-area rule using their selector.
.one {
grid-area: one;
}
.cont {
display: grid;
width: 90vw;
height: 90vh;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr 1fr 1fr;
gap: 0px 0px;
grid-template-areas:
"one one one one one"
"two two two three three"
"four five five three three"
"four eight nine three three"
"four eight nine six seven";
}
.one {
grid-area: one;
}
.two {
grid-area: two;
}
.three {
grid-area: three;
}
.four {
grid-area: four;
}
.five {
grid-area: five;
}
.six {
grid-area: six;
}
.seven {
grid-area: seven;
}
.eight {
grid-area: eight;
}
.nine {
grid-area: nine;
}
.divs {
display: flex;
justify-content: center;
align-items: center;
border: 1px solid black;
}
#main {
display: flex;
justify-content: center;
align-items: center;
}
<div id="main">
<div class="cont">
<div class="one divs">1</div>
<div class="two divs">2</div>
<div class="three divs">3</div>
<div class="four divs">4</div>
<div class="five divs">5</div>
<div class="six divs">6</div>
<div class="seven divs">7</div>
<div class="eight divs">8</div>
<div class="nine divs">9</div>
</div>
</div>
Using a Table:
So without setting your height rule for your tr's you will get a weird layout that does not look like you have five rows.
Once you set your height for your rows, it will parse the table correctly provided you have your colspan and rowspan set up properly
table, th, td {
border: 1px solid black;
border-collapse: collapse;
text-align: center;
font-weight: 100;
}
tr {
height: 10vh;
width: 20vw;
}
<table style=" width: 400px;">
<tr>
<th colspan="5">1</th>
</tr>
<tr>
<th colspan="3">2</th>
<th colspan="2" rowspan="3">3</th>
</tr>
<tr>
<th rowspan="3">4</th>
<th colspan="2">5</th>
</tr>
<tr>
<td rowspan="2">8</td>
<td rowspan="2">9</td>
</tr>
<tr>
<td>6</td>
<td>7</td>
</tr>
</table>
this is the code down below... then to remove the extra boarder around it add this border-collapse: collapse; to your table style:
<!DOCTYPE html>
<html>
<head>
<style>
table, th, td {
border: 1px solid black;
text-align: center;
font-weight: 100;
}
</style>
</head>
<body>
<table style=" width: 400px;">
<tr>
<th colspan= "5">1</th>
</tr>
<tr>
<th colspan= "3">2</th>
<th colspan= "2" rowspan= "3">3</th>
</tr>
<tr>
<th rowspan= "3">4</th>
<th colspan= "2">5</th>
</tr>
<tr>
<th rowspan= "2">8</th>
<th rowspan= "2">9</th>
</tr>
<tr>
<th rowspan= "2">6</th>
<th rowspan= "2">7</th>
</tr>
</table>
</body>
</html>

How can I get rid of a border on my responsive chessboard grid layout?

I have the following pattern, and it is quite responsive, no matter how I zoom in or change the width of the page squares stays the same size, the only way these squares change in size is by changing the height of the page. and that's what I want.
I achieved this by making the width and height proportional to the height of the page, using vh units, and adding these squares to a CSS grid.
The problem is the squares in the middle of the image appear to have a border, whereas I don't want a border. This is what I want, instead:
I tried padding the squares to the right or making a white border around them, but both approaches affected the responsiveness of the squares.
How can I blend those squares with the white background without affecting the responsiveness?
Is there a way I can reduce the amount of code required for the '.rect:nth-child' section?
body {
background-color: black;
height: 100vh;
display: grid;
grid-template-columns: 1fr 1fr;
}
.left{
display: grid;
grid-template-columns: 1fr 45vh;
height:100vh;
}
.design{
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(9, 1fr);
}
.rect{
background-color: white;
width: calc(100vh / 9);
height: calc(100vh / 9);
}
.rect:nth-child(1){
grid-column-start: 1;
grid-row-start: 1;
}
.rect:nth-child(2){
grid-column-start: 2;
grid-row-start: 2;
}
.rect:nth-child(3){
grid-column-start: 3;
grid-row-start: 1;
}
.rect:nth-child(4){
grid-column-start: 4;
grid-row-start: 2;
}
.rect:nth-child(5){
grid-column-start: 3;
grid-row-start: 3;
}
.rect:nth-child(6){
grid-column-start: 4;
grid-row-start: 4;
}
.rect:nth-child(7){
grid-column-start: 4;
grid-row-start: 6;
}
.rect:nth-child(8){
grid-column-start: 3;
grid-row-start: 7;
}
.rect:nth-child(9){
grid-column-start: 2;
grid-row-start: 8;
}
.rect:nth-child(10){
grid-column-start: 4;
grid-row-start: 8;
}
.rect:nth-child(11){
grid-column-start: 1;
grid-row-start: 9;
}
.rect:nth-child(12){
grid-column-start: 3;
grid-row-start: 9;
}
<body>
<div class="left">
<div class='design'>
<div class="rect"></div>
<div class="rect"></div>
<div class="rect"></div>
<div class="rect"></div>
<div class="rect"></div>
<div class="rect"></div>
<div class="rect"></div>
<div class="rect"></div>
<div class="rect"></div>
<div class="rect"></div>
<div class="rect"></div>
<div class="rect"></div>
</div>
</div>
<div class="right"></div>
</body>
Problems
"How can I blend those squares with the white background without affecting the responsiveness?"
"Is there a way I can reduce the amount of code required for the '.rect:nth-child' section?"
In order to cleanly resolve all issues, one must consider that the most direct and simplest solutions will most likely yield the best results as well as provide a stable base to which one can expand upon in the future. Using CSS grid for a simple design is over complicated, unnecessary, and will become problematic (it appears it already is -- hence this post).
Having said that, the pattern can be duplicated using:
1 <table>, 1 <tbody>, 9 <tr>, and 36 <td>
or
tags assigned: display: table;, table-row-group;, table-row;, and table-cell;
Reply to the first question: Tables have two ways to eliminate or blend all borders on and within itself:
table { border-collapse: collapse; }
or
table { border-collapse: separate;⃰ border-spacing: 0; }
table, td { border: 0; }
The second option is for more granular control like using border-radius or narrowing cells by negative border-spacing values, etc. Applying border: 0; to any other type of tag does not guarantee a seamless design (table behavior and style has been perfected and honed for 25+ years).
⃰ Default that can be omitted under normal circumstances.
Reply to the second question: Use a table design -- refer to previous information concerning tables.
OP's CSS.....: 16 rulesets / 35 properties
VS
Answer's CSS: 6 rulesets / 15 properties (less code)
Update
"... i I am trying to keep the design within the view port viewport without any scrolling."
Solution to the first requirement: Focus on how the parent tag occupies the viewport. Which would be difficult considering the OP's layout (ie .design). But with a table layout we can define dimensions by content:
table { table-layout: fixed; ... }
td { width: 11vh; height: 11vh; padding: 0 ... }
table-layout: fixed will force the table's width to conform to the width of each column. So here we have the dimensions of 44vh x 99vh which is well within the confines of the viewport. Note that 100vh is not used yet it is apparent in the demo that everything is edge to edge. It's never going to be precise from browser to browser, device to device, etc. -- hence 11vh will suffice rather than a length that actually exceeds the borders of visibility (ie calc(100vh / 9))
Solution to the second requirement: A complete and efficient way to eliminate scrolling is:
body { overflow: hidden; }
Demo
The following demo is 100% responsive vertically. It has no scrollbars and it is perfectly edge to edge. Also the color pattern is how it is posted in OP's screenshot without any unseemly borders. Moreover, it will not lose its structural integrity at extreme dimensions (ex. OP's code will separate and loose group cohesiveness as viewport height decreases).
:root,
body {
width: 100%;
height: 100%;
font: 700 2vh/1 Consolas;
}
body {
overflow: hidden;
}
main {
width: 99vh;
height: 99vh;
background: white;
}
table {
table-layout: fixed;
border-collapse: collapse;
margin: -8px 0 auto 0;
}
td {
width: 11vh;
height: 11vh;
padding: 0;
background: white;
}
.b {
background: black;
}
<main>
<table>
<tbody>
<tr>
<td></td>
<td class='b'></td>
<td></td>
<td class='b'></td>
</tr>
<tr>
<td class='b'></td>
<td></td>
<td class='b'></td>
<td></td>
</tr>
<tr>
<td class='b'></td>
<td class='b'></td>
<td></td>
<td class='b'></td>
</tr>
<tr>
<td class='b'></td>
<td class='b'></td>
<td class='b'></td>
<td></td>
</tr>
<tr>
<td class='b'></td>
<td class='b'></td>
<td class='b'></td>
<td class='b'></td>
</tr>
<tr>
<td class='b'></td>
<td class='b'></td>
<td class='b'></td>
<td></td>
</tr>
<tr>
<td class='b'></td>
<td class='b'></td>
<td></td>
<td class='b'></td>
</tr>
<tr>
<td class='b'></td>
<td></td>
<td class='b'></td>
<td></td>
</tr>
<tr>
<td></td>
<td class='b'></td>
<td></td>
<td class='b'></td>
</tr>
</tbody>
</table>
</main>

Flexbox in table cell appears in the vertical middle

I am using flexbox in a table.
The table has 2 columns, each with one cell.
The left cell is very big, and has a height of maybe 189%.
My CSS is as follows:
#openemail {
display: flex;
flex-flow: column;
height: 100%;
}
#openemail>#header {
flex: 0 1 auto;
}
#openemail>#body {
flex: 1 1 auto;
}
<table id="app">
<tr>
<td>
<div id="emailslist"><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/></div>
</td>
<td>
<div id="openemail">
<div id="header">SSS</div>
<div id="body">more SSS</div>
</div>
</td>
</tr>
</table>
As you can see, the flex container ends up in the middle, and is hard to find. My question is: how can I change my CSS so that the flex container is at the top of my table cell?
Would adding vertical-align: top to the table cell do what you want it to do? Like this:
<table id="app">
<tr>
<td>
<div id="emailslist"><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/></div>
</td>
<td style="vertical-align: top;">
<div id="openemail"><div id="header">SSS</div><div id="body">more SSS</div></div>
</td>
</tr>
</table>
RECOMMENDED:
Applying vertical-align: top to <td> seems to be the optimal solution in 2018, which is fully supported in CSS3 and HTML5. Here's a working sample:
table, th, td {
border: 1px solid black;
}
#openemail {
display: flex;
flex-flow: column;
height: 100%;
}
#openemail>#header {
flex: 0 1 auto;
}
#openemail>#body {
flex: 1 1 auto;
}
<table id="app">
<tr>
<td>
<div id="emailslist">
placeholder<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
</div>
</td>
<td style="vertical-align: top">
<div id="openemail"><div id="header">SSS</div><div id="body">more SSS</div></div>
</td>
</tr>
</table>
To learn more about the vertical-align style: https://www.w3schools.com/cssref/pr_pos_vertical-align.asp
NOT RECOMMENDED:
The following solution could also work if you are using older versions of HTML: setting the valign attribute of <td> to be top. It looks something like this:
table, th, td {
border: 1px solid black;
}
#openemail {
display: flex;
flex-flow: column;
height: 100%;
}
#openemail>#header {
flex: 0 1 auto;
}
#openemail>#body {
flex: 1 1 auto;
}
<table id="app">
<tr>
<td>
<div id="emailslist">
placeholder<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
</div>
</td>
<td valign="top">
<div id="openemail"><div id="header">SSS</div><div id="body">more SSS</div></div>
</td>
</tr>
</table>
To learn more about the valign attribute: https://www.w3schools.com/tags/att_td_valign.asp
Hope this helps!
Since you're dealing with table cells, the vertical-align property comes into play. This property applies to inline-level and table-cell elements only.
The default value of the vertical-align property, according to the spec, is baseline. However, major browsers tend to use the middle value instead.
In any case, the content of your table cell is vertically centered.
You can override this setting with vertical-align: top.
More details: Default value of vertical-align for table cells

How to create multiple columns in a page that continues the previus colum content. - HTML, CSS

First, sorry for any grammatical mistakes, I'm not an expert in English.
So, what I need is to separate my page in three colums that suport one table, when this table reachs to a, for example, height: 1000px in a colum it will go to the other colum.
I tried to do an quick example in Paint:
Everything that I tried just separate the page in three columns but they don't interact with each other as I want. There's any way to do that?
P.S: This table is created from my database, so it's not a fixed table.
I feel at some point when it's a standard, this would be a decent use-case for CSS Grid Layout, or at least it might be more semantic that way. But for now you can definitely apply flexbox styling to a <table>:
table {
/* forces the table to be full width
even without enough content */
display: block;
}
tbody {
border: 1px solid black;
/* display flex will reflow child elements
once they hit a limit in their parent */
display: flex;
/* flex-flow sets the direction to flow child elements,
and if they should wrap when hitting
the end of their parent */
flex-flow: column wrap;
max-height: 80px;
width: 100%;
}
tr {
border: 1px solid #bad;
/* the 33% (the flex basis) is how i'm
getting 3 columns, adjusting this will adjust
your number of columns, it's not the most general solution,
but it'll work for you case */
flex: 0 0 33%;
}
td {
border: 1px solid #ace;
}
<table>
<tbody>
<tr>
<td>row data</td>
</tr>
<tr>
<td>row data</td>
</tr>
<tr>
<td>row data</td>
</tr>
<tr>
<td>row data</td>
</tr>
<tr>
<td>row data</td>
</tr>
</tbody>
</table>
I think it is possible with flexbox. You set a height for the parent element and add flex-direction: column and flex-direction: wrap
<div class="wrapper">
<div class="element">
</div>
<div class="element">
</div>
<div class="element">
</div>
</div>
.wrapper {
height: 100vh;
width: 450px;
display: flex;
flex-direction: column;
flex-wrap: wrap;
}
.wrapper .element {
background: red;
margin: 10px;
height: 45vh;
width: 100px;
}
http://jsfiddle.net/fyj1htwk/

css: table scrollable both horizontally and vertically with fixed header

How can I implement a table that is both horizontally and vertically scrollable with fixed header using css?
I found this Scrolling a div from an outer div, but it is implemented by using Javascript/Jquery. Any way to implement it by using only CSS?
The updated code:
#div-table-content {
width: 100%;
overflow-x: auto;
}
table {
font-size: 12px;
white-space:nowrap;
overflow-x: scroll;
}
tbody {
height: 400px;
overflow-y: auto;
width: 100%;
display: block;
}
thead tr {
display: block;
width: 100%;
}
For a start divide your <table> semantically to headers inside <thead> and content inside <tbody>.
Then, for vertical scrolling, give a fixed height to your <tbody> and set overflow-y: auto and display: block.
For horizontal scrolling, I belive you have to wrap your entire table with a container (lets say <div> and give it a fixed width and overflow-x: auto.
jsFiddle Demo
You can fake table with css-grid (if you don't mind).
.table {
display: grid;
width: 100px;
height: 70px;
overflow: auto;
grid-auto-columns: max-content;
}
.head {
position: sticky;
top: 0;
grid-row: 1;
background-color: #fff;
font-weight: bold;
}
Than you put all cells into single element
<div class="table">
<div class="head">column 1</div>
<div class="head">column 2</div>
<div class="head">column 3</div>
<div>data - column 1 - row 1</div>
<div>data - column 2 - row 1</div>
<div>data - column 3 - row 1</div>
<div>data - column 1 - row 2</div>
<div>data - column 2 - row 2</div>
<div>data - column 3 - row 2</div>
<div>data - column 1 - row 3</div>
<div>data - column 2 - row 3</div>
<div>data - column 3 - row 3</div>
</div>
Now you can see both scrollbars all the time; header scrolls horizontally but not vertically.
Horizontal and vertical scrolling with sticky column headers using css only can be done with the following.
A container div with overflow: scroll
A thead with position: sticky and inset-block-start: 0;
Full example below:
.container {
overflow: scroll;
height: 180px;
width: 300px;
}
table {
border-collapse: collapse;
}
table th,
table td {
max-width: 300px;
padding: 8px 16px;
border: 1px solid #ddd;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
table thead {
position: sticky;
inset-block-start: 0;
background-color: #ddd;
}
<div class="container">
<table>
<thead>
<tr>
<th>Fruits</th>
<th>Nuts</th>
<th>Vegetables</th>
<th>Meats</th>
</tr>
</thead>
<tbody>
<tr>
<td>Apple</td>
<td>Peanut</td>
<td>Carrot</td>
<td>Chicken</td>
</tr>
<tr>
<td>Banana</td>
<td>Pecan</td>
<td>Potato</td>
<td>Pork</td>
</tr>
<tr>
<td>Cherry</td>
<td>Cashew</td>
<td>Tomato</td>
<td>Beef</td>
</tr>
<tr>
<td>Grape</td>
<td>Almond</td>
<td>Cabbage</td>
<td>Lamb</td>
</tr>
<tr>
<td>Kiwi</td>
<td>Brazil Nut</td>
<td>Onion</td>
<td>Chicken</td>
</tr>
<tr>
<td>Lemon</td>
<td>Hazelnut</td>
<td>Cucumber</td>
<td>Fish</td>
</tr>
</tbody>
</table>
</div>