I basically want to see if flexbox can support a 4-column table with
varying width and height, but with consistent row height.
Simply put, one good feature Flexbox share with HTML Table, is that flex item's on the same row can have the same height, which is controlled by the align-items
property. Its default value is stretch
, and will by that make items on a row equal high.
.flex-container {
display: flex;
flex-wrap: wrap; /* allow items to wrap */
justify-content: space-between; /* vertical */
align-items: stretch; /* horizontal, is default
and can be omitted */
}
.flex-item {
flex-basis: 23%; /* give each item a width */
background-color: #ccc;
padding: 10px;
box-sizing: border-box;
}
.flex-item:nth-child(n+5) {
margin-top: 10px; /* from 5th item, add top margin */
}
<div class="flex-container">
<div class="flex-item">Left<br>high</div>
<div class="flex-item">Middle/Left</div>
<div class="flex-item">Middle/Right</div>
<div class="flex-item">Right</div>
<div class="flex-item">Left</div>
<div class="flex-item">Middle/Left</div>
<div class="flex-item">Middle/Right</div>
<div class="flex-item">Right</div>
<div class="flex-item">Left</div>
<div class="flex-item">Middle/Left</div>
<div class="flex-item">Middle/Right<br>higher<br>higher</div>
<div class="flex-item">Right</div>
</div>
One thing that might be worth mentioned, is what Flexbox doesn't share with HTML Table.
- Dynamic equal column width.
If an item's content will be wider than the rest of the items in the same column, the other items won't adjust their width to equal the widest.
.flex-container {
display: flex;
flex-wrap: wrap; /* allow items to wrap */
justify-content: space-between; /* vertical */
align-items: stretch; /* horizontal, is default
and can be omitted */
}
.flex-item {
flex-basis: 23%; /* give each item a width */
background-color: #ccc;
padding: 10px;
box-sizing: border-box;
}
.flex-item:nth-child(n+5) {
margin-top: 10px; /* from 5th item, add top margin */
}
<div class="flex-container">
<div class="flex-item">Left<br>high</div>
<div class="flex-item">Middle/Left - is wider</div>
<div class="flex-item">Middle/Right</div>
<div class="flex-item">Right</div>
<div class="flex-item">Left</div>
<div class="flex-item">Middle/Left</div>
<div class="flex-item">Middle/Right</div>
<div class="flex-item">Right</div>
<div class="flex-item">Left</div>
<div class="flex-item">Middle/Left</div>
<div class="flex-item">Middle/Right<br>higher<br>higher</div>
<div class="flex-item">Right</div>
</div>
By prevent flex item's to shrink, and enable them to be smaller than their content, it is possible to force equal width.
Note, overflow: hidden
(or any value other than visible
) has the same effect as min-width: 0
has, so in below sample min-width
can be omitted.
.flex-container {
display: flex;
flex-wrap: wrap; /* allow items to wrap */
justify-content: space-between; /* vertical */
align-items: stretch; /* horizontal, is default
and can be omitted */
}
.flex-item {
flex-basis: 23%; /* give each item a width */
background-color: #ccc;
padding: 10px;
box-sizing: border-box;
flex-shrink: 0; /* prevent from "shrink to fit" */
min-width: 0; /* allow to shrink past content width */
overflow: hidden; /* hide overflowed content */
}
.flex-item:nth-child(n+5) {
margin-top: 10px; /* from 5th item, add top margin */
}
<div class="flex-container">
<div class="flex-item">Left<br>high</div>
<div class="flex-item">Middle/Left - is wider</div>
<div class="flex-item">Middle/Right</div>
<div class="flex-item">Right</div>
<div class="flex-item">Left</div>
<div class="flex-item">Middle/Left</div>
<div class="flex-item">Middle/Right</div>
<div class="flex-item">Right</div>
<div class="flex-item">Left</div>
<div class="flex-item">Middle/Left</div>
<div class="flex-item">Middle/Right<br>higher<br>higher</div>
<div class="flex-item">Right</div>
</div>
A more appropriate comparison would be with CSS Grid, which can do pretty much everything HTML Table can, and then some :)
Here is two great guides to Flexbox and CSS Grid: