This is, in effect, the Pinterest layout. However, the solutions found online are wrapped in columns, which means the container inadvertently grows horizontally. That is not the Pinterest layout, and it does not work well with dynamically-loaded content.
What I want to do is have a bunch of images of fixed width and asymmetrical height, laid out horizontally but wrapping in a new row when the limits of the fixed-width container are met:
Can flexbox do this, or do I have to resort to a JS solution like Masonry?
Instead of
flexbox
, I recommend to use columns for grids like this. As you can see, the spacing on the bottom images can be better, but for a native CSS solution I think it's pretty neat. No more JS:the
column
approach seems a good compromise if you setcolumn-width
viavmin
orvmax
units and dropcolumn-count
(first snippet) ,display:grid
andvmin
is also an option for the futur (second snippet).test demo with vmin
a link among others https://web-design-weekly.com/2014/11/18/viewport-units-vw-vh-vmin-vmax/
display:grid
coud make it also easy with auto-fill but will require to set a span value to tallest image so rows and columns can inbricateyou can see https://css-tricks.com/snippets/css/complete-guide-grid/
You can achieve the masonry effect as per your screenshot, but you've set the height of the outer div dynamically
What you want can be achieved in
32 ways, CSS wise:1.
flexbox:2. CSS columns
(this solution has the very neat advantage of built-in
column-span
- pretty handy for titles). The disadvantage is ordering items in columns (first column contains first third of the items and so on...). I made a jsFiddle for this.3. Masonry plugin
absolute positioning after calculating rendered item sizes, via JavaScript (masonry plugin).
Flexbox is a "1-dimensional" layout system: It can align items along horizontal OR vertical lines.
A true grid system is "2-dimensional": It can align items along horizontal AND vertical lines. In other words, cells can span across columns and rows, which flexbox cannot do.
This is why flexbox has a limited capacity for building grids. It's also a reason why the W3C has developed another CSS3 technology, Grid Layout (see below).
In a flex container with
flex-flow: row wrap
, flex items must wrap to new rows.This means that a flex item cannot wrap under another item in the same row.
Notice above how div #3 wraps below div #1, creating a new row. It cannot wrap beneath div #2.
As a result, when items aren't the tallest in the row, white space remains, creating unsightly gaps.
image credit: Jefree Sujit
column wrap
SolutionIf you switch to
flex-flow: column wrap
, flex items will stack vertically and a grid-like layout is more attainable. However, a column-direction container has three potential problems right off the bat:As a result, a column-direction container may not be feasible in many cases.
Other Solutions
Add containers
In the first two images above, consider wrapping items 2 and 3 in a separate container. This new container can be a sibling to item 1. Done.
Here's a detailed example: Calculator keypad layout with flexbox
One downside worth highlighting: If you're wanting to use the
order
property to re-arrange your layout (such as in media queries), this method may eliminate that option.Desandro Masonry
How to Build a Site that Works Like Pinterest
CSS Grid Layout Module Level 1
Grid Layout example: CSS-only masonry layout but with elements ordered horizontally