I have a grid of tiles I need to display.
Article tiles can fit 4 in a row.
Videos can fit 2 in a row.
The problem I'm running into is this: a row with article, article, article, video. The video is bumped to the next line.
Or article, video, video. Again the second video gets bumped to the next line.
Setting the order property seems to be a pain because the order that articles / videos are shown is totally random. Is there a a good way to handle this problem with flexbox?
Here's the fiddle - https://jsfiddle.net/nx4ap9u4/ (in this case I'm trying to have 2 blue blocks and green block in the first row, 4 blue blocks in the second row without me having to set the order with CSS or JS)
.blog-feeder {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-start;
}
.article-preview.grid {
flex-grow: 1;
flex-basis: 25%;
width: auto;
margin-right: 15px;
background: blue;
height: 300px;
}
.article-preview.grid.post_VIDEO {
flex-basis: 50%;
background: green;
}
<div class="blog-feeder">
<div class="article-preview grid"></div>
<div class="article-preview grid"></div>
<div class="article-preview grid"></div>
<div class="article-preview grid post_VIDEO"></div>
<div class="article-preview grid"></div>
<div class="article-preview grid"></div>
<div class="article-preview grid"></div>
</div>
This sort of layout algorithm is beyond the capacity of flexbox. Items in a flex container cannot be re-ordered automatically to fill a row.
However, this feature is available in another CSS3 technology, Grid Layout.
The "dense" packing algorithm of the grid-auto-flow property enables grid items to be automatically re-ordered to fill empty space in a row.
From the spec:
7.7. Automatic Placement: the
grid-auto-flowpropertyGrid items that aren’t explicitly placed are automatically placed into an unoccupied space in the grid container by the auto-placement algorithm.
grid-auto-flowcontrols how the auto-placement algorithm works, specifying exactly how auto-placed items get flowed into the grid.
denseIf specified, the auto-placement algorithm uses a “dense” packing algorithm, which attempts to fill in holes earlier in the grid if smaller items come up later. This may cause items to appear out-of-order, when doing so would fill in holes left by larger items.
.blog-feeder {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 100px;
grid-auto-flow: dense;
grid-gap: 10px;
padding: 10px;
}
.article-preview.grid {
grid-column-end: span 1;
background: blue;
}
.article-preview.grid.post_VIDEO {
grid-column-end: span 2;
background: green;
}
<div class="blog-feeder">
<div class="article-preview grid"></div>
<div class="article-preview grid"></div>
<div class="article-preview grid post_VIDEO"></div>
<div class="article-preview grid"></div>
<div class="article-preview grid"></div>
<div class="article-preview grid"></div>
<div class="article-preview grid post_VIDEO"></div>
<div class="article-preview grid"></div>
<div class="article-preview grid"></div>
<div class="article-preview grid"></div>
<div class="article-preview grid"></div>
<div class="article-preview grid post_VIDEO"></div>
<div class="article-preview grid"></div>
</div>
revised demo
Here's how it works:
The .blog-feeder element becomes a grid container with display: grid.
The grid-template-columns property sets the grid to four columns, each having a width of 1fr, which is an equal distribution of available space. (It's similar to flex-grow: 1 in flexbox.)
There are no explicit rows specified. But any rows created automatically by the grid (aka, implicit rows) will have a height of 100px. (Formerly 300px height on flex items in original code. Switched only for demo purposes.)
The grid-auto-flow property sets the layout algorithm. dense will take items out of source order if necessary to fill gaps.
The grid-gap property sets the space between items (the gutters). This property works only between items; it has no effect on the space between items and the container.
So far, all commands are set at the container level. This is different than flexbox, where many similar commands must be set on flex items.
span value in the grid-column-end property is telling each item how many columns to cover.Browser Support for CSS Grid
Here's the complete picture: http://caniuse.com/#search=grid
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With