w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.28k stars 632 forks source link

Alternate masonry path forward #9041

Open bfgeek opened 10 months ago

bfgeek commented 10 months ago

TL;DR

display: masonry;
masonry-template: repeat(auto-fill, auto);
masonry-direction: column-reverse;
masonry-span: 2;
masonry-threashold: 2px;

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: https://github.com/w3c/csswg-drafts/issues/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

SebastianZ commented 10 months ago

Separating masonry from grid layout was already discussed in #4650 and had a bunch of proponents, including me. @argyleink, @meyerweb, @AmeliaBR, @rachelandrew, @JoshuaLindquist, @thomascallahan FYI

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

rachelandrew commented 10 months ago

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.

fantasai commented 10 months ago

(Fwiw I could have sworn we had a resolution to adopt column-reverse and row-reverse values for grid-auto-flow, but I can't find it.)

Que-tin commented 10 months ago

(Fwiw I could have sworn we had a resolution to adopt column-reverse and row-reverse values for grid-auto-flow, but I can't find it.)

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?

bfgeek commented 10 months ago

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.

bfgeek commented 8 months ago

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.

fantasai commented 8 months ago

Breaking the specifics out into separate issues (not that this invalidates this one, or that listing them all here isn't useful, but still should have them filed individually):

SebastianZ commented 8 months ago
  • No ability to place a masonry item in an explicit row/column. I personally haven't seen people do this. Personally I don't think it's needed, and somewhat harmful accessibility wise.

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.

Homepage layout at gamestar.de

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. Take MDN for example. Instead of using Grid, its three-column layout could be done using masonry, i.e.

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 masonry-track property that allows to place items explicitly in a track (or even span over multiple ones) similar to how grid-column and grid-row work.

Sebastian

tabatkins commented 8 months ago

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 https://github.com/w3c/csswg-drafts/issues/9098

SebastianZ commented 8 months ago

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.

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.

Today this would just be a grid with two columns and one row, with all the stuff in each column wrapped in a container.

Correct. That's how it's solved right now in the first example.

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

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

tabatkins commented 8 months ago

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.

SebastianZ commented 8 months ago

Masonry's entire reason for existing is to allow you to place items according to the tracks' current fill height

I'd argue that this is not true. The spec's introduction says this:

This module defines a layout system that removes that restriction so that items can be placed into Grid-like tracks in just one of the axes, while stacking them one after another in the other axis.

This is the main use case for Masonry. The auto-placement algorithm is one aspect of it, like it is for Grid layout. And restricting it to auto-placement seems arbitrary to me and is also hugely restricting its usefulness. Allowing to place items manually (in addition to auto-placement) opens Masonry up to a whole new class of use cases. The use case is not "flow multiple items into one grid cell". (That's handily expressed so that it fits to #9098.) The use case is "have multiple tracks in one axis and stack items in the other axis".

Sebastian

tabatkins commented 8 months ago

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

css-meeting-bot commented 7 months ago

The CSS Working Group just discussed Alternate masonry path forward.

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/w3c/csswg-drafts/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)
nicoburns commented 7 months ago

Regarding masonry-direction: I'd like to propose that this is generalised to box-direction and becomes a shared property that works for both Flexbox and Masonry layout (similar to how grid-gap became gap when support was expanded to Flexbox containers)

stof commented 6 months ago

grid-gap having been generalized as gap for usage in flexbox actually made it impossible to detect support for gap in flexbox with @supports (as the gap property was already supported by browsers implementing Grid with the new property name). So is it a good idea to generalize like that ?

nicoburns commented 6 months ago

grid-gap having been generalized as gap for usage in flexbox actually made it impossible to detect support for gap in flexbox with @supports (as the gap property was already supported by browsers implementing Grid with the new property name). So is it a good idea to generalize like that ?

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.

stof commented 6 months ago

@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 box-direction gets implemented by a browser implementing Masonry without adding support for it in Flexbox (leaving no way to detect the missing support of Flexbox with box-direction).

Properties shared between multiple layouts would require these rules to be feature detectable properly:

However, I have no idea how realistic enforcing those is.

margin and padding were there before the introduction of the various layout modes (at least the ones that came at a time where compatibility with @supports makes sense), so supporting them was part of the initial spec of those layouts. And aspect-ratio was specified taking into account its impact on all layout modes, allowing to follow the rules above.

nicoburns commented 6 months ago

in case box-direction gets implemented by a browser implementing Masonry without adding support for it in Flexbox (leaving no way to detect the missing support of Flexbox with box-direction).

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:

The issue would be detecting the support in Flexbox, in case box-direction gets implemented by a browser implementing Masonry without adding support for it in Flexbox (leaving no way to detect the missing support of Flexbox with box-direction).

What would be the use case for this? If you want to support older browsers that don't support box-direction with flexbox then you would need to set both box-direction and flex-direction. And there would be no point in doing this conditionally which would just add more code to do the same thing (as CSS will ignore properties it doesn't understand anyway).

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 @supports somehow.

fantasai commented 3 weeks ago

We flagged this for the agenda in order to have a discussion of the pros and cons of building masonry into Grid vs creating a new display type, and hopefully resolve on one direction or the other. There's a multitude of different considerations, but some of the key ones have been outlined above and in https://github.com/w3c/csswg-drafts/issues/10233; they include

This issue about the overall direction of the layout model is blocking FPWD and general progress on this feature.

alisonmaher commented 3 weeks ago

The Microsoft Edge team has spent time investigating the current Masonry proposal as outlined in the Grid specification, and we have compared this with the proposal Ian has laid out in this issue. In summary, moving Masonry to its own display type would be our recommended path forward for the reasons outlined below.

The first reason is that we believe there are core aspects of Masonry that are philosophically distinct from Grid:

  1. As defined in the Grid spec, placement must come before sizing. Masonry breaks this principle by requiring the auto placement algorithm to have the resolved contribution size of a grid item before placing it.

  2. In Grid, the grid areas are defined by the intersection between grid lines in the columns and row axis. However, in Masonry the grid lines are only honored in the grid axis. In the masonry axis, there are no grid lines; these are instead determined by the “running position” of each track in the grid axis.

    • This is significant implementation-wise because determining alignment in the masonry axis will require a separate set of data structures to compute the running positions and perform layout than is needed in Grid today.
  3. Given points 1 and 2 above, the implementation of Masonry within the Grid Module will require large chunks of divergences in code, which helps indicate to us that Masonry makes more sense as its own display type.

  4. Subgrid is overkill for Masonry layout.

    • A very tricky scenario to nail in Subgrid is having mixed subgridded and standalone axes (i.e. having a subgrid with subgridded columns/standalone row, with a nested standalone columns/subgridded rows, etc). This scenario is very tricky because figuring out which subgridded items are considered for sizing in each axis involves complex logic.
    • As the css-grid-2 spec states, the grid sizing algorithm requires drilling down per axis into subgrids, rather than completing both axes as it recurses.
    • These two points can be severely simplified in Masonry, since we can only utilize subgrid (or its equivalent in display: masonry) in the grid axis.
  5. There is at least one feature in Grid that doesn't make sense in Masonry (grid-template-areas) and one feature in Masonry that doesn't make sense in Grid (masonry-auto-flow).

The next major category that we find to be a drawback to keeping Masonry as part of the Grid spec is the performance implication. The proposal outlined to address the placement/sizing mismatch in https://github.com/w3c/csswg-drafts/issues/8206#issuecomment-1710169743 could result in approximately quadratic performance, even in very simple cases.

Webkit’s initial attempt to implement this proposal (Masonry isn't performing intrinsic sizing correctly. by stwrt · Pull Request #27048 · WebKit/WebKit (github.com)) doesn’t, from our reading of the code, implement this in a way that showcases the full performance implication. For example, items that span multiple tracks don’t seem to be considered in Webkit’s implementation.

More specifically, consider grid-template-columns: 100px auto auto auto 50px, an item with width: 100px spanning 3 columns has 3 different possible contributions to the 3rd track. If it's placed at the beginning of the 1st track, it will contribute 0px to the 3rd column; if it's placed at the beginning of the 2nd column it will contribute 33.33px; finally, if placed at the beginning of the 3rd track, it will contribute 25px.

Beyond the complexity of implementation, we also feel that Ian’s proposal would be much simpler from an authoring perspective, likely will be easier for authors to understand, while also considering what we believe will be top authoring use cases.

As such, we would like to +1 the proposal to move Masonry to its own display type.

@ethanjv

kizu commented 3 weeks ago

As I did outline in my comment in https://github.com/w3c/csswg-drafts/issues/10233, I will need to find more time to elaborate on why I think masonry could still be a part of CSS grid (but maybe in a less magical form), and how there are many non-masonry cases for one-dimensional grids.

For now, I want to quickly respond to two points:

There is at least one feature in Grid that doesn't make sense in Masonry (grid-template-areas)

There are multiple use cases for template-areas in one-dimensional grids, I did write an article about one of them: “Grid Projection Naming”. If anything, having an ability to have one of the dimensions removed from a grid could allow for more flexible and usable grid-template-areas for such grids.

More specifically, consider grid-template-columns: 100px auto auto auto 50px, an item with width: 100px spanning 3 columns has 3 different possible contributions to the 3rd track. If it's placed at the beginning of the 1st track, it will contribute 0px to the 3rd column; if it's placed at the beginning of the 2nd column it will contribute 33.33px; finally, if placed at the beginning of the 3rd track, it will contribute 25px.

I really think that spanning items should not contribute to the width of the columns in masonry. Even in a regular grid this is the behavior that I find unnecessary and often harmful, and I don't think there are many legit use cases for wanting this in a masonry layout. As an author, when I want some element to span other columns/rows, I want it to adapt to whatever there is, not to contribute. (After writing this, I found https://github.com/w3c/csswg-drafts/issues/10053 which talks about this point, I'll copy this part there.)

fantasai commented 3 weeks ago

@alisonmaher A few quick points:

  1. [...] This is significant implementation-wise because determining alignment in the masonry axis will require a separate set of data structures to compute the running positions and perform layout than is needed in Grid today.

  2. Given points 1 and 2 above, the implementation of Masonry within the Grid Module will require large chunks of divergences in code, which helps indicate to us that Masonry makes more sense as its own display type.

How you split up your code and how we split up display do not need to match (and in many cases don't). That's an implementation detail. Whether we go with "masonry in grid" or "masonry as separate display type", an implementation could choose to share the implementation in their GridFormattingContext module or split out into separate GridFC/MasonryFC modules. This isn't something that should play into our decision here, which should be guided by what's the best interface for authors.

  1. There is at least one feature in Grid that doesn't make sense in Masonry (grid-template-areas) and one feature in Masonry that doesn't make sense in Grid (masonry-auto-flow).

This is true, but I think those two properties aren't it. :) grid-auto-rows/columns and masonry-threshold are the two properties that don't cross over; grid-template-areas works fine and is usable in Masonry, and there's an issue open (https://github.com/w3c/csswg-drafts/issues/10231) on merging masonry-auto-flow and grid-auto-flow which may make that point moot.

tabatkins commented 3 weeks ago

tldr: We think the performance characteristics of the current Grid-based Masonry spec are unshippable, and more or less unfixable while the two layout modes are entwined. But we think we can get a lot closer to agreement on the feature set than it appears the editors currently believe, if we can agree to make this a separate display type. In particular, every single one of the examples in the recent Safari blog post is completely fine in our preferred approach (despite the blog post asserting they aren't, because it's arguing against a much simpler version). See the very end for our alternate proposal; the rest of this is arguments for why we don't like the current and want something different.


The "masonry" behavior is currently defined directly on top of Grid, as a variant behavior similar to "subgrid". We (the Chrome and Edge team's engineers) find the feature valuable and want it to progress, but have come to the conclusion that this is not the right way to define this behavior.

Some of these issues were brought up back in 2022, in issue 8206. In July 2023, in Issue 9041, we raised the concern more generally, and suggested an alternate approach. Since then we've opened several additional issues about more specific concerns with the current approach (or had them opened, spinning out specific concerns from 9041):

These issues can generally be reduced to a single conflict: at their most fundamental level, Grid and Masonry are opposite wrt sizing and placement. Grid places all items before layout, and then has complete knowledge of what items are in any given track, so it can do complex intrinsic sizing based on that knowledge. Masonry places items as they're laid out, and thus it cannot know what elements will end up in any given track, and can't do the same complex intrinsic sizing (but as a result gains the potential for some behavior that Grid can't easily accommodate).

fantasai has attempted to address these concerns, by defining special "pre-placement" layout behavior - laying out each item in every possible position to obtain intrinsic measurements, and then using those measurements to size the tracks before starting placement. However, this doesn't fundamentally fix the issues, it just changes what the behavior is quadratic on: rather than being quadratic on the number of items, the complexity scales with (number of items) * (number of tracks). The exponential behavior from nesting grids also remains under this behavior. Also, this is still fundamentally different from what Grid does, raising the question of why they're considered the same layout mode when they use such different layout algorithms.

Given that we know authors like to push the boundaries of layout modes, and in particular often create grids with a very large number of tracks (sometimes to produce something like Masonry layout, but not always), we don't think this fix is acceptable. We extra don't believe exponential layout behavior is acceptable, as it causes layout to visibly stutter quickly, with only a handful of reasonably-sized grids involved. All of these can be avoided with some reasonable restrictions that we think still allow a wide range of useful Masonry behaviors, but which would be awkward to apply in the general Grid framework.

Additionally, as stated in Issue 9321, we think there are some useful behaviors that Masonry can allow that are infeasible to apply to Grid, such as repeat(auto-fill, auto). (Doing so in Grid causes essentially the same issues that were described for Masonry, above.)

Finally, we have a general design objection to attempting to merge Masonry and Grid into a single layout concept. The two layout modes absolutely have many conceptual similarities, and we can and should lean on those to ensure that they can work well together in obvious ways, but each has enough unique peculiarities that it just gets awkward to define what works for Grid, what works for Masonry, and what works for both. I believe this situation to be similar to that of Block and Multicol - these were folded into a single layout mode, and ever since we've had to deal with odd inconsistencies between the two in what behaviors they expect. If we had defined display: multicol back in the day, many issues would have been avoided. I think the Grid/Masonry marriage is even more fraught with inconsistencies - heck, they fundamentally don't and can't share a layout algorithm - and would like to avoid us repeating mistakes we made in the past. As we move forward, every new addition to Grid and Masonry will have to be evaluated to see if it applies to one or both modes, and when it applies to both, what distinctive quirks it has in each.


So the above is our general objections to the current approach, and address fantasai's first and third bullet points (whether Masonry fits in Grid conceptually, and whether integrating the two models is a pro or a con). I'll go a little more into detail about these in a sec, but first, let's discuss their second bullet point (whether track size variation is needed/useful, and how we can deal with the perf implications).

As we've stated before, existing JS masonry implementations don't generally seem to offer the ability to do distinct track sizes - all tracks the same width seems to be the overwhelming common case. That said, having differently-sized tracks does seem reasonable; Jen's blog post on Friday had a bunch of good examples.

There's a lot more flexibility between "all tracks the same" and "any intermixing of tracks like Grid can do", tho, and we think there's a reasonable sweet spot that allows a lot of useful cases without running into the perf issues we find so objectionable.

Basically, the perf issues arise only when you mix an intrinsically-sized track with any different-sized track.

In other words, every example given in Jen's blog post is just fine. Those are all totally doable, no objections here. We just object to the possibility of writing, say, grid-template-columns: 50px auto 100px;, because in degenerate cases (which are more common than one would suppose), they cause quadratic or even exponential layout behavior.


Now back to bullet point 3 - is integrating the two models a pro or a con.

We think the cons outweigh the pros. There are simply too many places where some property is only valid for one or the other, or worse, some values for a shared property are only valid for one or the other. Above I outlined why a perfectly valid grid-template-columns would be problematic for Masonry, but on the other side, Masonry is perfectly fine with allowing masonry-tracks: repeat(auto-fill, auto), which is so disallowed in Grid that it's a syntax error. These sorts of syntax distinctions are easier to understand and remember when they're across similar but separate properties; when it's a single property that just has a different mix of valid values depending on the value of a second property, it gets confusing. And we don't think it's reasonable to expect authors to develop an intuitive understanding of this; the reasons for some values being usable in Grid vs Masonry depend on fairly deep layout-engine knowledge that we don't generally expect authors to possess.

(We'd also have to define what happens when they do write the wrong thing. We can't reject it at parse time, since its validity depends on the computed value of another property. We'd have to guess at some fallback behavior. This is already present in the spec, with auto-fit being invalid in Masonry, and treated as auto-fill instead. It would be better if this could be rejected at parse time.)

Both layout modes have properties that don't apply to the other: grid-auto-* for Grid, masonry-threshold (and masonry-auto-flow, if we keep that).

Worse is grid-template-areas, which could conceptually apply to Masonry (giving names to tracks or groups of tracks), but can't in practice because of the 2d nature of the syntax. We'd have to define a masonry-areas to port the concept over.

The end result is that authors have an arbitrary-feeling list of restrictions in what properties can be used for one or the other - properties with a masonry- prefix obviously only work for Masonry, but some grid- properties work too, and others don't, and for the ones that do work, sometimes only certain values work. If they were more cleanly separated layout modes, with all the Masonry properties having a masonry-* prefix even when they're similar to Grid properties, none of this is a concern.


Finally, back to bullet point 1, whether Masonry and Grid fit together conceptually. We agree that they do! Many concepts are shared between them, and Jen's example of subgrid in masonry looks completely reasonable. We think that allowing subgrid items to take on a Masonry parent's lines is perfectly reasonable, with the caveat that the subgrid items interact with the Masonry track sizing in a Masonry-like way (as described above, for the case where the Masonry is using a repeated intrinsic track size; when the tracks are fixed/flexible, the issue's moot already). Similarly, if we defined some sort of "submasonry" value, using those in Grid parents would be reasonable, with similar restrictions on how they interact with Grid sizing.

And generally, for any concept for which Grid and Masonry share the idea, they should both have properties for it, with as identical of a syntax as possible. Helping authors transfer knowledge between the two layout modes is absolutely a good idea.


So, long post, apologies, we're at the end. Here is a very rough sketch of the proposal as we'd prefer to see it. I'm happy to spend time putting together a UD for this if it's easier to review that way, I just didn't have time to do so.

/* on the masonry container */
display: masonry;

masonry-template-tracks: [ <line-names> ? [ <fixed-or-flexible-size> | <fixed-or-flexible-repeat> ] ]+ <line-names>? ]
        | [ <line-names>? <intrinsic-repeat> <line-names>? ]
masonry-template-areas: (like one row of grid-template-areas)
masonry-direction: row | column | row-reverse | column-reverse
   /* initial value column, contrasted with flexbox's initial row */

justify/align-*: (same as Grid, but with some restrictions depending on masonry-direction)

masonry-threshold: [(as discussed in 9328)](https://github.com/w3c/csswg-drafts/issues/9328)
masonry-auto-flow: (as in the current spec)

/* on the masonry items */
masonry-track: <grid-line> [ / <grid-line> ]?
masonry-track-start: <grid-line>
masonry-track-end: <grid-line>

justify/align-*: (same as above)

We're flexible on all the details, save for those I talked about in the preceding text of this comment.

tabatkins commented 3 weeks ago

grid-template-areas works fine and is usable in Masonry

I don't agree that it works "fine". It works, in theory, but it's awkward to use and allows you to write things that don't make sense in a Masonry context.

"awkward" because you have to do something completely different if the masonry has columns vs rows. When it's columns, you just write grid-template-areas: "foo bar baz";, easy, but when it's rows you have to write grid-template-areas: "foo" "bar" "baz";.

Similarly, and perhaps worse, if you use grid-template so you can size and name the tracks at the same time, the sizing values go in completely different places, as does the masonry keyword: grid-template-areas: "foo bar baz" masonry / 10px 20px 1fr; vs grid-template-areas: "foo" 10px "bar" 20px "baz" 1fr / masonry;.

And "don't make sense" in that you can write grid-template-areas: "foo foo" "bar bar"; to define a 2x2 explicit grid, but Masonry has, at best, an Nx1 (or 1xN) explicit grid. We'd have to ignore all but the first track in one of the axises, rather than being able to reject that at parse time as a syntax error.


and there's an issue open (https://github.com/w3c/csswg-drafts/issues/10231) on merging masonry-auto-flow and grid-auto-flow which may make that point moot.

I think this would, similarly, be a bad idea. Masonry and Grid have slightly different things that they care about for auto flowing controls; if we put them both in the same property, we either have to bodge the different behaviors into the same keywords even when they're not ideal, or define layout-specific keywords and give them some fallback behavior when they're specified for the wrong layout. Again, being able to reject bad syntax at parse time is better.

alisonmaher commented 3 weeks ago

How you split up your code and how we split up display do not need to match (and in many cases don't). That's an implementation detail. Whether we go with "masonry in grid" or "masonry as separate display type", an implementation could choose to share the implementation in their GridFormattingContext module or split out into separate GridFC/MasonryFC modules.

Sure, this is an implementation detail. However, the implementation details we called out are a direct reflection of how the spec for Masonry is designed today. If we are having to diverge on very core aspects of an algorithm, the point still stands that this is a good indication that they are distinct enough concepts to separate (whether or not there are other concepts we can reuse between the two).

This isn't something that should play into our decision here, which should be guided by what's the best interface for authors.

Implementability should be discussed when the implementation is derived from the algorithm outlined in a spec. And the performance implications in particular would have a direct impact on authors/end users.

This is true, but I think those two properties aren't it. :) grid-auto-rows/columns and masonry-threshold are the two properties that don't cross over; grid-template-areas works fine and is usable in Masonry, and there's an issue open (https://github.com/w3c/csswg-drafts/issues/10231) on merging masonry-auto-flow and grid-auto-flow which may make that point moot.

Gotcha, yeah these might be the right properties to be discussing, and I'm glad to hear it is something we are looking into. However, given that that issue is not resolved, it is still a valid point to consider when discussing the larger question at hand in this issue.

css-meeting-bot commented 3 weeks ago

The CSS Working Group just discussed Alternate masonry path forward.

The full IRC log of that discussion <schenney> fantasai: topics: can masonry replace grid, track info, interaction of masonry-grid. For authors? For spec?
<fantasai> scribe+
<fantasai> scribe+ schenney
<fantasai> -> https://github.com/w3c/csswg-drafts/issues/9041#issuecomment-2071086963
<schenney> fantasai: Q? Use case for variable track sizes. It not neceaary, all sorts of objections due to complexity. Jen SImmons has demos to present and talk through.
<fantasai> ->
<TabAtkins> q+ for after the demos
<fantasai> jensimmons: We're hoping to make real progress on this question, it's been 4 years since this question first came up
<bts> Link to demo: https://webkit.org/demos/grid3/photos/
<fantasai> jensimmons: the demos are online
<fantasai> -> https://webkit.org/demos/grid3/photos/
<fantasai> jensimmons: Photos demo is a good start. If we show numbers you can see multicol layout, where the images go down the first column, then second, etc.
<fantasai> jensimmons: for this content it's ok, other content it's not great; but also it doesn't allow loading additional content to the bottom
<fantasai> jensimmons: if you use grid L1, it lines up in both row and column. If aspect ratio isn't uniform, doesn't look great
<fantasai> jensimmons: masonry gives a chance to lay things out going across the top of the columns, and then keep going across filling the shortest colun
<fantasai> jensimmons: it builds into grid easily, can specify any set of columns you want and then set rows to 'masonry'
<fantasai> jensimmons: basically turns the rows off
<fantasai> jensimmons: There are other things you can do with grid, because full power of grid-template-columns
<fantasai> jensimmons: in this demo, first and last cols are fixed sizes, and the iddle columns 1fr, and number of columns scales with width of window
<fantasai> jensimmons: next demo, all columns are flexible but we have narrow and wide columns
<fantasai> jensimmons: and always starts and ends with a narrow column
<fantasai> jensimmons: the basic masonry layout is popular because JS can only do so much, but building into CSS can do a lot more
<fantasai> jensimmons: spanning in grid allows some interesting possibilities, e.g. every 5th item is wider here. Gives more graphic design interest.
<fantasai> jensimmons: in this version made the landscape photos wider
<fantasai> jensimmons: [shows horizontal masonry demo]
<fantasai> jensimmons: Mega menus are another use case
<fantasai> jensimmons: multicol would go down the columns, but masonry allows to lay out the first items across
<fantasai> jensimmons: Text becomes more interesting also.
<fantasai> jensimmons: a lot of websites lay out teaser content by fitting the content to the regular boxes
<fantasai> jensimmons: often by trucating it
<fantasai> jensimmons: keep everything the same aspect ratio, creates a very modernist grid
<fantasai> jensimmons: this is why graphic design can feel boring on the web
<fantasai> jensimmons: classic masonry allows more flow of content, but still somewhat rigid
<fantasai> jensimmons: start applying different widths and spans, create very interesting layouts
<fantasai> -> https://webkit.org/demos/grid3/photos/
<fantasai> jensimmons: this last demo is classic masonry, but grid allows some extra possibilities
<fantasai> jensimmons: the header/sidebar can be shifted to the other side using explicit placement
<fantasai> jensimmons: or use subgrid to align metadata across cards
<lea> +1 for letting Jen finish. This is important, we can spend 5 more minutes on it. Also, talking about timeboxing came close to taking more time than the actual presentation.
<fantasai> jensimmons: subgrid is powerful here
<fantasai> jensimmons: questions?
<fantasai> jensimmons: As I wrote in the article, this is about saying "hey, we've got grid -- but what if we let go of the idea that it's only modular grids?"
<fantasai> jensimmons: columnar grids are grid systems, historically in graphic design
<fantasai> jensimmons: this just lets us turn off rows (or turn off columns)
<florian_irc> q+
<fantasai> jensimmons: and contents pack together
<astearns> ack emilio
<Rossen__> q?
<fantasai> ?: is this display: block grid?
<Rossen__> q?
<fantasai> jensimmons: no inlines, this is just 'display: grid'
<fantasai> s/?/Keith/
<lea> q+
<fantasai> TabAtkins: I posted a long comment to the issue about an hour ago. Long because I went into our reasoning, but can read tldr and proposal
<fantasai> TabAtkins: summary of our position, we the Chrome+Edge engineers find the current spec unshippable given the algorithm in it
<dbaron> https://github.com/w3c/csswg-drafts/issues/9041#issuecomment-2075210820
<fantasai> TabAtkins: it can trigger quadratic or exponential behavior, which could brick the page
<fantasai> TabAtkins: we acknowledge they are edge cases
<fantasai> TabAtkins: The restrictions we need are not ones that Jen's demos hit
<fantasai> TabAtkins: We just need to restrict to either a) fixed or flexible tracks OR b) intrinsic tracks
<fantasai> TabAtkins: every demo presented works in those constraints
<fantasai> TabAtkins: problem only happens when you can mix intrinsic track with other types of track sizing
<florian_irc> q- later
<fantasai> TabAtkins: because that's when spanners start to contribute differently in different racks
<Rossen__> ack TabAtkins
<Zakim> TabAtkins, you wanted to discuss after the demos
<fantasai> TabAtkins: On a more conceptual level, we thing there's a number of friction points where the syntax is suboptimal because designed for 2D grid
<fantasai> TabAtkins: or concepts don't directly translate and need to default values instead of rejecting at parse time
<fantasai> TabAtkins: e.g. auto-fit is treated as auto-fill
<fantasai> TabAtkins: However, we thing there's also significant conceptual similarity to grid. It has tracks, lines, etc.
<fantasai> TabAtkins: so should do as much connection between the two
<fantasai> TabAtkins: e.g. have subgrid take lines from a parent, assuming we have fixed sizing bits
<miriam> q+
<fantasai> TabAtkins: Similarly submasonry value, taking lines from parent
<florian_irc> q- later
<fantasai> TabAtkins: Everywhere they interact, make it easy to translate knowledge. But they're still not the same thing, and enough pain points that they should be done in different display types
<lea> Lea: These demos are impressive, and this is solving real author pain points.
<lea> Lea: I did have some reservations about how this combines with multicol from an author point of view, but I think I'm now convinced this makes sense as a part of grid.
<fantasai> scribe+ lea
<Rossen__> ack lea
<dholbert> TabAtkins' github comment with more details: https://github.com/w3c/csswg-drafts/issues/9041#issuecomment-2075210820
<lea> Lea: One thing is that the `masonry` keyword seems a little magical. How can authors set constraints on the min and max size of these generated rows/columns? How does it interact with `grid-auto-flow`?
<fantasai> Lea: e.g. what about 'dense' keyword?
<florian_irc> q-
<fantasai> miriam: Agree quite a bit with Lea. Agree we like this as part of grid. Syntax feels right.
<fantasai> miriam: would like to add a few more constrainst
<Rossen__> ack miriam
<fantasai> miriam: get that there's some constraints on implementation
<jensimmons> q+
<fantasai> miriam: Looking at separate masonry proposal, seems like new terms for similar things
<fantasai> miriam: why do I need to learn new terms for the same thing?
<fantasai> miriam: I also might want to switch between grid and masonry at different break points
<fantasai> miriam: keeping them together makes it a lot easier to do
<lea> +1 to miriam great point about switching to/from masonry
<schenney> scribe+ schenney
<fantasai> miriam: I like the grid syntax if we can make it work
<Rossen__> ack fantasai
<Zakim> fantasai, you wanted to respond to Lea's questions
<ydaniv> q+
<schenney> fantasai: Reponse to Lea. I don't iunderstand min/max rows columns. Maybe explain later.
<florian_irc> q+
<schenney> fantasai: Dense, autoflow maybe mergable from ? and ?
<Rossen__> ack jensimmons
<rachelandrew> q+
<fantasai> jensimmons: We put this out to designers and developers to see what kind of feedback we would get
<schenney> jensimmons: Get it to developers. See what feedback.
<fantasai> jensimmons: overwhelmingly people want to see this as part of grid. It's not 100%, but on issue in CSSWG it's roughly 80/20 in favor of building into grid.
<fantasai> jensimmons: authors prefer making it part of what they're already familiar with, already learning, as part of CSS Grid
<fantasai> ydaniv: +1 to what miriam said before
<Rossen__> ack ydaniv
<fantasai> ydaniv: thinking about interpolation, animating to/from masonry and grid
<fantasai> ydaniv: could be easier inside grid than between display types
<dholbert> q+
<TabAtkins> wrt the author feedback, note that the blog post argued exclusively against an overly simplistic model (only fixed-size, identical tracks, a la multicol). Every demo was showing how we need more than that. As I said, tho, every demo is perfectly fine; the actual restrictions we need are much more subtle. We can't take support for "what the blog post displayed" as arguments for "build it into Grid".
<lea> q+ to ask how does this work with explicit col/row placement?
<fantasai> florian_irc: Thanks Jen & team for the demos, and also for presentation. I had skimmed the blog but realized more things during presentation
<fantasai> florian_irc: more compelling
<fantasai> florian_irc: wrt Google proposal posted recently, seems it's fuller than what was originally discussed
<fantasai> florian_irc: I think we need more time on this topic, and discuss the differences between the two
<Rossen__> ack florian_irc
<Rossen__> ack rachelandrew
<fantasai> rachelandrew: WebKit team presented to developers saying the only way is to have grid implementation, and I don't think that's the case as Tab outlined
<fantasai> rachelandrew: but when I first started showing people Flexbox and Grid, people would say "it's inconsistent", because it was different from block layout
<fantasai> rachelandrew: at this point we have good understanding of formatting contexts
<fantasai> rachelandrew: my worry as someone who teaches this is, if we put masonry in grid we have to say "these properties only work in grid that's not masonry" or "these properties only work in grid that is masonry"
<florian_irc> s/more time on this topic/more time on this topic soon/
<fantasai> rachelandrew: if we build into a separate display type, can still have a lot of cool stuff, but not dancing around the differences
<Rossen__> ack dholbert
<fantasai> dholbert: we have a prototype implementation of masonry in grid
<florian_irc> s/more compelling/more compelling, and really makes the case for needing these capabilities
<fantasai> dholbert: I'm sympathetic to the performance considerations of every item in every track
<fantasai> dholbert: agree with sharing a lot of the same behavior with grid
<fantasai> dholbert: using a restricted form of track syntax but compatible for masonry, that's only possible to do by using a different set of property names
<Rossen__> ack lea
<Zakim> lea, you wanted to ask how does this work with explicit col/row placement?
<fantasai> lea: How does masonry work with explicit grid placement?
<Rossen__> ack fantasai
<schenney> fantasai: If you specify specific track, maonsry item goes there.
<schenney> fantasai: Just like grid etc, move to that position and keep placing.
<Rossen__> q?
<schenney> florian_irc: Do you ignore a dimension?
<schenney> fantasai: Yes.
<TabAtkins> + there's a switch in masonry-auto-flow about whether to place all the explicit items first (like Grid does) or in the normal order.
<fantasai> Rossen__: Good discussion, let's review comments and come back to it later.
<lea> big +1 for integrating masonry-auto-flow with grid-auto-flow if this becomes part of grid
<astearns> let’s keep posting and conversing in the issue - please do not wait until we can schedule more call time
fantasai commented 3 weeks ago

Implementability should be discussed when the implementation is derived from the algorithm outlined in a spec. And the performance implications in particular would have a direct impact on authors/end users.

Yes, these are valid things to consider: whether it can be implemented, and what performance characteristics it has. But whether it ends up being one module or two in your implementation... that's not an important consideration for whether it should be one display type or two. How you organize your code is not a consideration for how CSS should organize its interface for authors.

tabatkins commented 3 weeks ago

I mentioned a few friction points when trying to do Masonry in Grid, but didn't go into great detail. Here's a more complete list ^_^

Friction Points with Masonry-in-Grid


Conversely, if Masonry is a separate layout mode with masonry-* properties, you do have some degree of repetition, but in every case, the value spaces are somewhat different, so having the distinct syntaxes be distinguishable at parse time is a good thing.

I think that, in every one of these cases, the benefit from having their differences being detectable at parse-time is worth more than the downside of having their overlap be duplicated between the two properties.

rachelandrew commented 3 weeks ago

I talked about this on the call, but when I first starting showing people flexbox and grid, a very frequent comment was that they behaved inconsistently. What they meant was that they behaved differently to their assumptions about how things behave in block layout. At this point, I think we've been able to get a reasonable understanding of what it means to change formatting content across to developers. For example, to understand why certain alignment properties don't apply in flexbox.

If we bundle masonry with grid, I fear we end up with a situation where we have to say "these properties/values work in a grid formatting context but not if you are using masonry" or "these only work if you are in a grid formatting context AND using masonry". That's not just things that exist today (such as the alignment properties), but anything we might want to add in the future.

As Tab mentioned above, we can reuse a lot of grid things in display: masonry, we don't lose all the things Jen has shown in her demos because we define it as a new spec, but we also don't end up dancing around the differences forever.

kbabbitt commented 3 weeks ago

+1 to Tab's and Rachel's comments.

A theme I saw in the developer feedback thread is that integrating masonry into grid would build on existing knowledge of grid syntax and simplify some fallback cases. I agree that, for an author who has mastered CSS Grid, switching in one masonry keyword is simpler than having to rename declarations and add an @supports for fallback. I don't see anything in Tab's proposal that would hinder the knowledge transfer at a conceptual level, though.

I'd like to advocate instead on behalf of new authors who want to jump straight into building a masonry layout. Which of the following would represent the lowest barrier to entry?

  1. Start from a spec defining the syntax only for additions to Grid that make Masonry work, then back-fill the missing assumed knowledge about Grid from elsewhere.
  2. Start from a spec defining the syntax for the union of everything possible in both Grid and Masonry, then digest additional prose to understand which of those options apply to Masonry.
  3. Start from a spec defining the syntax only for what's possible in Masonry and nothing else.

In my opinion, the benefits of 3 to new authors in setting aside advanced Grid features until they're needed, outweigh the inconveniences to experienced authors, who presumably are already used to dealing with different property names for different contexts and having to implement graceful fallback.

nicoburns commented 3 weeks ago

One option could be to selectively merge style properties. It is my opinion that merging has worked well in the past in some cases (gap working across both Flexbox and Grid being a good example) but badly in others (IMO the attempt to abstract away axis by using "align" and "justify" for alignment properties was a mistake: this is something which frequently trips up people I try to teach web layout to and even turns them off authoring for the web entirely and I think clearer property names using "block", "inline", "main", "cross", "rows", "columns" would have made a big difference).

We could for example rename grid-template-columns to just columns, indicating that it applies across both classic Grid and Masonry contexts. While leaving grid-template-areas as it is, indicating that it applies only to grid. Perhaps that then nudges us towards a separate display: masonry value. Although I think is possibly less important. There is certainly precedent for multiple similar display modes using separate keywords though (e.g. block and flow-root).

astearns commented 3 weeks ago

(speaking as a member, not the chair)

On the point of making it easier to switch between Grid and Masonry at different break points, I am not convinced that keeping Masonry in Grid helps this. I expect that various track, template and area settings would likely also need to be switched at the break points, so you would be setting several properties in your break point queries.

If there is a separate set of masonry- properties, you could set everything up for both masonry and for grid, and just have your query do the display switch. Tweaks on the separate grid- and masonry-* properties would only affect one layout and not need to be tested on the other. I think this might be more helpful overall than where it would be useful (or possible!) to use the same property value for both Masonry and Grid.

nicoburns commented 3 weeks ago

I would also like to strongly advocate for the performance characteristics (and specifically of the default or easy to use styles) being strongly weighted in the debate (to the point that poor performance should be considered a deal breaker).

Performance is already a problem for CSS layout (with both Flexbox and CSS Grid having exponential complexity (albeit reducible with caching) unless one goes out of one's way to use styles like min-width: 0px on all flexbox items and minmax(0, 1fr) instead of 1fr for grid tracks). And I would like to see this fixed rather than new performance issues introduced. If that means intrinsic sizing of masonry columns being excluded entirely then so be it.

tabatkins commented 2 weeks ago

@nicoburns Merging gap worked because flex-gap and grid-gap were identical; absolutely zero differences in syntax. It was solely a difference in property name. Same for the *-self/items/content properties; exactly which set of properties apply varies between layout modes, but when they do apply, they use the same values. (I was skeptical of this when @fantasai first suggested merging the Flex and Grid alignment properties, but I was wrong!)

(Agreed on the naming, tho - we made a mistake in Flexbox in making it too flex-direction centric rather than just sticking with logical directions, and that hampered our ability to use logical-direction names. They absolutely should have been block-align-self/etc.)

However, as I pointed out at the end of my previous comment, this isn't true for Masonry/Grid. Almost none of the overlapping properties have the same syntax - as far as I can tell, the only ones that do are the placement properties (grid-row, etc), minus grid-area. Every single other overlapping property has some syntax space that's valid only for Grid, or only for Masonry, or both.

ydaniv commented 2 weeks ago

I think it's worth strengthening @tabatkins' point about ability to accept/reject at parse time. This means that dev tools will be able to suggest/highlight values immediately, and greatly improves discoverability. It would be nice if new syntax we add is statically checkable, and it may reduce friction.

Regarding my comment on animation at the meeting, I guess we could always have View Transitions as last resort.

astearns commented 2 weeks ago

(chair hat off still, this is just me trying to make sense of the options)

Assumptions and caveats:

Masonry + Grid together

Pros:

Cons:

Masonry as a separate display type

Pros:

Cons:

By “new properties” I mean things that aren’t yet in Grid or proposed for Masonry. If the new thing works identically in both modes then the property duplication for the separate display types is annoying. But it’s also not great if a new single property has to have a mode switch designed into it.

From a “designing future extensions to grid/masonry” standpoint I think I am favoring a separate display type.

romainmenke commented 2 weeks ago

New properties must be designed to accommodate both modes

And this must be done when new properties or values are first introduced. We can't add something new for Grid and only later figure out its use for Masonry.

bramus commented 2 weeks ago

And this must be done when new properties or values are first introduced. We can't add something new for Grid and only later figure out its use for Masonry.

Would also make it hard for feature detection, remember gap detection with display: flex.

When using dedicated properties for masonry, you can feature detect support for a certain value separately from grid supporting it.

tabatkins commented 2 weeks ago

More complicated value spaces (some apply only to one mode)

And just to stress on this point - every single Grid property that can apply to masonry, save for grid-row/-start/-end (or -column, depending on direction) has this issue. They all have some values that are only valid for one or the other type. (Documented at the end of this preceding comment.)

GrimLink commented 2 weeks ago

+1 to Tab's and Rachel's comments

nt1m commented 2 weeks ago

@mirisuzanne brought up a good argument in favor of masonry in grid: you might want to have a masonry in a certain @media query breakpoint and a grid in others, while sharing the same tracks. With a separate display type, you have to duplicate all the properties for each breakpoints.

tabatkins commented 2 weeks ago

@nt1m That's possible, but I'm less certain how plausible it really is. Presumably you'd be shifting from an auto-flow grid into a masonry; I'm not sure I really see how common it would be to change from "all rows same height" to "no rows" based on a breakpoint. If you are changing based on a size breakpoint, it seems more likely to me that you're also going to be changing the tracks, in which case it's the same effort either way.

systematixrahul commented 2 weeks ago

Hi, I need any HTMl example of HTML code related to article so I can better understand while I am working HTML conversion by Figma Is it possible to get any working example code to make it easier to understand for future use??

eckmo commented 2 weeks ago

I hadn't noticed the limitations that grid would have in conjunction with masonry, but that alone is a very compelling argument to have masonry as its own display. I think having masonry as a separate display would keep clarity between all of the display types as well, given that they do all seemingly handle different dimensionality. Given this method vs the Webkit method I'd prefer this. Thanks for the thoughtful breakdown!

astearns commented 2 weeks ago

(chair hat on)

In the interests of arriving at a decision, is there anything in the conversation so far that convinces the “separate display type” folks that integrating with Grid is the better path forward, or that convinces the “integrate with Grid” folks that a separate display type is the better path forward?

(bonus points if equal numbers of people switch camps)

Loirooriol commented 2 weeks ago

For what it's worth, I was initially neutral but the reasonings provided by the "separate display type" folks have convinced me that option seems better.

Que-tin commented 1 week ago

Quoting @astearns:

Masonry + Grid together

Pros: No duplicate properties for similar sorts of things You can reuse most of what you know about Grid in Masonry

Cons:

More complicated value spaces (some apply only to one mode) New properties must be designed to accommodate both modes

Masonry as a separate display type

Pros:

Less complicated values (each mode has only what it can use) New properties are less complicated to add

Cons:

Duplicate (or very similar) properties need to be added New properties can add to the duplication

Stepping away from the discussion a bit, I feel like this:

Less complicated values (each mode has only what it can use)

is the most important argument of all. Masonry has no value at all if developers don't adopt it, and I feel like the chances are much higher with a strictly defined syntax. As a speaker and someone who gives workshops on a regular basis, I still run into people who don't understand grid and are still only using flexbox. Blowing up the grid spec even more would exacerbate this problem.

New features (afaik) are introduced for the users - the web developers - and therefore should have the main focus on them to help solve their problems and therefore come with a good UX (Web Developer Experience). Going with Masonry + Grid together feels like we are shifting towards a better DX (Spec Writers - Browser Vendors) at the expense of worse UX by increasing complexity by introducing new edge cases into the spec and thus decreasing the adoption rate.

I feel like I was kind of repeating myself, but I hope you get my point - Take a step back and don't forget who we're introducing this feature for.

chrisarmstrong commented 1 week ago

@Que-tin

I still run into people who don't understand grid and are still only using flexbox. Blowing up the grid spec even more would exacerbate this problem.

You could also argue that this is due to Grid being an entirely new thing for them to learn, in which case keeping Masonry separate only adds to that problem?

chrisarmstrong commented 1 week ago

For me, this all boils down to the question of whether CSS syntax should be based on "What" it's doing, or "How" it's doing it.

When I say background: black, then switch it to background: linear-gradient(45deg, black, white), it doesn't matter to me HOW the browser is implementing that instruction... I’m simply telling it what I want it to look like. If the browser has to switch to an entirely different rendering approach to implement that instruction in a performant way, that’s a problem for the browser dev, not the CSS dev.

Creating display: masonry as a totally separate thing because of implementation concerns feels like it goes against this principle... it’s making me think about HOW the browser will perform my instructions, rather than WHAT I want it to do.

However I can appreciate the arguments on both sides, and ultimately I care more about getting SOME form of this I can use than I do about getting perfect syntax. Heck, the flexbox syntax* still confuses me (I never know whether I want justify or align) but I’m still really glad we have it.

*Possibly more a reflection of my lack of intelligence than anything else. To those of you who made it happen: thank you.