Skip to content
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 · 58 comments
Open

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

rachelandrew opened this issue Jan 16, 2017 · 58 comments

Comments

@rachelandrew
Copy link
Contributor

@rachelandrew 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
Copy link

@jensimmons 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
Copy link

@Zatnosk 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
Copy link
Member

@tabatkins 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
Copy link

@MatsPalmgren 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
Copy link

@hunboy 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
Copy link

@hunboy 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
Copy link

@jamesdoc 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
Copy link

@yisibl 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
Copy link

@hunboy hunboy commented Mar 30, 2017

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

@yisibl
Copy link

@yisibl yisibl commented Apr 21, 2017

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

@jcklpe
Copy link

@jcklpe 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
Copy link

@nategreen 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
Copy link
Member

@tabatkins 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
Copy link

@MrGrigri 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
Copy link
Member

@tabatkins 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
Copy link

@MrGrigri 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
Copy link
Contributor Author

@rachelandrew 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
Copy link
Collaborator

@Loirooriol 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

Edit: Actually, breaking flex lines with break-before: always is a Firefox bug. The standard way will be wrap-before: flex.

@tabatkins
Copy link
Member

@tabatkins 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
Copy link

@MrGrigri 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
Copy link

@simonlayfield 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
Copy link
Collaborator

@Loirooriol 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
Copy link

@mor10 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
Copy link

@GreLI 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
Copy link
Member

@tabatkins tabatkins commented Aug 16, 2017

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

@MladenJanjetovic
Copy link

@MladenJanjetovic 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
Copy link

@Dan503 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.

@OliverJAsh
Copy link

@OliverJAsh 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
…ng in #945 and it's not entirely clear it's a Grid issue.
@FremyCompany
Copy link
Contributor

@FremyCompany FremyCompany commented Mar 8, 2018

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

@AmeliaBR
Copy link
Contributor

@AmeliaBR 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
Copy link
Collaborator

@frivoal 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
Copy link
Contributor

@AmeliaBR 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
Copy link

@ghost 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
Copy link

@SabineWren 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
Copy link

@gethinoakes 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
Copy link
Member

@tabatkins 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
Copy link

@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
Copy link

@oscarotero 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
Copy link
Contributor

@FremyCompany 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
Copy link

@oscarotero 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.

@desandro
Copy link

@desandro desandro commented Oct 24, 2018

Hi, I am the author of Masonry JavaScript plugin. Just seeing this thread now.

I would love to see Masonry layouts be added to the CSS spec

The Masonry plugin will turn 10 years old next year. It has remained widely popular through the years. Even with the addition of flexbox & grid layout specs, the Masonry use case remains to be supported natively. It deserves to be added to the spec. I regret not advocating for its adoption earlier (hindsight 20/20).

A couple items to think about:

Loading images

The Masonry layout algorithm works by iterating through a collection of item elements, measuring each, and placing them in a column. If the size of an item changes (loading media like images and video) the entire layout may need to change — placing items in different columns. This can lead disorientation while you watch the page load.

Multi-column spanning items

Will the layout support items that can occupy more than one column?

masonry-multi

Filling gaps

If multi-column items are supported, does the algorithm support filling gaps that may be filled by subsequent items? I had to develop a separate plugin, Packery, to hand this much requested feature.

masonry-gap2

Retaining horizontal order

Lots of users still expect horizontal order to be maintained even with the Masonry layout. See desandro/masonry#873. Counter-intuitive to a developer, I realized, but its what the people wanted.

masonry-order


That said, I think a Masonry layout spec that at least supports the basic single-column layout would be a great feature that satisfies 80% of use cases. I'm happy to provide my experience & discuss this more.

@SelenIT
Copy link
Collaborator

@SelenIT SelenIT commented Oct 24, 2018

I believe that this comment is underrated in this thread. I can't help seeing that the behavior of the Packery algorithm is to the usual behavior of floating boxes as dense auto placement is to default (sparse) auto placement in Grid layout. Maybe [css-floats-3] could also be considered a possible approach for this?

@MrGrigri
Copy link

@MrGrigri MrGrigri commented Oct 24, 2018

This should now be supported with the CSS.layoutWroklet -- Aka Houdini -- in at lease Chrome for now. I have created a pen here that demonstrates this functionality. Because of the way that Codepen works, there is another supporting file found here that is the actual layoutWorklet.

The whole point of the layoutWorklet is so that the W3C doesn't have to come up with a new layout every time it becomes popular.

@MrGrigri
Copy link

@MrGrigri MrGrigri commented Oct 24, 2018

This spec provides direct access to the layout portion of the JavaScript event loop. Thus making it highly performant.

@OliverJAsh
Copy link

@OliverJAsh OliverJAsh commented Jun 15, 2019

A clever and recent technique which uses flexbox: https://tobiasahlin.com/blog/masonry-with-css/. (Posting here because it's not been posted yet, and it might be a good workaround for anyone who lands here.)

@Loirooriol
Copy link
Collaborator

@Loirooriol Loirooriol commented Jun 15, 2019

@OliverJAsh Isn't that the same as what I proposed 2 years ago in this same thread? #945 (comment)

@OliverJAsh
Copy link

@OliverJAsh OliverJAsh commented Jun 17, 2019

@Loirooriol Yes, you're right. Apologies.

@MatsPalmgren
Copy link

@MatsPalmgren MatsPalmgren commented Jan 6, 2020

I've experimented a bit with implementing masonry layout inside a grid container and I've summarized my conclusions in #4650.

@Nic787
Copy link

@Nic787 Nic787 commented Apr 8, 2020

I believe that this comment is underrated in this thread. I can't help seeing that the behavior of the Packery algorithm is to the usual behavior of floating boxes as dense auto placement is to default (sparse) auto placement in Grid layout. Maybe [css-floats-3] could also be considered a possible approach for this?

I think you have a good point.
Currently, float is becoming old and flexbox allow a lot of things to be done, but this masonry layout is lacking in both.
I drawn this to show what people are forgetting about the masonry layout. It's not just a way to automatically place boxes or images where it fit. I think the best way to see that is that it put the following image at the highest point it can get in a column.
masonry
What I want to show you there is that box 4 is not necessarily on the left. It's where you get the highest point like I said. Sometimes you can have lot of small images in a row, so making it left to right can't work all the time. Masonry is left to right like always, but in a way it's easier for the user to access informations.

Like this example over there : http://www.castlecodeweb.com/mediaboxes/example/gallery.html
Whatever, even if this can make beautiful gallery like this one, another solution is to use justified gallery which is almost the same, but instead of having rows of different height, you have columns of different width which is much simpler in term of coding.
https://wexley-demo.squarespace.com/
http://miromannino.github.io/Justified-Gallery/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
You can’t perform that action at this time.