New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[css-grid][css-flexbox] Pinterest/Masonry style layout support #945

Open
rachelandrew opened this Issue Jan 16, 2017 · 49 comments

Comments

Projects
None yet
@rachelandrew
Contributor

rachelandrew commented Jan 16, 2017

I'm getting frequent questions about whether Grid can handle a Masonry style layout using auto-placement.

You can see a good example, along with some author use cases here.

Currently the closest you can get with CSS to this type of layout is to use multi-col however the items then flow top to bottom rather than across the rows.

This feels more like a behaviour of flexbox than grid, as the solution is very much based on the size of the items. Opening this in order to record the feature request/use case for future discussion.

@jensimmons

This comment has been minimized.

Show comment
Hide comment
@jensimmons

jensimmons Jan 17, 2017

Yeah, I was asked this question twice this week. As people start to expand their imagination for what's possible in layout with CSS, they are reaching for the things they've seen... Pinterest and other sites use this layout. It is a Flexbox-like layout, but with different content order than what's possible using multicolumn.

jensimmons commented Jan 17, 2017

Yeah, I was asked this question twice this week. As people start to expand their imagination for what's possible in layout with CSS, they are reaching for the things they've seen... Pinterest and other sites use this layout. It is a Flexbox-like layout, but with different content order than what's possible using multicolumn.

@Zatnosk

This comment has been minimized.

Show comment
Hide comment
@Zatnosk

Zatnosk Jan 18, 2017

I'm new to this process, so please point me in the right direction if I've misunderstood anything or should be proposing solutions somewhere else, or at a later point in time.

In order to fit the Masonry style layout in Flexbox, flex-direction could be extendeed with two additional values: row-cross and column-cross. (or something like that - naming isn't important to me)
column-cross would have the block direction as main axis, like column, but laying out flex items one by one along the cross axis, as if wrapping on to multiple lines.
row-cross would be similar, but have inline direction as main axis.
By adding a flex-wrap value of wrap or wrap-reverse, the flex items would be wrapped and dispersed between lines in the direction of the chosen cross axis.

This approach would still have the problem of flex-items not being "intuitively placed" i.e. a flex item might be before another in order, but be farther from the main start than that other item - somewhat breaking the (assumed) Masonry expectation that earlier items appear first when scrolling.

Zatnosk commented Jan 18, 2017

I'm new to this process, so please point me in the right direction if I've misunderstood anything or should be proposing solutions somewhere else, or at a later point in time.

In order to fit the Masonry style layout in Flexbox, flex-direction could be extendeed with two additional values: row-cross and column-cross. (or something like that - naming isn't important to me)
column-cross would have the block direction as main axis, like column, but laying out flex items one by one along the cross axis, as if wrapping on to multiple lines.
row-cross would be similar, but have inline direction as main axis.
By adding a flex-wrap value of wrap or wrap-reverse, the flex items would be wrapped and dispersed between lines in the direction of the chosen cross axis.

This approach would still have the problem of flex-items not being "intuitively placed" i.e. a flex item might be before another in order, but be farther from the main start than that other item - somewhat breaking the (assumed) Masonry expectation that earlier items appear first when scrolling.

@tabatkins

This comment has been minimized.

Show comment
Hide comment
@tabatkins

tabatkins Jan 23, 2017

Member

You can have Grid do Masonry if you know the heights of the items ahead of time. It's a bit hacky, but you set the grid container to grid: auto-flow dense 1px / <column widths here>;, then set each item to grid-row: span <pixel height as integer>; (for example, if the item is 50px tall, use grid-row: span 50;).

The dense placement will put each item into whichever column is the least filled (has the highest open row).

There's not currently any way to make this work with auto heights. We might do this in the future.

Member

tabatkins commented Jan 23, 2017

You can have Grid do Masonry if you know the heights of the items ahead of time. It's a bit hacky, but you set the grid container to grid: auto-flow dense 1px / <column widths here>;, then set each item to grid-row: span <pixel height as integer>; (for example, if the item is 50px tall, use grid-row: span 50;).

The dense placement will put each item into whichever column is the least filled (has the highest open row).

There's not currently any way to make this work with auto heights. We might do this in the future.

@MatsPalmgren

This comment has been minimized.

Show comment
Hide comment
@MatsPalmgren

MatsPalmgren Feb 6, 2017

This kind of layout isn't very well suited for Grid, so I don't think we should try to squeeze it in there. It seems multicol layout is a better fit for the example in rachelandrew/cssgrid-ama#19 (comment)
We could add a column-auto-flow property, similar to: https://drafts.csswg.org/css-grid/#grid-auto-flow-property, where 'column' would do it exactly as that example, and 'column dense' would place the next box in the column with the smallest height, i.e. "4" would go under "3" in that example.

MatsPalmgren commented Feb 6, 2017

This kind of layout isn't very well suited for Grid, so I don't think we should try to squeeze it in there. It seems multicol layout is a better fit for the example in rachelandrew/cssgrid-ama#19 (comment)
We could add a column-auto-flow property, similar to: https://drafts.csswg.org/css-grid/#grid-auto-flow-property, where 'column' would do it exactly as that example, and 'column dense' would place the next box in the column with the smallest height, i.e. "4" would go under "3" in that example.

@hunboy

This comment has been minimized.

Show comment
Hide comment
@hunboy

hunboy Feb 6, 2017

MatsPalmgren, the column layout is not good, because reordering the content, when you add more items, and basically vertically flowing across the columns, in a typographically correct way.

tabatkins, currently this grid feature is promised:
https://bug1336679.bmoattachments.org/attachment.cgi?id=8833796

This testcase is a lazy load picture gallery, when you scroll down, it loads more items as flowed.

Only 1 issue causes discussion: the maximum number of rows is too limited in firefox and crhomium.
probably would be better way to limit the row-spanning itself instead of the whole grid if it causes some stacking problems.

hunboy commented Feb 6, 2017

MatsPalmgren, the column layout is not good, because reordering the content, when you add more items, and basically vertically flowing across the columns, in a typographically correct way.

tabatkins, currently this grid feature is promised:
https://bug1336679.bmoattachments.org/attachment.cgi?id=8833796

This testcase is a lazy load picture gallery, when you scroll down, it loads more items as flowed.

Only 1 issue causes discussion: the maximum number of rows is too limited in firefox and crhomium.
probably would be better way to limit the row-spanning itself instead of the whole grid if it causes some stacking problems.

@hunboy

This comment has been minimized.

Show comment
Hide comment
@hunboy

hunboy Feb 7, 2017

for a final solution the float: top left; can ce 1 possible way to make cheap and responsive masonry, but this one doesn't exist currently.

hunboy commented Feb 7, 2017

for a final solution the float: top left; can ce 1 possible way to make cheap and responsive masonry, but this one doesn't exist currently.

@jamesdoc

This comment has been minimized.

Show comment
Hide comment
@jamesdoc

jamesdoc Feb 22, 2017

At the V&A we're currently using columns as a "solution". This is fine, until we need to add more items into the DOM. Because columns items are displayed in the order of the HTML elements, when you add more at the bottom the resulting transition is a very unexpected user experience.

Example: https://www.vam.ac.uk/collections/renaissance

Clicking the 'show more' button reveals more items, but how the items appear to be ordered is very odd.

screen shot 2017-02-22 at 10 57 43

screen shot 2017-02-22 at 10 58 05

jamesdoc commented Feb 22, 2017

At the V&A we're currently using columns as a "solution". This is fine, until we need to add more items into the DOM. Because columns items are displayed in the order of the HTML elements, when you add more at the bottom the resulting transition is a very unexpected user experience.

Example: https://www.vam.ac.uk/collections/renaissance

Clicking the 'show more' button reveals more items, but how the items appear to be ordered is very odd.

screen shot 2017-02-22 at 10 57 43

screen shot 2017-02-22 at 10 58 05

@yisibl

This comment has been minimized.

Show comment
Hide comment
@yisibl

yisibl Mar 30, 2017

image

https://500px.com/

This is a very common layout, in any case, I hope to have the relevant norms as soon as possible.

yisibl commented Mar 30, 2017

image

https://500px.com/

This is a very common layout, in any case, I hope to have the relevant norms as soon as possible.

@hunboy

This comment has been minimized.

Show comment
Hide comment
@hunboy

hunboy Mar 30, 2017

@yisibl it is pretty easy with flex only currently: https://jsfiddle.net/utasir/t0a1dnq1/

hunboy commented Mar 30, 2017

@yisibl it is pretty easy with flex only currently: https://jsfiddle.net/utasir/t0a1dnq1/

@yisibl

This comment has been minimized.

Show comment
Hide comment
@yisibl

yisibl Apr 21, 2017

@hunboy That's not the same.In particular, the last element is stretched.

yisibl commented Apr 21, 2017

@hunboy That's not the same.In particular, the last element is stretched.

@jcklpe

This comment has been minimized.

Show comment
Hide comment
@jcklpe

jcklpe Jun 8, 2017

Just wanted to put in my support for the implementation of masonry style layout through css grid. Column does not work when adding more content.

jcklpe commented Jun 8, 2017

Just wanted to put in my support for the implementation of masonry style layout through css grid. Column does not work when adding more content.

@nategreen

This comment has been minimized.

Show comment
Hide comment
@nategreen

nategreen Jun 26, 2017

Would it work to have a keyword for grid-template-columns or -rows which would effectively tell that axis to be flow/flex instead of lining things up?

So, for example, in @jamesdoc 's example above I would have something like:

.figure-list {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: flow;
}

Does that make sense?

I'm not sure how I'd expect this to behave if you used that keyword for both axes, though...something like this, perhaps, simply packing boxes into the next available space horizontally/vertically based on grid-auto-flow:

image

I'm sure I'm missing some reason why this wouldn't work, but wanted to suggest it in case it helps move the conversation along. :) Thanks!

nategreen commented Jun 26, 2017

Would it work to have a keyword for grid-template-columns or -rows which would effectively tell that axis to be flow/flex instead of lining things up?

So, for example, in @jamesdoc 's example above I would have something like:

.figure-list {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: flow;
}

Does that make sense?

I'm not sure how I'd expect this to behave if you used that keyword for both axes, though...something like this, perhaps, simply packing boxes into the next available space horizontally/vertically based on grid-auto-flow:

image

I'm sure I'm missing some reason why this wouldn't work, but wanted to suggest it in case it helps move the conversation along. :) Thanks!

@tabatkins

This comment has been minimized.

Show comment
Hide comment
@tabatkins

tabatkins Jun 27, 2017

Member

There's no "simple" way to adapt Grid into Masonry - anything would involve non-trivial edits to the layout algorithm. Packery, in particular, really needs things to have a defined width. ^_^

Member

tabatkins commented Jun 27, 2017

There's no "simple" way to adapt Grid into Masonry - anything would involve non-trivial edits to the layout algorithm. Packery, in particular, really needs things to have a defined width. ^_^

@MrGrigri

This comment has been minimized.

Show comment
Hide comment
@MrGrigri

MrGrigri Aug 1, 2017

Why not just add a new display property value of masonry or comic (like a comic book), e.g. display: masonry;. That way we could enforce the lang property correctly. I don't see this as being implemented correctly if we try to hack either flexbox or grid to work with this layout.

MrGrigri commented Aug 1, 2017

Why not just add a new display property value of masonry or comic (like a comic book), e.g. display: masonry;. That way we could enforce the lang property correctly. I don't see this as being implemented correctly if we try to hack either flexbox or grid to work with this layout.

@tabatkins

This comment has been minimized.

Show comment
Hide comment
@tabatkins

tabatkins Aug 3, 2017

Member

There's no such thing as "just add[ing] a new display property value". ^_^ Layout specs are the most complicated specs in all of CSS; even one that can borrow heavily from an existing spec, like Masonry could from Grid, will still have significant amounts of divergence and complication.

Member

tabatkins commented Aug 3, 2017

There's no such thing as "just add[ing] a new display property value". ^_^ Layout specs are the most complicated specs in all of CSS; even one that can borrow heavily from an existing spec, like Masonry could from Grid, will still have significant amounts of divergence and complication.

@MrGrigri

This comment has been minimized.

Show comment
Hide comment
@MrGrigri

MrGrigri Aug 3, 2017

@tabatkins, I understand that adding a new display property is not that easy. I just see all other options as a hack. If you knew the height of each element of the 'masonry' layout, then you could easily implement a grid system. However, most of the time, the height is unknown.

I am still suggesting that a new display property be created. Idk how to get that ball rolling so I did some Google searching and watched a talk from @rachelandrew, and decided to come here. In my opinion, neither Grid or Flexbox is the right option. They both sound like a hack.

MrGrigri commented Aug 3, 2017

@tabatkins, I understand that adding a new display property is not that easy. I just see all other options as a hack. If you knew the height of each element of the 'masonry' layout, then you could easily implement a grid system. However, most of the time, the height is unknown.

I am still suggesting that a new display property be created. Idk how to get that ball rolling so I did some Google searching and watched a talk from @rachelandrew, and decided to come here. In my opinion, neither Grid or Flexbox is the right option. They both sound like a hack.

@rachelandrew

This comment has been minimized.

Show comment
Hide comment
@rachelandrew

rachelandrew Aug 3, 2017

Contributor

@MrGrigri The thing is we can't create a brand new value of display for every distinct design pattern. I hope that this is an issue we can solve in Level 2 of grid, or at least explore doing so.

Contributor

rachelandrew commented Aug 3, 2017

@MrGrigri The thing is we can't create a brand new value of display for every distinct design pattern. I hope that this is an issue we can solve in Level 2 of grid, or at least explore doing so.

@Loirooriol

This comment has been minimized.

Show comment
Hide comment
@Loirooriol

Loirooriol Aug 9, 2017

Collaborator

Not sure if I'm missing something, but it seems the Flexbox spec already allows this kind of layout, and it works perfectly on Firefox. Does not work on other browser yet because they don't support forced line breaks in flexbox.

The steps are simple:

  1. Place the elements in a multiline column flex container.
  2. Reorder the elements, so that the DOM order is respected horizontally instead of vertically.
  3. Force a column break before the first item of each column.

See the details in https://stackoverflow.com/a/35097136/1529630

Collaborator

Loirooriol commented Aug 9, 2017

Not sure if I'm missing something, but it seems the Flexbox spec already allows this kind of layout, and it works perfectly on Firefox. Does not work on other browser yet because they don't support forced line breaks in flexbox.

The steps are simple:

  1. Place the elements in a multiline column flex container.
  2. Reorder the elements, so that the DOM order is respected horizontally instead of vertically.
  3. Force a column break before the first item of each column.

See the details in https://stackoverflow.com/a/35097136/1529630

@tabatkins

This comment has been minimized.

Show comment
Hide comment
@tabatkins

tabatkins Aug 9, 2017

Member

You have to manually calculate where the items will go, and manually pre-balanced the columns, for that to work.

Member

tabatkins commented Aug 9, 2017

You have to manually calculate where the items will go, and manually pre-balanced the columns, for that to work.

@MrGrigri

This comment has been minimized.

Show comment
Hide comment
@MrGrigri

MrGrigri Aug 9, 2017

@Loirooriol That is not the same thing...albeit close. Masonry, in a left-to-right language like English, is ordered from left-to-right and top-to-bottom in a comic book style frame. See the below image for details. Green is correct, and red is incorrect.

asset 6 asset 5

MrGrigri commented Aug 9, 2017

@Loirooriol That is not the same thing...albeit close. Masonry, in a left-to-right language like English, is ordered from left-to-right and top-to-bottom in a comic book style frame. See the below image for details. Green is correct, and red is incorrect.

asset 6 asset 5

@simonlayfield

This comment has been minimized.

Show comment
Hide comment
@simonlayfield

simonlayfield Aug 13, 2017

The above image from @MrGrigri illustrates the problem well, but for clarity's sake I've adjusted it to clearly demonstrate the problem we faced when attempting a masonry layout with columns containing variable height children. Rather than appending grid items strictly from left to right, the grid needs to append children to the column with the lowest height - thus conserving vertical space as well as (roughly) achieving uniform column heights. Particularly with lazy loading content you can very quickly start to see a strict left-to-right solution fail.

masonry-example
masonry-example-wrong

simonlayfield commented Aug 13, 2017

The above image from @MrGrigri illustrates the problem well, but for clarity's sake I've adjusted it to clearly demonstrate the problem we faced when attempting a masonry layout with columns containing variable height children. Rather than appending grid items strictly from left to right, the grid needs to append children to the column with the lowest height - thus conserving vertical space as well as (roughly) achieving uniform column heights. Particularly with lazy loading content you can very quickly start to see a strict left-to-right solution fail.

masonry-example
masonry-example-wrong

@Loirooriol

This comment has been minimized.

Show comment
Hide comment
@Loirooriol

Loirooriol Aug 13, 2017

Collaborator

It's true that appending to the shortest column is a greedy approach to minimize the height of the container. But it also has downsides, e.g. you animate the height of an item a little bit, and bam!, the order of the following items completely changes. It's not a stable layout. Recalculating it all seems more expensive for browsers, and as an user I get confused by these spooky actions at a distance.

Collaborator

Loirooriol commented Aug 13, 2017

It's true that appending to the shortest column is a greedy approach to minimize the height of the container. But it also has downsides, e.g. you animate the height of an item a little bit, and bam!, the order of the following items completely changes. It's not a stable layout. Recalculating it all seems more expensive for browsers, and as an user I get confused by these spooky actions at a distance.

@mor10

This comment has been minimized.

Show comment
Hide comment
@mor10

mor10 Aug 15, 2017

From my perspective Masonry layouts run counter to the core premise of grid layouts as layout-in. For a Masonry layout to be created, the grid must be laid out to fit the grid items which is the opposite of how grid layouts work (define a grid, then place contents within that grid).

Working with various Masonry solutions including original Masonry, Isotope, and Packery I constantly encounter the challenge of having to either wait for all the items (in particular images etc) to be loaded into the browser before painting the Masonry layout, or forcing a Masonry layout at the onset and then repainting it once the items are fully loaded to correctly size each item and avoid overlaps. Either way is clunky and creates a sub-optimal user experience, especially on image heavy sites and slow connections. On top of this comes RWD which makes things all the more challenging, especially if the columns are fluid.

To me, while Masonry may look like a grid layout, it's actually an item-out layout modality with unified horizontal sizing + margin/padding/gutter properties applied. As @MrGrigri and @simonlayfield demonstrate in their visual examples, the items in Masonry are laid out using something akin to a scanline approach where the browser paints horizontally from left to right, top to bottom, and places items at the first available space.

A pure CSS method for building the example above could be to define pseudo-columns for the parent container stating "descendants will be displayed three across" and then telling the browser that each descendant item is a Masonry item with pre-defined horizontal and vertical gutters. The browser then places each item within the first open vertical area of the first available pseudo-column from the top down.

I have no idea what that would look like markup wise, but I don't think it would fall under the grid spec.

mor10 commented Aug 15, 2017

From my perspective Masonry layouts run counter to the core premise of grid layouts as layout-in. For a Masonry layout to be created, the grid must be laid out to fit the grid items which is the opposite of how grid layouts work (define a grid, then place contents within that grid).

Working with various Masonry solutions including original Masonry, Isotope, and Packery I constantly encounter the challenge of having to either wait for all the items (in particular images etc) to be loaded into the browser before painting the Masonry layout, or forcing a Masonry layout at the onset and then repainting it once the items are fully loaded to correctly size each item and avoid overlaps. Either way is clunky and creates a sub-optimal user experience, especially on image heavy sites and slow connections. On top of this comes RWD which makes things all the more challenging, especially if the columns are fluid.

To me, while Masonry may look like a grid layout, it's actually an item-out layout modality with unified horizontal sizing + margin/padding/gutter properties applied. As @MrGrigri and @simonlayfield demonstrate in their visual examples, the items in Masonry are laid out using something akin to a scanline approach where the browser paints horizontally from left to right, top to bottom, and places items at the first available space.

A pure CSS method for building the example above could be to define pseudo-columns for the parent container stating "descendants will be displayed three across" and then telling the browser that each descendant item is a Masonry item with pre-defined horizontal and vertical gutters. The browser then places each item within the first open vertical area of the first available pseudo-column from the top down.

I have no idea what that would look like markup wise, but I don't think it would fall under the grid spec.

@GreLI

This comment has been minimized.

Show comment
Hide comment
@GreLI

GreLI Aug 16, 2017

@tabatkins:

There's no "simple" way to adapt Grid into Masonry - anything would involve non-trivial edits to the layout algorithm. Packery, in particular, really needs things to have a defined width. ^_^

Should not aspect-ratio help with such an issue? Is there a progress about it? For now it's a common way to use padding hack which isn't as simple and pretty as CSS should be.

GreLI commented Aug 16, 2017

@tabatkins:

There's no "simple" way to adapt Grid into Masonry - anything would involve non-trivial edits to the layout algorithm. Packery, in particular, really needs things to have a defined width. ^_^

Should not aspect-ratio help with such an issue? Is there a progress about it? For now it's a common way to use padding hack which isn't as simple and pretty as CSS should be.

@tabatkins

This comment has been minimized.

Show comment
Hide comment
@tabatkins

tabatkins Aug 16, 2017

Member

No, the problem isn't related to aspect ratios.

Member

tabatkins commented Aug 16, 2017

No, the problem isn't related to aspect ratios.

@MladenJanjetovic

This comment has been minimized.

Show comment
Hide comment
@MladenJanjetovic

MladenJanjetovic Sep 11, 2017

Masonry layout is the next big step for CSS grid IMHO.
Actually, the only thing I found missing in CSS grid, so far.

MladenJanjetovic commented Sep 11, 2017

Masonry layout is the next big step for CSS grid IMHO.
Actually, the only thing I found missing in CSS grid, so far.

@Dan503

This comment has been minimized.

Show comment
Hide comment
@Dan503

Dan503 Oct 5, 2017

I think I have a solution that could work. Masonry layout is essentially a series of display: flex; columns with flex-direction set to column that sit next to one another.

The main issue we have right now is that elements in flex as no way of controlling columns when flex-direction is set to column.

There is another css-property that does a similar thing to masonry layout. It's column-count.
https://css-tricks.com/guide-responsive-friendly-css-columns/

Think about this. What if a new flexbox property was introduced that allowed us to control flex-items in a similar sort of way to how column-count works? We can't really use column-count since flex-direction can be set to column which won't make sense.

Just for now let's call the new property flex-block-count. I'm going to use the term flex-block to basically mean a single row/column of flex items. So if you had 2 rows of flex items using flex-wrap, each row would be considered a flex-block.

Let's say we apply flex-block-count: 2 to the flex container. This would basically act the same way as how column-count works on text but it applies to flex items instead of text. It knows that it needs to have at least 2 flex-blocks (unless there aren't enough flex items for that to happen) and it will evenly distribute flex items between flex blocks as best it can. If there are too many flex-items to fit in the flex container, the flex-count setting will be treated as a minimum setting.

This alone wouldn't create masonry layout yet since it would stack things in the wrong order by default:
1 - 4
2 - 5
3 - 6

.flex-container {
  display: flex;
  flex-direction: column;
  flex-block-count: 2;
}

Masonry requires this:
1 - 2
3 - 4
5 - 6

So to achieve that we would need another property. Let's call it flex-block-flow for now. By default, flex-block-flow would be set to straight. If we set it to cross then it would place things across flex blocks as it's first priority and place things within existing flex blocks as a second priority.

1 - 2
3 - 4
5 - 6

.flex-container {
  display: flex;
  flex-direction: column;
  flex-block-count: 2;
  flex-block-flow: cross;
}

You would then use the proposed row-gap and column-gap properties to apply the gaps between flex items.

Dan503 commented Oct 5, 2017

I think I have a solution that could work. Masonry layout is essentially a series of display: flex; columns with flex-direction set to column that sit next to one another.

The main issue we have right now is that elements in flex as no way of controlling columns when flex-direction is set to column.

There is another css-property that does a similar thing to masonry layout. It's column-count.
https://css-tricks.com/guide-responsive-friendly-css-columns/

Think about this. What if a new flexbox property was introduced that allowed us to control flex-items in a similar sort of way to how column-count works? We can't really use column-count since flex-direction can be set to column which won't make sense.

Just for now let's call the new property flex-block-count. I'm going to use the term flex-block to basically mean a single row/column of flex items. So if you had 2 rows of flex items using flex-wrap, each row would be considered a flex-block.

Let's say we apply flex-block-count: 2 to the flex container. This would basically act the same way as how column-count works on text but it applies to flex items instead of text. It knows that it needs to have at least 2 flex-blocks (unless there aren't enough flex items for that to happen) and it will evenly distribute flex items between flex blocks as best it can. If there are too many flex-items to fit in the flex container, the flex-count setting will be treated as a minimum setting.

This alone wouldn't create masonry layout yet since it would stack things in the wrong order by default:
1 - 4
2 - 5
3 - 6

.flex-container {
  display: flex;
  flex-direction: column;
  flex-block-count: 2;
}

Masonry requires this:
1 - 2
3 - 4
5 - 6

So to achieve that we would need another property. Let's call it flex-block-flow for now. By default, flex-block-flow would be set to straight. If we set it to cross then it would place things across flex blocks as it's first priority and place things within existing flex blocks as a second priority.

1 - 2
3 - 4
5 - 6

.flex-container {
  display: flex;
  flex-direction: column;
  flex-block-count: 2;
  flex-block-flow: cross;
}

You would then use the proposed row-gap and column-gap properties to apply the gaps between flex items.

@MrGrigri

This comment has been minimized.

Show comment
Hide comment
@MrGrigri

MrGrigri Oct 5, 2017

This will still not work for children of different height. See #945 (comment) above.

MrGrigri commented Oct 5, 2017

This will still not work for children of different height. See #945 (comment) above.

@Dan503

This comment has been minimized.

Show comment
Hide comment
@Dan503

Dan503 Oct 5, 2017

It could work if something similar to grid-auto-flow:dense; was also introduced to flexbox. I realise that that would probably be a pretty major change to the algorithm though :/

Dan503 commented Oct 5, 2017

It could work if something similar to grid-auto-flow:dense; was also introduced to flexbox. I realise that that would probably be a pretty major change to the algorithm though :/

@Dan503

This comment has been minimized.

Show comment
Hide comment
@Dan503

Dan503 Oct 5, 2017

It would probably be part of flex-block-flow.

flex-block-flow: cross-dense;

Dan503 commented Oct 5, 2017

It would probably be part of flex-block-flow.

flex-block-flow: cross-dense;

@andybarefoot

This comment has been minimized.

Show comment
Hide comment
@andybarefoot

andybarefoot Oct 7, 2017

I'm no expert at either CSS or JavaScript but I think its possible to get a nice Masonry-like solution which uses just a small amount of JavaScript but relies mostly on the CSS Grid functionality.

If each item is the same width (1 column) you can specify the row height of the grid to be something fairly small (say 20 pixels) and then set each item individually to span the optimum number of rows for its content then you get a Masonry layout with the CSS Grid benefits:

  • responsive "auto-fill" the number of columns
  • the "dense" packing automatically gives the correct Masonry ordering defined above

The disadvantage is that the height of each item will be a multiple of the row height (and row gap) and not the exact height of the content. This makes it better for content that is text, or text and image, and not perfect for just images of unpredictable heights.

The JavaScript to loop through all the items and calculate, then set, the correct row span is easy and needs to be done once on page load.
If the items will contain images then you should resize each item again once the image has loaded.
If you are using minmax to give variable column sizes you may want to run the loop again on resize as the width of the columns may change and hence the height of the content.

Even if you do have items of different widths the dense packing still does a good job of creating a gap-free layout although you won't maintain the strict order of your items. In this case a larger row height will result in less gaps in the grid (but more white space at the bottom of each item) and a smaller row height will result in more gaps in the grid (but less white space at the bottom of each item).

Here's my attempt at both fixed-width and multi-width items. Please let me know if you see any flaws or advantages in this approach.

Fixed width: https://codepen.io/andybarefoot/pen/RLRPQL
Multi width: https://codepen.io/andybarefoot/pen/xLvPOE

andybarefoot commented Oct 7, 2017

I'm no expert at either CSS or JavaScript but I think its possible to get a nice Masonry-like solution which uses just a small amount of JavaScript but relies mostly on the CSS Grid functionality.

If each item is the same width (1 column) you can specify the row height of the grid to be something fairly small (say 20 pixels) and then set each item individually to span the optimum number of rows for its content then you get a Masonry layout with the CSS Grid benefits:

  • responsive "auto-fill" the number of columns
  • the "dense" packing automatically gives the correct Masonry ordering defined above

The disadvantage is that the height of each item will be a multiple of the row height (and row gap) and not the exact height of the content. This makes it better for content that is text, or text and image, and not perfect for just images of unpredictable heights.

The JavaScript to loop through all the items and calculate, then set, the correct row span is easy and needs to be done once on page load.
If the items will contain images then you should resize each item again once the image has loaded.
If you are using minmax to give variable column sizes you may want to run the loop again on resize as the width of the columns may change and hence the height of the content.

Even if you do have items of different widths the dense packing still does a good job of creating a gap-free layout although you won't maintain the strict order of your items. In this case a larger row height will result in less gaps in the grid (but more white space at the bottom of each item) and a smaller row height will result in more gaps in the grid (but less white space at the bottom of each item).

Here's my attempt at both fixed-width and multi-width items. Please let me know if you see any flaws or advantages in this approach.

Fixed width: https://codepen.io/andybarefoot/pen/RLRPQL
Multi width: https://codepen.io/andybarefoot/pen/xLvPOE

@ghost

This comment has been minimized.

Show comment
Hide comment
@ghost

ghost Dec 11, 2017

Here's a slightly generalized version of @andybarefoot suggestion:

  • Assumes no column spanning.
  • Uses scrollheight to retrieve each element content size, and adding element margin.

css-grid-layout

ghost commented Dec 11, 2017

Here's a slightly generalized version of @andybarefoot suggestion:

  • Assumes no column spanning.
  • Uses scrollheight to retrieve each element content size, and adding element margin.

css-grid-layout

@Dan503

This comment has been minimized.

Show comment
Hide comment
@Dan503

Dan503 Dec 11, 2017

I don't think that quite works because what happens when item 1 is taller than item 3 but shorter than item 3 + row gap?

It would be trying to place a row in the middle of a row gap which is a bit of a paradox.

I think the solution will end up being something more to do with flexbox than grid.

Dan503 commented Dec 11, 2017

I don't think that quite works because what happens when item 1 is taller than item 3 but shorter than item 3 + row gap?

It would be trying to place a row in the middle of a row gap which is a bit of a paradox.

I think the solution will end up being something more to do with flexbox than grid.

@ghost

This comment has been minimized.

Show comment
Hide comment
@ghost

ghost Dec 11, 2017

Here's my understanding:

  • Positioning: Items are placed in-order. First available row, then first available column.
  • Vertical sizing: Each item takes into consideration the gap spacing when row span is >1, since the gap space is utilizable when spanning. An item gains any additional height leftover within the grid row.

@Dan503 You don't need to think about the row gap unless an item span more than 1 row. And if it spans more than 1 row, then row gap is taken into consideration when finding the total number of grid rows to span.

ghost commented Dec 11, 2017

Here's my understanding:

  • Positioning: Items are placed in-order. First available row, then first available column.
  • Vertical sizing: Each item takes into consideration the gap spacing when row span is >1, since the gap space is utilizable when spanning. An item gains any additional height leftover within the grid row.

@Dan503 You don't need to think about the row gap unless an item span more than 1 row. And if it spans more than 1 row, then row gap is taken into consideration when finding the total number of grid rows to span.

@tabatkins

This comment has been minimized.

Show comment
Hide comment
@tabatkins

tabatkins Dec 11, 2017

Member

Yeah, that math seems right.

Member

tabatkins commented Dec 11, 2017

Yeah, that math seems right.

@andybarefoot

This comment has been minimized.

Show comment
Hide comment
@andybarefoot

andybarefoot Dec 12, 2017

@trondolsen Exactly. The items can only be values of (rowheightx)+(rowgap(x-1)) which means you may get get some unwanted whitespace under your content but you can minimize this by choosing small values of rowheight and rowgap.
The positioning is taken care of by CSS Grid which automatically positions them in default "masonry" order.

andybarefoot commented Dec 12, 2017

@trondolsen Exactly. The items can only be values of (rowheightx)+(rowgap(x-1)) which means you may get get some unwanted whitespace under your content but you can minimize this by choosing small values of rowheight and rowgap.
The positioning is taken care of by CSS Grid which automatically positions them in default "masonry" order.

@OliverJAsh

This comment has been minimized.

Show comment
Hide comment
@OliverJAsh

OliverJAsh Jan 3, 2018

You can have Grid do Masonry if you know the heights of the items ahead of time.

This is the same approach described in https://stackoverflow.com/a/45200955/5932012.

However, this won't work for images which have an aspect ratio instead of a hardcoded height (unless you're OK to crop them with object-fit). The height should change in relation to the column width.

@tabatkins Is there any pure CSS solution for masonry layout that can maintain a defined aspect ratio on each cell?

OliverJAsh commented Jan 3, 2018

You can have Grid do Masonry if you know the heights of the items ahead of time.

This is the same approach described in https://stackoverflow.com/a/45200955/5932012.

However, this won't work for images which have an aspect ratio instead of a hardcoded height (unless you're OK to crop them with object-fit). The height should change in relation to the column width.

@tabatkins Is there any pure CSS solution for masonry layout that can maintain a defined aspect ratio on each cell?

fantasai added a commit that referenced this issue Jan 24, 2018

[css-grid-2] Remove issue about masonry layout; discussion is happeni…
…ng in #945 and it's not entirely clear it's a Grid issue.
@FremyCompany

This comment has been minimized.

Show comment
Hide comment
@FremyCompany
Contributor

FremyCompany commented Mar 8, 2018

Just dropping this here:
https://twitter.com/bfgeek/status/971505916259450880

@AmeliaBR

This comment has been minimized.

Show comment
Hide comment
@AmeliaBR

AmeliaBR Mar 11, 2018

I don't think we can effectively define a masonry layout as an extension of either flexbox or grid layout. There needs to be a new display type.

But I do think that it can be defined without any new properties, by re-using column layout properties.

A display: masonry value on a container would cause child nodes to be treated as distinct items (like in grid/flex layout), and to be assigned according to the agreed-upon rules for masonry layout: one item at a time, into the column that has the least total height.

But the sizing of those columns would be defined by column-width and/or column-count, and column-gap (and sure, why not column-rule, too). Column breaks wouldn't have an effect. Multi-column spans also probably don't make sense (unless someone comes up with a logical proposal of how it would work).

That said, a few properties from grid/flex could be borrowed for more control:

  • row-gap, to specify a gap between masonry items in each column. That's already conveniently been redefined with a layout-mode-agnostic name.
  • align/justify contents/self properties for positioning fixed-width items within their column, and for spacing columns across the container (if both column-width and column-count are constrained, or if there aren't enough items for the number of calculated columns).

But other than the column assignments for items, this isn't new layout math, just re-using existing properties in different combinations. Column widths are defined by the properties on the container. Item sizes are defined by the normal block layout rules when fit into a column of that width.

(@bfgeek How hard would it be for you to tweak your Houdini demo to use the multicol properties to define the column sizes, instead of custom props?)

As an important side benefit to reusing the existing properties, a basic column layout is an acceptable fallback for most masonry layouts. (It looks similar, but the reading/tab order requires scrolling down a column then back up, and the column assignments are not stable if you add new elements to the end of the list.). So in most cases you wouldn't need any fallback code for browsers that don't recognize display: masonry.


Of course, as a few people have mentioned, the other missing piece of the puzzle is a way to define aspect ratios for fit-to-available-width replaced content elements, so that the layout doesn't jump around erratically as images download and change the heights of the masonry items. But that's a feature that is useful well beyond Masonry layout, and should be defined separately.


<aside>

I started playing with existing CSS today, trying to fake Masonry, in a constrained case, as a flexbox layout with :nth-of-type() used to adjust order (Spoiler: even after constraining the container size to match the content & number of columns, it didn't work).

I even started to write up a full proposal defining masonry as a new value for flex-wrap (the idea being that you'd assign items to flex lines by going across the cross axis, instead of by filling up a single line on the flex axis). But that made me realize that you would need to define the cross-axis line height/width before assigning items, and that's not how flexbox works. But it is how columns work: the column sizes are defined by the container size, and content fits to the columns. So I wrote up this proposal, instead.

</aside>

AmeliaBR commented Mar 11, 2018

I don't think we can effectively define a masonry layout as an extension of either flexbox or grid layout. There needs to be a new display type.

But I do think that it can be defined without any new properties, by re-using column layout properties.

A display: masonry value on a container would cause child nodes to be treated as distinct items (like in grid/flex layout), and to be assigned according to the agreed-upon rules for masonry layout: one item at a time, into the column that has the least total height.

But the sizing of those columns would be defined by column-width and/or column-count, and column-gap (and sure, why not column-rule, too). Column breaks wouldn't have an effect. Multi-column spans also probably don't make sense (unless someone comes up with a logical proposal of how it would work).

That said, a few properties from grid/flex could be borrowed for more control:

  • row-gap, to specify a gap between masonry items in each column. That's already conveniently been redefined with a layout-mode-agnostic name.
  • align/justify contents/self properties for positioning fixed-width items within their column, and for spacing columns across the container (if both column-width and column-count are constrained, or if there aren't enough items for the number of calculated columns).

But other than the column assignments for items, this isn't new layout math, just re-using existing properties in different combinations. Column widths are defined by the properties on the container. Item sizes are defined by the normal block layout rules when fit into a column of that width.

(@bfgeek How hard would it be for you to tweak your Houdini demo to use the multicol properties to define the column sizes, instead of custom props?)

As an important side benefit to reusing the existing properties, a basic column layout is an acceptable fallback for most masonry layouts. (It looks similar, but the reading/tab order requires scrolling down a column then back up, and the column assignments are not stable if you add new elements to the end of the list.). So in most cases you wouldn't need any fallback code for browsers that don't recognize display: masonry.


Of course, as a few people have mentioned, the other missing piece of the puzzle is a way to define aspect ratios for fit-to-available-width replaced content elements, so that the layout doesn't jump around erratically as images download and change the heights of the masonry items. But that's a feature that is useful well beyond Masonry layout, and should be defined separately.


<aside>

I started playing with existing CSS today, trying to fake Masonry, in a constrained case, as a flexbox layout with :nth-of-type() used to adjust order (Spoiler: even after constraining the container size to match the content & number of columns, it didn't work).

I even started to write up a full proposal defining masonry as a new value for flex-wrap (the idea being that you'd assign items to flex lines by going across the cross axis, instead of by filling up a single line on the flex axis). But that made me realize that you would need to define the cross-axis line height/width before assigning items, and that's not how flexbox works. But it is how columns work: the column sizes are defined by the container size, and content fits to the columns. So I wrote up this proposal, instead.

</aside>

@frivoal

This comment has been minimized.

Show comment
Hide comment
@frivoal

frivoal Mar 11, 2018

Contributor

@AmeliaBR That sounds like it would work, except if you want multiple columns of different sizes. Is the demand for that low enough that we can defer it to whenever multicol gets columns of different sizes (which might be never), or would that be a deal breaker?

Contributor

frivoal commented Mar 11, 2018

@AmeliaBR That sounds like it would work, except if you want multiple columns of different sizes. Is the demand for that low enough that we can defer it to whenever multicol gets columns of different sizes (which might be never), or would that be a deal breaker?

@AmeliaBR

This comment has been minimized.

Show comment
Hide comment
@AmeliaBR

AmeliaBR Mar 11, 2018

@frivoal Most of the examples I've seen use a consistent width for all columns, so I wasn't considering an option of different sizes as part of the layout requirement.

David DeSandro's Masonry library, which is also used in Isotope, supports multi-column spanning objects (within a grid of fixed column sizes), in addition to the simpler layout I was focusing on. The packing algorithm works most effectively if the item heights are also multiples of a grid row height, so that it becomes very much like a densely packed auto-fit grid. However, the number of row spans is calculated by the JS, and there may be gaps created by one element filling multiple columns that weren't the same height. So, this could be a basis for using column-span within display: masonry as I described it above.

In contrast, Oracle Jet's masonry layout and the Nested JQuery plugin are densely-packed grid layouts as defined in CSS grid, with each item given fixed row and column spans; they don't support arbitrary or auto-height items.

Other masonry JS libraries/plugins (that I found in a search for "masonry layout") all use columns with the same width, each item in a single column, and heights determined by the content items: Macy.js, Wookmark JQuery plugin, WordPress Masonry Layout.

This SitePoint article also includes horizontal flow layouts in the category of "masonry", but they are more like wrapping flexbox: fill one row, then wrap to the next, with flexible size adjustments to fill the row width.

(One limitation of using columns is that it only divides the container along the inline direction. If you really wanted a layout in LTR language with a fixed number of rows, where you added items to the row that has the least content, so that the reading order goes down columns first then across the screen, you would need to change the writing-mode on the container to vertical, then change it back to horizontal on the items. But I haven't seen examples of this layout in practice, so that doesn't seem like a problem.)


A comment on this entire topic:

The goal of the extensible web & of the Houdini project is to allow web authors to implement custom features, and let actual use determine which new web platform features are most wanted. Once an idea is proved popular, and a consensus has been achieved about its key features, then it would be standardized.

I'm not a huge fan of the masonry layout, but I do believe that it has met this standard.

I just listed four different JS implementations of Masonry that implement the same basic layout rules.

There are also numerous search results promising "Pure CSS" masonry, which use multicol or flexbox columns to create something that is visually similar to the column-based masonry layout. But as mentioned elsewhere in this thread, these solutions are sub-optimal because the DOM order doesn't match the normal LTR reading order & the layout is unstable when you add new items to the container.

To me, the only confusions / questions about features (separate from debating the actual API) are:

  • One of the masonry libraries also supports elements that span multiple columns. Should that also be included in the native feature?
  • Two other libraries that came up in my search use the name masonry, but implement a 2D densely packed grid, which is now supported natively in CSS under another name. Does that mean that the name "masonry" is ambiguous, and another name is needed? (I'm pretty sure we can't use display: pinterest-style...)

AmeliaBR commented Mar 11, 2018

@frivoal Most of the examples I've seen use a consistent width for all columns, so I wasn't considering an option of different sizes as part of the layout requirement.

David DeSandro's Masonry library, which is also used in Isotope, supports multi-column spanning objects (within a grid of fixed column sizes), in addition to the simpler layout I was focusing on. The packing algorithm works most effectively if the item heights are also multiples of a grid row height, so that it becomes very much like a densely packed auto-fit grid. However, the number of row spans is calculated by the JS, and there may be gaps created by one element filling multiple columns that weren't the same height. So, this could be a basis for using column-span within display: masonry as I described it above.

In contrast, Oracle Jet's masonry layout and the Nested JQuery plugin are densely-packed grid layouts as defined in CSS grid, with each item given fixed row and column spans; they don't support arbitrary or auto-height items.

Other masonry JS libraries/plugins (that I found in a search for "masonry layout") all use columns with the same width, each item in a single column, and heights determined by the content items: Macy.js, Wookmark JQuery plugin, WordPress Masonry Layout.

This SitePoint article also includes horizontal flow layouts in the category of "masonry", but they are more like wrapping flexbox: fill one row, then wrap to the next, with flexible size adjustments to fill the row width.

(One limitation of using columns is that it only divides the container along the inline direction. If you really wanted a layout in LTR language with a fixed number of rows, where you added items to the row that has the least content, so that the reading order goes down columns first then across the screen, you would need to change the writing-mode on the container to vertical, then change it back to horizontal on the items. But I haven't seen examples of this layout in practice, so that doesn't seem like a problem.)


A comment on this entire topic:

The goal of the extensible web & of the Houdini project is to allow web authors to implement custom features, and let actual use determine which new web platform features are most wanted. Once an idea is proved popular, and a consensus has been achieved about its key features, then it would be standardized.

I'm not a huge fan of the masonry layout, but I do believe that it has met this standard.

I just listed four different JS implementations of Masonry that implement the same basic layout rules.

There are also numerous search results promising "Pure CSS" masonry, which use multicol or flexbox columns to create something that is visually similar to the column-based masonry layout. But as mentioned elsewhere in this thread, these solutions are sub-optimal because the DOM order doesn't match the normal LTR reading order & the layout is unstable when you add new items to the container.

To me, the only confusions / questions about features (separate from debating the actual API) are:

  • One of the masonry libraries also supports elements that span multiple columns. Should that also be included in the native feature?
  • Two other libraries that came up in my search use the name masonry, but implement a 2D densely packed grid, which is now supported natively in CSS under another name. Does that mean that the name "masonry" is ambiguous, and another name is needed? (I'm pretty sure we can't use display: pinterest-style...)
@ghost

This comment has been minimized.

Show comment
Hide comment
@ghost

ghost Mar 11, 2018

For a demo of my usage see https://trondolsen.github.io/dashboard/dashboard.html. Items have variable height, are filled left-to-right, prioritized.

readme

ghost commented Mar 11, 2018

For a demo of my usage see https://trondolsen.github.io/dashboard/dashboard.html. Items have variable height, are filled left-to-right, prioritized.

readme

@w3c w3c deleted a comment from davemorris80 Mar 20, 2018

@SabineWren

This comment has been minimized.

Show comment
Hide comment
@SabineWren

SabineWren Apr 3, 2018

A console warning would be marvellous for debugging the 1000 row grid limit on Chrome, especially for people who don't develop in Chrome. It's a stupid limit anyway, because without it grid would be fine for masonry. Computers have tons of memory.

SabineWren commented Apr 3, 2018

A console warning would be marvellous for debugging the 1000 row grid limit on Chrome, especially for people who don't develop in Chrome. It's a stupid limit anyway, because without it grid would be fine for masonry. Computers have tons of memory.

@gethinoakes

This comment has been minimized.

Show comment
Hide comment
@gethinoakes

gethinoakes Apr 18, 2018

@SabineWren thanks for mentioning this, I thought I'd finally found a simple solution for a masonry layout with CSS grid... both Safari and Firefox seem to handle 1,000+ rows just fine.

I left a comment on the related issue and had a response saying hopefully they'll have a fix "in the following weeks"... not quite sure what that means but hopefully we'll be able to use this soon!

https://bugs.chromium.org/p/chromium/issues/detail?id=688640

gethinoakes commented Apr 18, 2018

@SabineWren thanks for mentioning this, I thought I'd finally found a simple solution for a masonry layout with CSS grid... both Safari and Firefox seem to handle 1,000+ rows just fine.

I left a comment on the related issue and had a response saying hopefully they'll have a fix "in the following weeks"... not quite sure what that means but hopefully we'll be able to use this soon!

https://bugs.chromium.org/p/chromium/issues/detail?id=688640

@tabatkins

This comment has been minimized.

Show comment
Hide comment
@tabatkins

tabatkins Apr 18, 2018

Member

Note that we've decided to add a SHOULD-level requirement (implementations must honor it, unless they have a good reason to do otherwise) for browsers to support at least 10k rows/columns (plus another 10k in the negative direction). https://drafts.csswg.org/css-grid/#overlarge-grids

Member

tabatkins commented Apr 18, 2018

Note that we've decided to add a SHOULD-level requirement (implementations must honor it, unless they have a good reason to do otherwise) for browsers to support at least 10k rows/columns (plus another 10k in the negative direction). https://drafts.csswg.org/css-grid/#overlarge-grids

@jonjohnjohnson

This comment has been minimized.

Show comment
Hide comment
@jonjohnjohnson

jonjohnjohnson commented Apr 19, 2018

@SabineWren @gethinoakes #2261 - [css-grid] Re "Clamping Overly Large Grids": Perhaps have a minimal required track count

RESOLVED: have a minimum of 10k tracks in each direction as a recommendation

@oscarotero

This comment has been minimized.

Show comment
Hide comment
@oscarotero

oscarotero Jun 6, 2018

Hi.
I think a good approach for masonry-style layouts is something similar to salvattore: https://github.com/rnmp/salvattore

I imagine a new property to define how the items are placed in the cells. Currently, if two elements are in the same cell, they are overlapping. This new property, let's call area-placement could have the value flow to insert the new items next to the currently existing items. For example:

.masonry {
    display: grid;
    grid-template-column: repeat(3, 300px);
    grid-column-gap: 20px;
}
.item:nth-child(3n+1) {
    grid-area: 1 / 1;
    area-placement: flow;
}
.item:nth-child(3n+2) {
    grid-area: 2 / 1;
    area-placement: flow;
}
.item:nth-child(3n) {
    grid-area: 3 / 1;
    area-placement: flow;
}

This brings more flexibility, not only to build masonry layouts, but also for more other use cases.

oscarotero commented Jun 6, 2018

Hi.
I think a good approach for masonry-style layouts is something similar to salvattore: https://github.com/rnmp/salvattore

I imagine a new property to define how the items are placed in the cells. Currently, if two elements are in the same cell, they are overlapping. This new property, let's call area-placement could have the value flow to insert the new items next to the currently existing items. For example:

.masonry {
    display: grid;
    grid-template-column: repeat(3, 300px);
    grid-column-gap: 20px;
}
.item:nth-child(3n+1) {
    grid-area: 1 / 1;
    area-placement: flow;
}
.item:nth-child(3n+2) {
    grid-area: 2 / 1;
    area-placement: flow;
}
.item:nth-child(3n) {
    grid-area: 3 / 1;
    area-placement: flow;
}

This brings more flexibility, not only to build masonry layouts, but also for more other use cases.

@FremyCompany

This comment has been minimized.

Show comment
Hide comment
@FremyCompany

FremyCompany Jun 8, 2018

Contributor

I don't see why you force a specific column in your example, you can achieve the exact same example like this:

.masonry {
    display: grid;
    grid-template-column: repeat(3, 300px);
    grid-column-gap: 20px;
    grid-auto-rows: auto;
}
.item:nth-child(3n+1) {
    grid-column: 1;
}
.item:nth-child(3n+2) {
    grid-column: 2;
}
.item:nth-child(3n) {
    grid-column: 3;
}

(and when you have subgrid, you will be able to wrap this niceline in one row of the parent grid if you want, yet reusing the grid lines for your columns)

Contributor

FremyCompany commented Jun 8, 2018

I don't see why you force a specific column in your example, you can achieve the exact same example like this:

.masonry {
    display: grid;
    grid-template-column: repeat(3, 300px);
    grid-column-gap: 20px;
    grid-auto-rows: auto;
}
.item:nth-child(3n+1) {
    grid-column: 1;
}
.item:nth-child(3n+2) {
    grid-column: 2;
}
.item:nth-child(3n) {
    grid-column: 3;
}

(and when you have subgrid, you will be able to wrap this niceline in one row of the parent grid if you want, yet reusing the grid lines for your columns)

@oscarotero

This comment has been minimized.

Show comment
Hide comment
@oscarotero

oscarotero Jun 9, 2018

Sorry, I have explained myself badly.
What I try to say is that when you place many elements in the same cell in a grid, these elements are overlapping each other. You can see an example here:

https://codepen.io/oscarotero/pen/yEgawv

A way to archieve a masonry-style grid could be allowing to customize this behavior and instead place all elements in the same position, they respect the natural flow, as they where placed in different containers like in this example:

https://codepen.io/oscarotero/pen/LrxRoK

Your example is not valid because the cells of the same row have the same height:

https://codepen.io/oscarotero/pen/JZERgq

AFAIK, subgrid cannot be applied to grid areas, but html element. If subgrid could be applied to grid areas or cells, that would be great because opens the door to an endless number of possibilities.

oscarotero commented Jun 9, 2018

Sorry, I have explained myself badly.
What I try to say is that when you place many elements in the same cell in a grid, these elements are overlapping each other. You can see an example here:

https://codepen.io/oscarotero/pen/yEgawv

A way to archieve a masonry-style grid could be allowing to customize this behavior and instead place all elements in the same position, they respect the natural flow, as they where placed in different containers like in this example:

https://codepen.io/oscarotero/pen/LrxRoK

Your example is not valid because the cells of the same row have the same height:

https://codepen.io/oscarotero/pen/JZERgq

AFAIK, subgrid cannot be applied to grid areas, but html element. If subgrid could be applied to grid areas or cells, that would be great because opens the door to an endless number of possibilities.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment