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
Alternate masonry path forward #9041
Comments
|
Separating masonry from grid layout was already discussed in #4650 and had a bunch of proponents, including me. As indicated by the different properties @bfgeek introduces, masonry layout works differently than grid in several points. And separating its syntax from grid also allows adding features that only apply to it and not to grid and vice versa. Sebastian |
|
I've never been a fan of including masonry in grid layout. Mostly because we'd forever more be having to figure out how new grid stuff works with Masonry layout, which will always be a bit weird because a masonry layout is different to a grid layout. The current spec makes masonry layouts do a whole bunch of extra things that I've not seen authors ask for, mostly because "why not?" once it's all bundled into grid. Without compelling use cases for these features, it feels as if we'd be adding future problems of needing to work round masonry for grid additions, plus making to harder to add masonry specific things. I think this proposal achieves the things people want out of masonry, and avoids these pitfalls. |
|
(Fwiw I could have sworn we had a resolution to adopt |
I was actually searching for this quite a lot lately and didn't find a resolution on this and to be honest not even a draft. Would that be smth. for the Cupertino F2F Agenda as well @fantasai? |
|
So I don't forget - default alignment needs to be different for masonry as well. E.g. its desirable for replaced elements to stretch (vs. the grid default of start) similar to flexbox. |
|
Another thing so I don't forget - variable track sizes is problematic with items that span multiple tracks with "dense" packing. To correctly place the item in the correct tracks, you need O(N) layout passes on the item. |
For what it's worth, I do have a use case for that at https://www.gamestar.de. That page has two columns. And those columns contain different sections, which are placed explicitly in those columns. In horizontal direction the sections are meant to align on tracks while vertically they should be independent from each other. At the same time, they are explicitly placed in one of the tracks. The two-column split is just one example. There are other pages which use three or even four columns. So, this seems to be a perfect match for masonry layout. And I believe, basically every website that is split into several columns could benefit from masonry layout. display: masonry;
masonry-template: minmax(0,1fr) minmax(0,2.5fr) minmax(0,15rem);The point of using Masonry here is that the height of the items should not depend on each other nor on a grid. So, I'd vote for a Sebastian |
|
That's not really masonry tho, right? They're not selecting the column based on available space; the stuff in the first column is meant for the first column, the stuff in the second is meant for the second. Today this would just be a grid with two columns and one row, with all the stuff in each column wrapped in a container. To fix the general problem of wanting to flow a mixed set of contents into a single grid cell without having to pre-wrap them in a container div we have #9098 |
Right. That use case avoids the auto-placement algorithm altogether, like it can be done in Grid and Flexbox, already. The benefit over Grid is that they are only aligned on one axis and the benefit over Flexbox is that they don't rely on wrapping logic.
Correct. That's how it's solved right now in the first example.
Yes, that issues would also solve that use case. Though that use case seems to be a natural fit for masonry and less so for grid. Sebastian |
|
What I mean is, since there is no column auto-selection at all, this isn't Masonry. Masonry's entire reason for existing is to allow you to place items according to the tracks' current fill height; if you're skipping that entirely, then Masonry might not be the right abstraction for this. This is especially true if reusing Masonry as the layout abstraction for this (and making changes to accommodate it) would harm more core use-cases. On the other hand, nothing about this case is particularly unusual for Grid. New functionality is needed (flowing multiple items into one cell as if they were grouped into a container element), but it's immediately compatible with the rest of Grid, too; it doesn't force us to reshape anything else about grid to accommodate it. As far as Grid is concerned it's exactly like just having a container element filled with stuff, and that's exactly what the use-case needs and wants out of it. So yes, in theory we could address some variations of this "flow multiple items into one grid cell" use-case with Masonry, but we can't hit all of them, and even for the ones we can do, it requires adding additional features to Masonry that harm the core use-cases. |
I'd argue that this is not true. The spec's introduction says this:
This is the main use case for Masonry. The auto-placement algorithm is one aspect of it, like it is for Grid layout. Sebastian |
|
Yes, that's an introduction for Grid Level 3. It was written starting from the assumption that this new functionality would be based on Grid, so it being somewhat Grid-biased is not a surprise. But the use-case in the wild, that we are attempting to capture in a layout mode, is pretty clear: it's items of arbitrary size being placed relatively tightly into tracks according to whichever track is currently least-filled. Placing items into specific tracks without automatic placement has not been traditionally called "masonry" or addressed by those tools; it's instead been handled by "group them in a container element". Anything going beyond that remit might be appropriate to solve with Masonry, or might be best solved with another layout mode (one that already exists or one not yet written!). We should not assume that every nearby use-case is necessarily appropriate to fold in, particularly when, as I said, doing so would harm the core use-cases. (Which allowing different-sized columns might do, as has been argued, by making some features (spanners, in particular) either not work correctly or be surprisingly expensive to layout.) |
|
The CSS Working Group just discussed The full IRC log of that discussion<TabAtkins> iank_: When Masonry was introduced there was discussion about whether this should be a new display type, or built into grid<TabAtkins> iank_: After reviewing this in more detail, I'm more convinced we want a new display type <TabAtkins> iank_: We didn't have a great proposal for what this would look like, so I typed up some details in a quick issue <TabAtkins> iank_: There's some fudnamental tensions between Masonry layout and Grid. This leads to some undesireable complexities, possibly perf problems <TabAtkins> iank_: So for a new masonry display type, we can do masonry-first, rather than bolting it onto Grid <TabAtkins> iank_: This is so far a very simple proposal, it can be extended in the future, but it concentrates on the core use-cases <TabAtkins> iank_: Handful of props. masonry-template tells how your non-masonry'd tracks look <TabAtkins> iank_: One detail is that, at least for now, ahving all your tracks the same size is important for perf. <TabAtkins> iank_: We also ahven't seen different-size tracks in the wild. <TabAtkins> iank_: Another is masonry-direction, same concept as flex. <TabAtkins> iank_: There are example where you want your masonry items to flow upwards <TabAtkins> iank_: Another detail - you can tell a masonry item to span, but not specify in a specific track. Again, based on use-cases we haven't found any use for that. <TabAtkins> iank_: A few other bits about alignment, squaring off. <fantasai> scribe+ <TabAtkins> Rossen_: Next steps? <TabAtkins> iank_: We might be interestsed in prototyping this in Chromium. I think if there are any fundamental issues, or use-cases that aren't covered by this proposal, that would be good to hear about <TabAtkins> Rossen_: I see the issue thread is already fairly active, some +1s, some open issues. <TabAtkins> Rossen_: I propose we take the convo back to the issue. When we have enough of an understanding on next steps we can bring them here. <fantasai> -> https://github.com//issues/9041#issuecomment-1710838816 <TabAtkins> fantasai: I took Ian's issues and split them out into sub-issues <Rossen_> ack fantasai <TabAtkins> fantasai: I think we should go thru and address these individually <TabAtkins> fantasai: The q of whether to make this a new display type or part of grid is kinda like the top of this issue, but some of the questions are "well is it even possible to build this into grid?" and I think we should answer that first <TabAtkins> fantasai: Then the question about a new display type isn't about whether or not it's possible, but whether it's *better* to be part of Grid or a separate display type. <TabAtkins> fantasai: I think all the issues Ian raises are addressable within the Grid framework, so it would be good to go thru the individual issues to see if they're actually blockers. <TabAtkins> fantasai: Then we can come back and see whether there's acutally a blocker that forces a new display type, or if it *is* possible in Grid so it'll be more a decision of which is better <plinss> q+ <TabAtkins> iank_: One thing I want to ensure is that, while lots of things are possible, perf is important. I'm concerned about quadratic behavior to add this into Grid. <Rossen_> ack plinss <TabAtkins> plinss: Orthogonal q - what's the status of layout worklets? <TabAtkins> iank_: We have a prototype; we want to clean it up after our layout rearchitecture. <TabAtkins> iank_: It's not a huge list of issues, we're just evaluating where it is on priority. <TabAtkins> plinss: k, just curious. if we're experimenting with new display types, seems like a great opportunity to explore in userland <TabAtkins> (fwiw I'm fairly certain Masonry *can* be done in the existing layout worklet API) |
|
Regarding |
|
grid-gpa having been generalized as gap for usage in flexbox actually made it impossible to detect support for gap in flexbox with |
Hmm... I think that would be less likely to be a problem here if this was included in the first version the masonry spec as you would be able to just test for masonry support at all. In general, I would prefer properties to be combined like this. Otherwise you end up with lots of duplicates which is much harder for authors to remember. Imagine if margin, padding, aspect-ratio, etc all had separate variants for each layout mode. |
|
@nicoburns the issue is not about detecting support for it in Masonry, where the support should be detected for Masonry itself indeed. The issue would be detecting the support in Flexbox, in case Properties shared between multiple layouts would require these rules to be feature detectable properly:
However, I have no idea how realistic enforcing those is.
|
I mean, ideally this just wouldn't happen, and the release of the property could be coordinated for all layout modes (similarly to aspect-ratio). But in this case, I don't think it would matter too much if that didn't happen:
What would be the use case for this? If you want to support older browsers that don't support If there were properties that did require layout-mode specific feature detection then I guess it might make sense to add the ability to specify display mode to |

TL;DR
The primary issue with building masonry layout on top of grid is related to intrinsic-sizing (of the container itself, and intrinsic tracks).
Grid layout works by placing everything in the 2D grid, that is assigning each child a column(s), and row(s), then sizing the grid with all the children fixed within the grid (they can't jump to another grid position).
Masonry layout however works in reverse - by sizing the rows/columns first, then placing children in the "shortest" row/column. This means that we can't correctly size the rows/columns (as we don't know the content), and also can't size the container itself correctly (if sizing using min/max content sizes).
This is detailed in issue: #8206
There are potential workarounds to deal with this issue, e.g. assume that all children are in every row/column for the purposes of sizing, but this prevents some potentially desirable use cases.
One thing that seems desirable is to allow a wider/different syntax for rows/columns than is currently allowed for grid, e.g.
masonry-template: repeat(auto-fill, auto).(Above would measure all the masonry items, and select the best number of tracks to fit the content).
(Arguably above might be a better default than masonry-template: auto for example).
This isn't possible for grid-template for good reasons - but we could accept it for masonry.
One open question is if we need different track sizes or just one would suffice. All the designs I have personally seen have just one track repeated N times. Accepting just one track template would allow easier intrinsic sizing of spanners for example.
One addition which is currently missing with grid repeaters is the ability to clamp to a minimum / maximum number. This is more relevant with masonry. E.g.
masonry-template: repeat(auto-fill, /* min */ 1, /* max */ 5, auto)would allow clamping to a maximum of 5 tracks which seems desirable from designs I've seen.(this is probably a bad syntax but you get the idea).
Another missing in the current proposal is controlling the direction of the masonry flow. E.g. there are cases where you'd want the masonry axis to start from the block-end / inline-end.
This could be covered by a property similar to flex-direction , a simple (and likely understandable property) might be:
masonry-direction: row | row-reverse | column | column-reverse(this would be similar to the originTop/originLeft controls in masonry.js https://masonry.desandro.com/options.html#originleft )
One issue with masonry style layouts is that things can easily be visually out of order, e.g. if the current tracks are [100px, 99px] the next masonry item would be placed in the 2nd track, when the first would be more natural. A potentially solution to this is some user defined "threshold" to "place within the first track within Xpx of the smallest track"
masonry-threshold: <length>Things that aren't in this proposal vs. the current draft are:
Ian
The text was updated successfully, but these errors were encountered: