Reputation: 8982
I created a responsive grid which should contain rows of 4, 3, 2 or 1 items, depending on the window size. Hard requirement from Design is that no widows and no half filled rows are allowed. So for 11 items, there could be two rows of four items and one of three, or three rows of three items and one of two items, or... . You get the idea.
To solve the problem, I created a css grid:
display: grid;
grid-template-columns: repeat(auto-fit, minmax(264px, 1fr));
grid-gap: 24px;
This works fine for the resizing, but it does not take care of the widow problem. At first I did the naive approach of selecting the last item with a last-of-type
selector and giving it a grid-row: 1 / -1
style, but that does not ensure that the row above is fully filled.
I guess there won't be a css only solution. Is there a way for an element to realize that it is alone in a row, or that it has to grow to fill the row? I had an idea using the nextSibling
property to select the last child via JavaScript and maybe determine via the page offset if it fills the whole row. But my problem is that I can't hardcode the width of the screen.
Alternatively, is there a way to tell an element to spread until the end of the row? I tried this, but it did not work:
.card:last-of-type {
grid-column-end: span -1;
}
Click here for minimal reproducible example.
Upvotes: 1
Views: 500
Reputation: 6505
A solution is to use flexbox instead of grid. This way it can stretch with the screen size.
We use 25%
for a 4 column layout. Subtracting 1rem
for a bit of margin. (0.5 left + 0.5 right)
(Open snippet in fullscreen to see it working)
.my-grid {
display: flex;
flex-wrap: wrap;
}
.card {
min-width: 264px;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 1px 1px #00000026;
font-size: 14px;
background-color: red;
margin: .5rem;
flex: 1 1 calc(25% - 1rem);
}
<div class="my-grid">
<div class="card">1</div>
<div class="card">1</div>
<div class="card">1</div>
<div class="card">1</div>
<div class="card">1</div>
<div class="card">1</div>
<div class="card">1</div>
<div class="card">1</div>
<div class="card">1</div>
<div class="card">blub</div>
</div>
Upvotes: 1