Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flexbox order of tiles with variable widths

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>
like image 697
Tom Avatar asked Dec 16 '25 13:12

Tom


1 Answers

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-flow property

Grid items that aren’t explicitly placed are automatically placed into an unoccupied space in the grid container by the auto-placement algorithm.

grid-auto-flow controls how the auto-placement algorithm works, specifying exactly how auto-placed items get flowed into the grid.

dense

If 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.

  • On the grid items themselves, the span value in the grid-column-end property is telling each item how many columns to cover.

Browser Support for CSS Grid

  • Chrome - full support as of March 8, 2017 (version 57)
  • Firefox - full support as of March 6, 2017 (version 52)
  • Safari - full support as of March 26, 2017 (version 10.1)
  • Edge - full support as of October 16, 2017 (version 16)
  • IE11 - no support for current spec; supports obsolete version

Here's the complete picture: http://caniuse.com/#search=grid

like image 140
Michael Benjamin Avatar answered Dec 19 '25 06:12

Michael Benjamin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!