My challenge involves formatting a grid with two columns and multiple rows. Typically, one column has more content than the other. I want to achieve a layout similar to an old-fashioned table where free space is distributed proportionally based on the content in each cell, but using CSS Grid instead of a traditional table. The goal is to have the cells stack vertically on smaller screens.
While grid-template-columns: auto auto
gets close to the desired effect, it evenly splits any remaining space, whereas I need it split at a 2:1
ratio or another specified ratio. Unfortunately, values like 2fr 1fr
don't provide the exact result needed, and there isn't an equivalent of 2auto 1auto
.
I've explored various combinations of CSS Grid properties to replicate the spacing of a classic table without success. Utilizing a table and overriding its display property at specific screen sizes seems clunky. Is there a way to achieve this using only CSS Grid?
table {
border: 1px solid red;
}
td {
border: 1px solid red;
}
.grid {
display: grid;
gap: 5px;
border: 1px solid blue;
padding: 5px;
margin-bottom: 5px;
}
.grid>* {
border: 1px solid blue;
padding: 5px;
grid-template-columns: 100%;
}
.grid0 {
grid-template-columns: fit-content(100%) fit-content(100%);
}
.grid1 {
grid-template-columns: auto auto;
}
.grid2 {
grid-template-columns: 2fr 1fr;
}
.grid3 {
grid-template-columns: minmax(auto, 2fr) minmax(auto, 1fr);
}
@media (max-width: 400px) {
table.hacky,
table.hacky tr,
table.hacky tr td {
display: block;
}
}
<p>
Implementing my base grid structure without taking up additional space:
</p>
<div class="grid grid0">
<div>
This cell contains significantly more content compared to the other
</div>
<div>
Less content here
</div>
</div>
<p>
To illustrate, here's a representation using a classic table. Note how the first column receives more free space naturally due to higher content.
</p>
<table cellspacing="5" cellpadding="5" width="100%">
<tr>
<td>
This cell contains significantly more content
</td>
<td>
Less content here
</td>
</tr>
</table>
<p>
First Attempt: Trying "grid-template-columns: auto auto;".
</p>
<div class="grid grid1">
<div>
This cell contains significantly more content
</div>
<div>
Less content here
</div>
</div>
<p>
Second Attempt: Experimenting with "grid-template-columns: 2fr 1fr;".
</p>
<div class="grid grid3">
<div>
This cell contains significantly more content
</div>
<div>
Less content here
</div>
</div>
<p>
Third Attempt: Testing "grid-template-columns: minmax(auto, 2fr) minmax(auto, 1fr);".
</p>
<div class="grid grid3">
<div>
This cell contains significantly more content
</div>
<div>
Less content here
</div>
</div>
<p>
Fourth Attempt: Using a classic table and changing the "display" style below a certain breakpoint.
</p>
<table class="hacky" cellspacing="5" cellpadding="5" width="100%">
<tr>
<td>
This cell contains significantly more content
</td>
<td>
Less content here
</td>
</tr>
</table>