The following simple snippet results in a single web page that takes up the available screen space with a header at the top, a footer at the bottom, and the main content tak
The html table
element retains its display
property in a flex container:
display: table
Therefore, it doesn't accept flex properties.
However, simply override that rule with display: block
display: flex
and the layout should work.
html,
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
body {
display: flex;
flex-flow: column;
}
h1,
small {
flex: 0 1 auto;
}
table {
display: flex;
flex: 1 1 auto;
}
tbody {
display: flex;
width: 100%;
}
tr {
display: flex;
width: 100%;
}
td {
flex: 1;
border: 1px solid red;
}
<h1>Some Header</h1>
<table>
<tr>
<td>Some Content</td>
<td>Some Content</td>
<td>Some Content</td>
<td>Some Content</td>
<td>Some Content</td>
</tr>
</table>
<small>Some Footer</small>
I think the problem is that the table box is placed inside a table wrapper box:
the table generates a principal block box called the table wrapper box that contains the table box itself and any caption boxes
So the table box is no longer a child of the flex container, and thus is not a flex item. The flex item is the table wrapper box, but you set the flex
property to the table
element, and
values of non-inheritable properties are used on the table box and not the table wrapper box
So your flex
is used on a box which is not a flex item and thus is ignored.
It might have worked if that property was used on the table wrapper box, but it's not possible to select it. Even if you could, it wouldn't be clear whether it should be sized according to the tabular layout it generates instead of by the the Flexbox layout in which it participates.
The solution is simple:
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
body {
display: flex;
flex-flow: column;
}
h1, small {
flex: 0 1 auto;
}
div {
position: relative;
flex: 1 1 0; /* Chrome needs non-auto flex-basis */
overflow: auto;
}
table {
position: absolute;
height: 100%;
width: 100%;
left: 0;
top: 0;
table-layout: fixed;
border-collapse: collapse;
}
td {
border: 1px dotted;
text-align: center;
}
<h1>Some Header</h1>
<div>
<table><tr>
<td>This</td>
<td>is</td>
<td>equidistributed.</td>
</tr><tr>
<td>This</td>
<td>is also</td>
<td>equidistributed.</td>
</tr></table>
</div>
<small>Some Footer</small>
Just for fun, a hacky way to avoid adding the wrapper would be styling the table as a block and the automatically inserted tbody as the table.
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
body {
display: flex;
flex-flow: column;
}
h1, small {
flex: 0 1 auto;
}
table {
display: block;
position: relative;
flex: 1 1 0;
}
tbody {
display: table;
position: absolute;
height: 100%;
width: 100%;
left: 0;
top: 0;
table-layout: fixed;
border-collapse: collapse;
box-sizing: border-box;
}
td {
border: 1px dotted;
text-align: center;
}
<h1>Some Header</h1>
<table><tr>
<td>This</td>
<td>is</td>
<td>equidistributed.</td>
</tr><tr>
<td>This</td>
<td>is also</td>
<td>equidistributed.</td>
</tr></table>
<small>Some Footer</small>
Well one thing, you should use vw and vh units for height and width, they are not supported throughout most browsers, but they are really good at what they can do. Also, with the table issue, you never designated it a width, so you'll only get a cell that fits the text.
Adding something like "width: 75vw;" to the table style would help (you can use %s for width)