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-3][masonry] Masonry Syntax Debate #11243

Open
fantasai opened this issue Nov 19, 2024 · 24 comments
Open

[css-grid-3][masonry] Masonry Syntax Debate #11243

fantasai opened this issue Nov 19, 2024 · 24 comments
Labels

Comments

@fantasai
Copy link
Collaborator

fantasai commented Nov 19, 2024

The CSSWG's masonry layout draft includes two competing syntax proposals for the feature. There has been a lot of discussion between the two, and there's an overview of the debate in the TAG review issue.

Opening this issue to focus on the syntax question, since the previous issue debating two possible models started with focus on the performance implications of mixed track sizing, etc. that are no longer relevant.

Key links (primary in bold):

@fantasai fantasai added Agenda+ css-grid-3 Masonry Layout labels Nov 19, 2024
@astearns
Copy link
Member

A couple of questions for folks to (maybe?) spark some discussion:

  • What is the strongest argument for the option you do not prefer?
  • If you have changed your opinion from one of the options to the other, what was the reason for the change?

@astearns
Copy link
Member

TAG feedback: w3ctag/design-reviews#1003 (comment)

@nathanchase
Copy link

FWIW: I still agree that in isolation, display: masonry makes more sense due to its brevity, but a lot of the points brought up by @jensimmons (https://webkit.org/blog/16026/css-masonry-syntax/) and @shadeed (https://ishadeed.com/article/css-grid-masonry/) convinced me that the overall context shift is higher to create new keywords, recall syntax differences, and set up default values that could potentially have highly unintended results. Particularly, this matrix is compelling:
image

With that in mind, and with the also welcome shift away from using "masonry" as a term and instead leaning on the existing "collapse" keyword already found elsewhere makes a lot more sense for the future.

@kizu
Copy link
Member

kizu commented Dec 4, 2024

If we were to choose from the two options presented, I prefer the “Just use Grid” option.

I have a bigger take on this, which I just can't find an opportunity to write up properly, but the gist is that with masonry we're mixing two things: one-dimensional layouts (without the masonry specifically, as a wider feature), and the masonry auto-placement algorithm. I'd want the first feature as a part of a CSS grid, regardless of the masonry. Then, having one-dimensional grids, introducing an alternative placement algorithm in addition sounds like a reasonable iterative approach.

I am against the display: masonry for the reasons presented by Jen and Ahmad, specifically the fallbacks and conditional adjustments aspects. It is much easier to adjust or create a fallback for something when you don't have to change N different properties at the same time. I would prefer learning a slightly different syntax for specific cases rather than an additional set of slightly different properties.

What is the strongest argument for the option you do not prefer?

I agree with the arguments for the grid-independent option about good defaults and shorthands. However, I can see a future where, instead of putting the current flawed grid aside and giving up on it in favor of a new system, we could see if we could improve what we have. With new keywords added to the mix, they allow us to change the way shorthands behave, and design things better. It is true that authors rarely use the grid shorthand, and that means that we should look into how we could improve it for all the cases.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed Masonry Syntax Debate.

The full IRC log of that discussion <fantasai> Topic: Masonry Syntax Debate
<fantasai> github: https://github.com//issues/11243
<fantasai> alisonmaher presenting from Chromium team
<fantasai> alisonmaher: [intros the topic]
<fantasai> alisonmaher: Several properties behave differently in each, or don't apply, so we think a new display type would be better.
<fantasai> alisonmaher: Plus we can define a better default value for the template tracks, creating an automtical masonry instead of a single column
<fantasai> alisonmaher: Regarding grid fallback, needing one is a temporary problem, so should focus on the future
<fantasai> alisonmaher: authors should make explicit fallback, to avoid surprises
<fantasai> alisonmaher: Positioning in masonry is simpler than grid, it's only placed in 1 axis instead of 2
<fantasai> alisonmaher: Grid is confusing because authors might make a mistake about which axis they are placing in (rows vs columns)
<fantasai> alisonmaher: separate model only has one axis
<fantasai> alisonmaher: this allows switching the axis easily
<fantasai> alisonmaher: Shorthands also are better with separate shorthand. Grid shorthand is complicated, hard to use. Masonry shorthand is easier because don't need to remember the order
<fantasai> alisonmaher: placement works differently in grid vs masonry
<fantasai> alisonmaher: dense packing is also different : for grid can place in any empty slot, but due to perf considerations for masonry current proposal restricts to same-sized track
<fantasai> alisonmaher: masonry also has different intrinsic sizing rules, with auto-placed items affecting all auto-sized tracks not just the one they end up in
<fantasai> alisonmaher: alignment is also very different, open questions about how this works in the masonry axis
<fantasai> alisonmaher: this means grid and flexbox are quite different in how they behave
<fantasai> alisonmaher: in masonry layout auto-placed subgrids don't inherit line names
<fantasai> alisonmaher: we expect there to also be other changes for submasonry/subgrid that will lead to divergences
<fantasai> alisonmaher: Integrating masonry into grid will lead to spec bloat, will be harder to teach, and lead to developer confusion
<fantasai> alisonmaher: Conclusion: masonry should be a separate display type
<fantasai> jensimmons: [intro slide]
<fantasai> jensimmons: At this point decision is about syntax -- mental model. Behavior is same in both.
<fantasai> jensimmons: [reviews basic case]
<fantasai> jensimmons: Choice to Just Use Grid is extending Grid L1. [shows example of grid vs masonry photo grid, with one difference - the grid-template-rows: collapse line]
<fantasai> jensimmons: New layout type, creates a separate tool with separate syntax that's similar but not the same as what exists
<fantasai> jensimmons: [shows table of properties being added]
<fantasai> jensimmons: We don't believe there's a compelling argument to add so many new properties to CSS
<fantasai> jensimmons: Both have properties for defining tracks; defining masonry axis
<fantasai> jensimmons: both have ways to define placement, and both have a new slack property
<fantasai> jensimmons: both have shorthand, and a gap property
<fantasai> jensimmons: and both have ways to implicitly size tracks
<fantasai> jensimmons: more significant difference is grid-auto-flow vs masonry-direction/fill/flow
<fantasai> jensimmons: Chromium argues that their new syntax is more understandable. We disagree, just use grid-auto-flow
<fantasai> jensimmons: Other major difference is template syntax
<fantasai> jensimmons: Here's a column example using the templat syntax. identical in grid 1, and masonry in both
<fantasai> jensimmons: When you layout rows in grid, template syntax is a bit different -- you stack the template names to phyiscally diagram the names for the rows
<fantasai> jensimmons: Just Use Grid re-uses this syntax exactly; but new masonry layout uses the column syntax for rows.
<fantasai> jensimmons: Chrome believes it's less confusing to use the same syntax in rows vs columns; but we believe it's better to use the same syntax between grid rows and masonry rows
<fantasai> jensimmons: Other difference is the auto-flow -- grid's indicates the primary fill direction, Chrome believes this doesn't make sense and changed it to match the orientation of lines
<fantasai> jensimmons: Debatable which is better. Might make sense if we had time machine, but is it worth creating a new layout API for this ?
<fantasai> jensimmons: Lots of subtle differences are likely to trip people up. They're familiar but not quite the same.
<fantasai> jensimmons: We shouldn't fork grid, would be confusing to authors.
<lea> q?
<lea> q+
<fantasai> jensimmons: Chrome argues that new display type allows better defaults -- but the defaults propose aren't good
<fantasai> jensimmons: if you think through the default they propose, it doesn't quite work as easily as claimed [see article]
<fantasai> jensimmons: requires deep understanding of autosizing
<fantasai> jensimmons: We believe it's better to just use grid. Very simple, one new value, re-uses syntax and mental model makes easier to learn
<fantasai> jensimmons: also easier to switch, e.g. at breakpoints or progressive enhancement
<fantasai> jensimmons: follows CSS design principles to re-use what already exists
<fantasai> [end presentations]
<fantasai> astearns: If you have comments, please add yourself to the queue
<astearns> ack lea
<lea> https://github.com/w3ctag/design-reviews/issues/1003#issuecomment-2489688718
<fantasai> lea: We did a TAG review on this
<fantasai> lea: My opinion is fully reflected there. I think the arguments WebKit team makes are compelling.
<oriol> q+
<fantasai> lea: We thought not only should masonry be part of grid, but should go further.
<fantasai> lea: a lot of arguments for integrating is that "grid is too hard". In that case we should make grid things easier.
<astearns> q+
<fantasai> lea: complex things are possible, but simple things are not so easy
<fantasai> lea: Big part of Google's argument is defaults, but we could just have smarter defaults -- there is precedent for this in CSS
<fantasai> lea: if we decided that would help ergonomics
<TabAtkins> q+
<fantasai> lea: We agree that switching between grid vs masonry is common. Grid might be a slightly better fallback than nothing, but minor argument because ppl can use @supports
<fantasai> lea: Introducing all these new properties increasing the API surfaces that authors need to learn. Less they can port over.
<fantasai> lea: Even if we say we will be disciplined, experience shows that we won't. Even if not intentional, accidental.
<fantasai> lea: DRY - don't have multiple sources of truth
<miriam> q+
<fantasai> lea: One of arguments against masonry in grid is that grid's are 2D, but actually in graphic design grids were often 1D
<fantasai> lea: I agree that most masonry use cases need simpler grids than general grid use cases
<fantasai> lea: but that means we should make those grids easier to define for both grid and masonry
<fantasai> lea: the more we looked into this, we realize there are 3 different layout modes that give you 2D arrangement of children
<fantasai> lea: we recommended not just make masonry part of grid, but find ways of integrating what we already have better
<fantasai> lea: could we come up with a shorthand that sets grid-auto-flow and flex-direction, and promote that for layout direction in general?
<fantasai> lea: then authors only need to learn one control for it
<fantasai> lea: another concern was overfitting
<fantasai> lea: it doesn't cover a lot of cases that look like masonry, like Flickr-style grid
<fantasai> lea: it's like a horizontal masonry
<astearns> ack oriol
<fantasai> oriol: Problem with jensimmons's reasoning
<fantasai> oriol: She said the proposed masonr-direction property would be new syntax that doesn't match grid-auto-flow property
<fantasai> oriol: but this property matches flex-direction property
<fantasai> oriol: so instead of trying to be close to grid, tries to be close to flexbox
<fantasai> oriol: closer to grid is a choice, could be consistent with different things
<fantasai> astearns: One question I asked is, has anyone changed their mind on which proposal they support?
<fantasai> astearns: I personally have. I thought that separate display property made a lot more sense, in terms of designing the feature and I was very daunted by the idea that we'd have to consider both grid and masonry for any new development ineither
<fantasai> astearns: seemed sticky to me
<fantasai> astearns: but the TAG argument convinced me that we should do the work of integrating these things
<astearns> ack TabAtkins
<fantasai> TabAtkins: Thanks for setting that up for me, because I'm going to refute the TAg argument! I think they're wrong in this case
<astearns> ack astearns
<astearns> zakim, close queue
<Zakim> ok, astearns, the speaker queue is closed
<fantasai> TabAtkins: You can draw a lot of surface-level connections between Grid and Masonry, and Flexbox, and other hypothetical layouts
<jyasskin> q+
<fantasai> TabAtkins: but when you actually look at details of how they work, behaviors each one is capable of, they're pretty distinct
<fantasai> TabAtkins: if you try to combine together, it would be an unholy mess of conflicting constraints -- e.g. flexing in items of masonry or grid
<fantasai> TabAtkins: or you'd have a weird mish-mash of, "the 2D layout", but if you call it a flex you get access to these properties, call it grid, access to these other properties
<fantasai> TabAtkins: concrete example, "pillar" example mentioned in webKit blog post, that wasn't compatible with the base concepts in masonry and flex because it wants a shared block formattng context
<fantasai> TabAtkins: grid etc have different formatting contexts, can't use floats
<lea> actually, the TAG argument was that layout seems to actually be a continuum, and syntax should accommodate that rather than forcing one of two extremes (current flex vs current grid).
<fantasai> TabAtkins: they're specialized for what makes sense
<fantasai> TabAtkins: You can occasionally merge things together, but definitely not something you can do that by default
<fantasai> TabAtkins: too distinct to be merged in a reasonable way
<jensimmons> That's why the "pillar" example will use `display: block`. The argument being made when it was articulated is NOT that it should be part of Grid, but that it should be part of Block, and not it's own yet another new mode.
<lea> Our argument was not "make it a part of grid" per se, but more "don't introduce a completely parallel new thing". If you can extend flex so that masonry can become part of that, that's just as fine
<fantasai> TabAtkins: Then usability arguments.
<lea> q+
<fantasai> TabAtkins: The masonry shorthand can be very similar to a standard CSS shorthand -- fully reorderable, just put the bits you care about
<fantasai> TabAtkins: integrated one, the grid shorthand is very complex, mixing in masonry doesn't make it simpler
<fantasai> TabAtkins: would stay bad and get worse
<fantasai> TabAtkins: separating lets use design things catered to the use case
<lea> if the `grid` shorthand has poor usability we should improve the grid shorthand, not design a new thing :)
<astearns> ack miriam
<fantasai> miriam: Like Alan, tend to agree with TAG on this. I'm not real excited about a future where we keep inventing new layout modes with slight differences.
<TabAtkins> The `grid` shorthand is complex *intrinsically*, it's got a lot of concepts that have to all be put together. It can't really be made much better.
<astearns> ack dbaron
<fantasai> miriam: I get that there's complexity, but it's worth the attempt to figure out how to not invent new tracks every time we have a new layout that has tracks
<TabAtkins> And that intrinsic complexity is directly tied to it being an inherently 2d layout mode, whereas Masonry, like Flex, is "1d, plus a bit"
<fantasai> dbaron: I remember Ian arguing about the perf characteristics wrt intrinsic size calculations
<fantasai> dbaron: Was related to fundamental ordering between how parts of the process run in grid vs masonry
<fantasai> dbaron: Good perf important for end users. Is that topic still under debate? Or is masonry in grid syntax using the model that Ian wanted
<fantasai> TabAtkins: Whether in grid syntax or not, using the distinct layout rules we defined to work for it
<fantasai> jyasskin: Wanted to emphasize a couple aspects of TAG review
<fantasai> jyasskin: It seems really nice to keep the property from Chrome proposal that you don't have to learn both, can just learn to do masonry without learning all of Grid
<fantasai> jyasskin: even if that's in a unified system
<fantasai> jyasskin: perhaps still define masonry shorthand, and have it set grid properties
<jensimmons> To create a simple masonry-style layout in Grid, you just need 3 lines of code (4 with a gap). It's quite simple.
<fantasai> jyasskin: Most consensus part of TAG feedback was to share properties whenver possible
<lea> q+
<fantasai> jyasskin: Not necessary to share the same 'display' values; could define different 'display' values but share the properties.
<fantasai> jyasskin: One thing we didn't like about unified proposal was `grid-auto-flow` in the unified proposal, where some values were ignored.
<TabAtkins> Yeah, this is the usability point I'm pounding on
<fantasai> astearns: I'm not hearing a way forward yet. At some point, one of the camps is going to have to concede in order to move this forward.
<fantasai> lea: What if we do a straw poll. Not to decide, but to figure out how far are we from consensus?
<fantasai> +1 lea
<fantasai> lea: people may have been convinced
<fantasai> POLL: 1) Just Use Grid 2) New Masonry Layout
<TabAtkins> 2
<lea> 1
<fantasai> 1
<kizu> 1
<oriol> 2
<bts> 1
<alisonmaher> 2
<jensimmons> 1
<masonf> 2
<florian> 1
<miriam> 1
<ethanjv> 2
<JaseW> 1
<astearns> 1 (changed from 2)
<dbaron> abstain
<ydaniv> 2
<rachelandrew> 2
<dholbert> 2 (weak preference)
<gfaujdar> 1
<chrishtr> 2
<SebastianZ> 2
<jfkthame> 1
<bramus> abstain
<kbabbitt> 2
<joshtumath> 2 (but being persuaded)
<schenney> 1 but try to move toward common property names
<noamr> abstain (happy if we ship either!)
<jyasskin> I would love to see both camps' attempts to move a step closer to a shared understanding. e.g. Do the WebKit folks think it makes sense to define a masonry: shorthand in the grid-unified proposal? Can they fix grid-auto-flow? Do the Chromium folks see some properties that could be more shared?
<romain> 1 (changed from 2)
<emilio> 1.5
<fantasai> jensimmons: Personally disappointed that we're not making more progress. We've been having this argument for 5 years.
<fantasai> jensimmons: We have two implementations. We'd like to ship. Lots of discussion over the last year.
<fantasai> jensimmons: Many folks have strong opinions, but the target keeps moving. A lot of the concerns have been addressed, but new reasons to keep separate.
<TabAtkins> I mean, same.
<fantasai> jensimmons: Argument is no longer about technical details, but overall concept and authoring experience.
<JaseW> Are Jen's slides available anywhere?
<fantasai> astearns: I believe both camps want to ship and are frustrated with current impasse.
<rachelandrew> not new reasons here, same reasons I started with (before I was at Google)
<astearns> zakim, open queue
<Zakim> ok, astearns, the speaker queue is open
<fantasai> jyasskin, yes I think we could do that. Not sure it would convince the Chrome folks though :)
<JaseW> @jensimmons

@astearns astearns removed the Agenda+ label Dec 4, 2024
@astearns
Copy link
Member

astearns commented Dec 4, 2024

@JoshTumath
Copy link

JoshTumath commented Dec 6, 2024

Now that I've had more time to consider the opinions raised in our call on Wednesday – and particularly the TAG review which @LeaVerou shared – my mind has changed and I have swayed towards the 'Just use grid' option. I'll explain why.

The TAG viewpoint set us a new north star to aim for where all layout methods that do a '2D arrangement of children' become more unified and easier for authors to declare:

Overall, we think masonry, grid, and wrapping-flexbox should be incorporated into a unified set of properties.

This argument was particularly compelling to me (emphasis added):

  1. It was argued that the grid-independent syntax makes things easier if the properties need to diverge in the future. We think that is a drawback of that syntax, not a feature. Even if the WG selects a syntax like the grid-independent one, it should work hard to ensure that the properties diverge as little as possible in the future, even if some masonry properties initially appear not to have an obvious behavior for other display modes. It would be even worse to evolve subtle variations in patterns that otherwise appear to match, for example by forgetting to apply a new grid keyword to the parallel masonry property.

This argument trumped my main concerns around how we might want the syntax to diverge. The argument also supported the vision that the WebKit team gave us at the end of their blog post about a possible future where we could even somehow use the grid properties on flow layouts.

And then the TAG review goes on to talk more broadly about layout syntax.

We urge the WG to explore ways to unify these so that authors can port more knowledge from one to the other (even if they are implemented as separate code paths internally). For example grid-auto-flow, flex-direction, masonry-direction, and masonry-fill all control the same stylistic aspect from an author pov and it seems that they could be more unified to some degree.

[...]

These patterns blur the line we've been assuming between 1-d and 2-d layout, and the WG may need to solve the problem by leaning into a continuum between those two options. It would be ideal to find a set of properties that can be used to build all of these layout patterns, instead of potentially overfitting to just masonry layouts.

In conclusion

On behalf of the BBC, I am happy to support the "Just use grid" syntax to move the proposal forward.

However, the TAG review has set out a wider vision for shorthands or other more generic syntaxes for defining layouts. Would it be helpful, as part of this issue, to start blue-skying those, just to help the debate along? I would be interested to see any proposals.

For example, the fact that we can now use gap in flex layouts and align-content in grid, flex and now flow layouts has been a game changer. It would be great to see how some of the grid-* properties could be made more generic. Like @kizu said, 'It is true that authors rarely use the grid shorthand, and that means that we should look into how we could improve it for all the cases.'

@Monknow
Copy link

Monknow commented Dec 6, 2024

I am an outsider here, but wanted to give my grain of sand from an author's point of view. I don't want to get into which proposal will be easier to define in the spec or implement in browsers since that's something that most developers aren't aware of but rather boil it down to what syntax developers will find easier to learn and use, and if the future gives us more layouts like the Webkit post suggests, which will make it easier for developers to learn to new layouts.

Prefixes and extra properties

One of the main arguments for the Just Use Grid team is the enormous amount of similar properties that would need to be added to CSS.

image

By the WebKit Post:

One of the guiding principles that drives decisions at the CSS Working Group is to always strive to reuse existing patterns and properties when creating new possibilities.

When multicolumn was invented, a new column-gap property provided a way to define the space between columns. A decade later, when the CSSWG needed a way to define space between grid columns, the column-gap property was repurposed. It got a corresponding row-gap property and a new shorthand, gap, to be more universal, and eventually made its way to Flexbox as well. It took a couple of tries, but the CSSWG realized it would be a mistake to keep creating separate gap properties for different contexts — column-gap + grid-gap + flex-gap… It’s better to repurpose what already exists.

By the same logic, it isn't a problem of new properties with a masonry- prefix, but of the prefixes altogether. If we are thinking about defining new layouts, then the grid- prefix is also a reusability antipattern. I keep thinking that, just from a syntax standpoint, it should be possible to use a new unprefixed template-areas property for masonry and grid, regardless of the formatting contexts.

If we look at another example given in the WebKit post:

image

According to the Chrome proposal, this type of layout would have its own prefix, but I think everyone would agree it would be hellish to also have pillar- or new-layout- prefixed properties, and so on if future layouts are added.

Onto the Webkit argument, they say that maybe in the future this layout could be achieved with a snippet like the following:

article {
  display: block; /* default value, unnecessary to state */
  grid-template-columns: 1fr 1fr minmax(15ch, 30ch) minmax(15ch, 30ch) 1fr;
  grid-default-column: 3 / 5;
}

But to me, it feels unnatural to use grid- prefixed properties for things that aren't grid. That's why I think removing prefixing altogether is an option to consider. The grid- prefixed properties would still work for backward compatibility, but you could also use the unprefixed version. Maybe properties that only work in their corresponding formatting context would remain prefixed, but overall, it would reduce the number of properties to add and the syntax to remember.

If the conversation is focusing on unifying, then I just wanted to bring this to the table, but I must say that I am ignorant of the consequences and implications of this. Just a not-that-technical developer's point of view of what I would like to code in the future :)

@tabatkins
Copy link
Member

tabatkins commented Dec 27, 2024

I've been sitting on this for a bit, because of vacation/Christmas/etc., but I think it's ready to post now.

tldr: The "reuse when possible" principle is completely valid and should be (and is) applied as much as possible, but it shouldn't be overused, when merging/reuse is messy or complicated. Grid/Masonry is an example of the latter, with several properties that work well in Grid but are genuinely bad when used for Masonry, and several other properties that are at least clumsy in Masonry (tho technically usable). This appears to be a general issue, since Flexbox can't meaningfully merge into these either, nor can future examples that have been brought up.

In short, while new layout abilities sometimes merge nicely into an existing layout mode (like Subgrid into Grid), it is usually the case that the abilities of one layout mode, and the specialized syntaxes we design to allow authors control over those abilities, are usually a bad fit for even a moderately different layout mode. Layout modes should, in general, get their own set of properties with their own specialized syntaxes, rather than trying to reuse each other's properties.

I'll go into detail on exactly how the current Grid-masonry design is bad, and at the end, offer a compromise if the WG still disagrees that Masonry should be its own independent layout mode.

Specific examples

Apologies for the length of this section. The badness really is in the details; the way that the Grid properties work when applied to Masonry is an extraordinarily bad design, and it's worth working thru those details rather than handwaving it as "it's bad, just trust me". If you'd prefer to trust me, feel free to skim.

  • grid-template-areas:

    • Syntax allows defining an NxM grid; when used in Grid-masonry, we are forced to ignore all but the first row/column. "Technically valid but ignored" values are an anti-pattern we try to avoid when possible; we often purposely design grammars to avoid this even being possible.

    • A single-column Grid-masonry and a single-row Grid-masonry use different syntaxes; "one two three" vs "one" "two" "three". Requiring authors to remember which syntax to use depending on their masonry direction is bad.

      In Grid, the syntax works well, and authors have good reason to break the separate row-strings onto separate lines, to align the columns across the strings and make 2D ASCII art showing the grid structure. There is no such benefit in Grid-masonry (there's only one cell per row), so instead you just have the value put on one line regardless, and the weird syntax split based on direction.

      That is, authors are not going to write:

       grid-template-areas: "foo bar baz"; // column masonry
       grid-template-areas: "foo"
                            "bar"
                            "baz"; // row masonry

      as that's just a frankly silly use of linebreaks/whitespace. They'll just write:

       grid-template-areas: "foo bar baz"; // column masonry
       grid-template-areas: "foo" "bar" "baz"; // row masonry
  • grid-auto-flow:

    • Grid 2 syntax is [ row | column ] || dense. In Grid, this dictates how auto-placed items search for empty spaces - by scanning each row before moving to the next, or scanning each column. Both row and column do absolutely nothing in Grid-masonry; it's already intrinsically auto-placing, and only has one possible axis to do it in. (While dense originally did nothing in Masonry either, we've since come up with a behavior for it, tho it's less powerful than the Grid behavior.)

    • Grid 3 adds row-reverse, column-reverse, and wrap-reverse. For Grids, the first two are the same as row/column, but flip the direction you fill the rows/columns in; the third flips to make it fill in the last row/column first and wrap back toward the start when you need more rows/columns.

      In Grid-masonry, we first have the issue that row-reverse and column-reverse again do the exact same thing, because the "auto flow" direction is already fixed. They do finally have an effect, tho, which is vaguely similar but notably distinct from their effect in Grid: rather than changing the direction you search for holes, it changes which direction you favor when breaking ties for "shortest track". Note that while row vs row-reverse in Grid will have a pretty large effect on the layout, in Grid-masonry it might only have an effect on the first items to be placed (since all tracks are tied initially); afterwards, if there aren't any ties it does nothing.

      Grid-masonry's wrap-reverse is more similar to Grid's in effect and impact, as it causes the tracks to fill from their end side. The name is a little misleading, however; there's no real notion of "wrapping" in Masonry (while it makes perfect sense in Grid).

      The display:masonry properties are much clearer; they borrow their names and syntax from Flexbox, which has similar concepts: just like Flexbox's flex-direction: row | column | row-reverse | column-reverse, we have masonry-direction: row | column | row-reverse | column-reverse, with very similar behavior. Then the one novel property in this group, masonry-fill, determines how it breaks ties, a situation/behavior that neither Flexbox nor Grid really has.

  • the grid-template shorthand:

    • In Grid, this combines grid-template-rows/grid-template-columns and grid-template-areas. Grid-masonry, thus, inherits all the problems of those properties: only one of -row/-columns is used (the other needs to specify masonry), and the -areas component has its two distinct syntaxes. The combination actually compounds the badness, tho.

      First, the -rows/-columns components are in a specific order in Grid: the rows, then the columns. This order is, again, completely sensical in Grid, as it corresponds to how you write the 2d grid in ASCII, but in Grid-masonry it's an unnecessary requirement. So a row-masonry needs to be written repeat(3, 1fr) / masonry while a column masonry is masonry / repeat(3, 1fr) - the masonry's direction is completely implicit, never explicitly mentioned. Compare with display:masonry, which uses masonry: row repeat(3, 1fr) or masonry: column repeat(3, 1fr) (or in reverse order) - direction is clearly and explicitly provided via a keyword, and order of the values doesn't matter.

      Second, the "one string or multiple strings" problem with grid-template-areas infects this property too, and compounds. A row masonry is written "foo" 1fr "bar" 2fr "baz" 3fr / masonry (with this precisely fixed order of values), while a column masonry is written "foo bar baz" masonry / 1fr 2fr 3fr. This massive divergence in how you are required to write the property, depending solely on whether it's a row or column masonry, is completely unacceptable from a design standpoint. Nobody would ever design a property like this on purpose, it's terrible.

      Compare with display:masonry, which is masonry: row "foo bar baz" 1fr 2fr 3fr (with the three bits in any order), or masonry: column "foo bar baz" 1fr 2fr 3fr. Free re-ordering to whatever the author prefers, and the only difference between the two directions is the keyword declaring that direction.

  • the grid shorthand

    • In Grid, this combines the three properties of grid-template with the grid-auto-* properties - grid-auto-rows, grid-auto-columns, and grid-auto-flow. One would think that this inherits even more problems - all the grid-template issues + the grid-auto-flow problems, but actually the property doesn't work at all.

      That is, while you can of course still write a grid-template value in grid, it also offers this grammar for doing all both grid-template-* and grid-auto-*:

       <<'grid-template-rows'>> / [ auto-flow && dense? ] <<'grid-auto-columns'>>?
      

      (This specifies explicit rows and auto columns; there's also the reverse for auto rows and explicit columns.)

      This grammar is fundamentally incompatible with Masonry. It only lets you specify one of grid-template-rows/-columns, but Grid-masonry needs both so it can declare one axis with explicit tracks and the other as masonry. The most you could do is something like masonry / auto-flow 1fr: no explicit tracks listed at all, a meaningless auto-flow value (because Masonry is always auto-flowing), and a grid-auto-columns value that does get used, but only in a weird way: the grid will create enough implicit columns (with that size) to fit the largest spanning item or the furthest placed item. (Which means, in the common case, it'll just spawn a single implicit track.)

      With the Grid 3 values for grid-auto-flow it'll be possible to specify a slightly meaningful value instead of auto-flow, but it'll still mean you only have a single track in the common case. And, again, if you instead wanted to have a row masonry, you'd have to flip the order of things.

      (The grammar should be amended to allow specifying masonry on the auto-flow side, so the explicit track list is actually useful. But this is another indicator that the mental model underlying the Grid syntax is simply not designed for how Masonry wants to be written.)

      Also, the grid syntax only lets you choose between combining -rows/-columns with -areas, or with -auto-*. You can't actually shorthand all of the properties at the same time. (This isn't super intentional on Grid's part, fwiw. It would be completely reasonable to want to name your columns even if all your rows are auto-generated. The grammar just gets too complex to make that reasonable, so we left it out.)

      Compare all of this with display: masonry, which trivially lets you combine all the functionality in a single, fully-reorderable property with no complexity to deal with: masonry: column-reverse 1fr 2fr 3fr reverse;.

Conclusion

Even with a few more fixes to the grammar to make it work properly, Grid-masonry is still fundamentally awkward to specify and use. We would never design such a syntax from scratch; we'd be laughed out of the WG telcon. The cost of requiring authors to use such a clumsy syntax, and the precedent it establishes for how clumsy of a syntax we're willing to tolerate, is not remotely worth the benefits of authors not having to learn a new set of property names. As well, the benefit of reusing property names does not meaningfully carry over to actually reusing the property values in many cases; the actual meaning of those values is in several cases significantly distinct anyway, so authors are effectively still learning a new set of properties when using Grid-masonry, just spelled the same as an existing set.

This is actually a detriment to learning and understanding, versus having to learn a new-but-similar set of well-designed properties and values that match the underlying model better and much less clumsily.

Even if we designed Flexbox from scratch today, it would similarly not be able to reuse the Grid properties without being awkward and clumsy. I assert (without showing my work) that this would be true even if we designed the entire thing from scratch, all three of Flexbox, Grid, and Masonry together without any backwards compat to worry about. And the discussed possible future layout models, like "pillar", are similarly quite distinct and would have their own awkward/clumsy integration into such a combined layout mode.

In conclusion, Masonry should be its own display value, with its own set of properties that are well-designed for it. I suspect I (/Chrome) am willing to formally object to the current Grid-masonry design; it really is Just That Bad.

Compromise (that I don't like)

If the WG still disagrees with all of the above and thinks it is worth trying to reuse Grid properties in Masonry as much as possible, I offer this in-between proposal that avoids as much of the badness as I can.

I must stress that I do not like this proposal. A lot of the clumsiness is inherent to the fact that Grid is designed to be fully 2d, while Masonry is, similar to Flexbox, 1d-and-a-bit in its concepts. But it is substantially better than the current Grid-masonry proposal.

  • grid-template-rows/-columns/-areas reused as-is. Do not add the masonry keyword. (Ignore whichever one is in the masonry axis.)

    • Add the "intrinsic sizes in an auto-repeat function" grammar that Masonry allows. Either figure out some way to make that usable in Grid, or just give it fallback behavior (take one repetition), like when you use auto-repeats values in an instrincally-sized Grid today.
  • grid-auto-rows/-columns reused as-is. (Again, ignoring whichever one is in the masonry axis.)

  • grid-row/etc reused as-is. (Again, ignoring whichever one is in the masonry axis.)

  • Add a masonry-flow: none | [ row | column | row-reverse | column-reverse] || [ tie-start | tie-end ] property, which makes the Grid into a Masonry, and declares the masonry axis and direction, and tie-breaking direction. (Identical to masonry-flow in the current draft with an extra none keyword, except I'm changing the masonry-fill keywords. I want to make that change anyway.)

    (I'm using masonry-* naming here, to go along with the masonry-slack property we're already planning to add in either syntax. Alternately it could be grid-masonry if we want to nest it under the grid-* prefix.)

  • grid-auto-flow is ignored entirely; masonry-flow completely subsumes it.

  • Add a masonry shorthand, matching the current draft, which sets masonry-flow and all the existing grid-* properties appropriately.

  • Probably change the grid-template & grid shorthands to also reset masonry-flow. (masonry-slack can go either way; I'm inclined to leave it alone.)

This design lets us ignore the terrible syntax of grid-template-areas, grid-template, and grid (when used for Masonry) entirely; instead, authors will just use the masonry shorthand, which is simple and easy. masonry-flow makes the masonry axis clearer by reusing the already-understandable Flexbox syntax, and lets us avoid the clumsy reinterpretation of grid-auto-flow keywords entirely. If you really want to, tho, you can still use grid-template or grid as usual, and then set masonry-flow to activate the masonry axis. It does still carry some dead weight; authors have to be aware that several Grid properties are ignored when Masonry is active.

If we really wanted to minimize the number of new properties, we could instead merge masonry-flow into grid-auto-flow, as a separate grammar branch with a special keyword, like grid-auto-flow: masonry row, and have that be the trigger for Masonry behavior. Because this is a completely separate grammar branch, tho, it isn't meaningfully different from just having a separate property. Also, it really does do a substantially different thing than what grid-auto-flow does today, so merging it in isn't very helpful from a meaningfulness standpoint. I'd recommend against this.

Note that accepting this compromise does not imply that we'll continue to merge more layout modes into Grid just because they're 2d-ish. We'd still evaluate them as they come.

@fantasai
Copy link
Collaborator Author

Apple spent some time reviewing the TAG feedback and the comments above, and particularly considering the concerns about awkwardness with grid-auto-flow integration that Google also identified, and we have come up with the following counter-proposal building on the Just Use Grid option:

  1. Drop the masonry keyword from grid-template-*. Continue to use display: grid.
  2. Re-use the grid templating and grid placement properties, as currently.
  3. Unify grid-auto-flow with flex-flow as item-flow per the TAG’s feedback, and split it out into the following longhands as described in [css-flexbox][css-grid] Unifying grid-auto-flow and flex-flow #11480: item-direction, item-wrap, and item-pack. Also create item-slack, either as a longhand or separate. (Note: Open to renaming the item- prefix.)
  4. Add a collapse keyword to item-pack to trigger masonry-style layout.

The new flow controls for masonry would look like this:

item-flow: <item-direction> || <item-wrap> || <item-pack> || <item-slack>
shorthand for...
   item-direction: row | column | row-reverse | column-reverse
   item-wrap: wrap | wrap-reverse
   item-pack: normal | dense || collapse
   item-slack: <length-percentage>

Here’s the code to accomplish two use cases from this article:

grid-3-layout-light

.masonry {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
  item-flow: collapse; /* == item-flow: row collapse 1em; */
  gap: 1rem; 
}

sideways-masonry-light

main {
  display: grid;
  grid-template-rows: 2fr 1fr;
  item-flow: column collapse; 
}

Thoughts?

@Crissov
Copy link
Contributor

Crissov commented Jan 11, 2025

item-tile-

@nathanchase
Copy link

nathanchase commented Jan 11, 2025

item-tile-

item is more aligned with current convention:

  • align-items
  • justify-items

The content inside of flexbox or grid are items.

@Loirooriol
Copy link
Contributor

Thoughts?

IMO it looks quite confusing that in order to get a masonry that has rows, you need item-flow: column collapse. Sure, items will flow vertically so you can think of columns, but there are no actual columns. And I think it's much more intuitive to define whether you want columns or rows, rather than defining whether you want the next item to flow vertically or horizontally, and then infer from there. So I still prefer masonry-direction & friends.

@JoshTumath
Copy link

I commented on Apple's proposal: #11480 (comment)

I like it, but I'm wondering if it leads us towards a hybrid of Apple and Google's syntax proposals. Each layout system still has properties unique to it, like flex or grid-template-columns. Where it's not possible to unify layout properties as per the TAG review recommendation, maybe it does make sense, after all, to have masonry-* properties?

So I'm interested in what other opportunities we have to unify the syntax, which may help to address Tab's concerns. (#11243 (comment)).

@tabatkins
Copy link
Member

(I commented over in #11480 instead.)

@kbabbitt
Copy link
Collaborator

Thinking about the TAG's question of what we would have done if we had a time machine... I might have proposed a refactoring of Grid+Flexbox into:

  1. A scheme for specifying layout boundaries in a 2D space, in both horizontal and vertical directions. I'm reminded of "guidelines" from the desktop publishing world. In CSS, we have something similar in track definitions, except we specify the spaces between the guidelines rather than the guidelines themselves. Such a scheme could be shared across various 2D layouts, with some using both sets of guidelines/tracks and some using just one.
  2. A scheme or schemes for specifying how children are arranged within that space. This is how we would define wrapping-flexbox, grid, masonry, Flickr, and maybe even other 2D layouts such as Pillar. The item-* properties and discussion in #11480 seem to me like a great step towards a common language for these.

To those points, I think this:

Drop the masonry keyword from grid-template-*

is an important simplifying change, because it decouples track definition (point 1; what existing grid-template-* were doing) from item placement (point 2; what existing grid-auto-flow was doing).

@jfkthame
Copy link
Contributor

1. A scheme for specifying layout boundaries in a 2D space, in both horizontal and vertical directions. I'm reminded of "guidelines" from the desktop publishing world.

As something of an aside, perhaps this is also how the features of "rhythmic sizing" or "line-grid" should be introduced. They're just more cases of defining a "grid" (in one direction), and then controlling how elements size and place themselves in relation to that grid.

@astearns astearns moved this to FTF agenda items in CSSWG January 2025 meeting Jan 27, 2025
@astearns astearns moved this from FTF agenda items to Thursday afternoon in CSSWG January 2025 meeting Jan 28, 2025
@astearns astearns moved this from Thursday afternoon to Friday morning in CSSWG January 2025 meeting Jan 31, 2025
@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-grid-3][masonry] Masonry Syntax Debate, and agreed to the following:

  • RESOLVED: Re-use grid templating and placement properties for masonry layout
The full IRC log of that discussion <bramus> fantasai: the 1st topic is should masonry use its own template props or should we reuse existing grid-template props?
<bramus> … (for placement)
<bramus> … we have gone of this before a bunch of times
<bramus> … the q is separate from the rest we believe
<bramus> … the q is to go for grid-template props or masonry-template props for defining tracks and for placement
<bramus> jensimmons: so there is lots of complexity
<bramus> … idea with just use grid is to stick to grid-template-* props
<bramus> … ide with masonry is to use separte tsyntax
<bramus> … since last meeting tab proposed to maybe the new masornry layout position we woul dneed to duliate a bunch of props
<bramus> … not a final decision but it is an idea that could get isolated from the rest
<bramus> … do we want to put to bed the masonry-template-* props and masonry-autuo-tracks and use the grid props where we can in order to not have duplication?
<bramus> fantasai: we are not talking about grid-=auto-flow or masonry-…flow – is only about grid tpl properties
<bramus> … versus their masonry equivalent
<bramus> … and then grid-row vs ?? for placement
<TabAtkins> Just the "template" and "placement" properties.
<kbabbitt> s/vs ??/vs masonry-track/
<lea> Could someone summarize what the actual proposal is?
<bramus> jensimmons: do we want to resolve that no matter what we end up doing to not create 19 new props that are very similar
<alisonmaher> q+
<bramus> … and try to use grid props as much as possible
<fantasai> s/and then/grid-template-* and grid-auto-* for track definition/
<bramus> astearns: so basic idea is masonry has some things that are identical to grid (or very close).
<TabAtkins> q+
<bramus> … grid tpl things, and so … just use grid props for that
<bramus> florian: separately from the rest
<astearns> ack alisonmaher
<bramus> alisonmaher: why for pos items having separate pros is useful for ergonomics
<bramus> ; if we use it for grid- props, authors could sset the wrong one int he wrong direction
<bramus> … would still parse but not give them the wanted result
<bramus> … separate tracks poisition would only apply in the direrctiont the author intended
<astearns> ack TabAtkins
<bramus> TabAtkins: this is not “hey, we are going to replace this with grid”. q is “whcih one should we go with“
<bramus> … reasons for either one
<bramus> … reusing grid props has benefit that confcepts are shared
<bramus> … layout algo talks in grid in many ways
<bramus> … few things to still deal with
<bramus> … initial value is a wrinkle
<bramus> … and auto filled tracks with intrinsic size
<bramus> … but its theoretically doable
<bramus> … potential to declare both rows and cols for grid
<bramus> … need to ignore one of the sets
<astearns> q+
<bramus> … masonry set of things mean that while these are a close duplicate in grammar, they are a single well designed thing that fits masonry perfectly\
<bramus> … some duplicate but better fit
<bramus> ; ntohnig needs tobe ignore in dweird cases
<bramus> … grid-tpl-areas is the one i am most uncomfortable with
<bramus> … dont like using
<bramus> … designed to do ascii art in grid
<bramus> … clever design
<bramus> … works perfectly there (in grid)
<bramus> … in masonry you dont have 2d grid
<bramus> … 1 set of tracks in 1 direction
<bramus> … ???
<bramus> … masonry cols is 1 string which ontains all cojum anmes
<bramus> … if you have rows you ahve mutliple strings with 1 row name in each string
<TabAtkins> "foo bar baz" vs "foo" "bar" "baz"
<bramus> … bc how oyou declare a sginel rolw multi col grid
<bramus> … that sort of grid is rare
<bramus> … ppl dont generally do that
<bramus> … if they do, the may or may not name their areas
<ntim> grid-template-areas: "r1c1 r1c2" "r2c1 r2c2"
<bramus> ; asklward that when depending on masorny direction you need a different syntax
<bramus> … could live iwth it, bu tnot great
<bramus> … leaning towards masonry props, but ok with either way.
<bramus> astearns: 1 more distinction
<bramus> … reusing grid props gives us that nice fallback fn thats been talked about in the grid proposal
<bramus> … that you dont have to redeclare a bunch of things
<TabAtkins> q+
<bramus> … and if we find that there is some problem with dev ergonomics in using the grid props for masonry
<bramus> … we coud prop by prop add a masonr equivalent when justfied by author usage
<astearns> ack astearns
<astearns> ack TabAtkins
<bramus> TabAtkins: it was imlplicit when i talked abou tsome masonry values that dont work well in grid
<bramus> … that means if we reuse same set of grid-tpl props, we need to define what that means for grid
<bramus> … can make it valid
<bramus> … ??
<bramus> … will continue to be a potential issue that any new prop needs to be defined for both at the same time
<fantasai> s/??/can define it as some fallback e.g. repeat resolves to 1/
<bramus> … if they are separte that does not need to happen
<bramus> … reuse on 1 side and independent definition on the other are two discussion topics
<florian> q+
<astearns> ack florian
<bramus> florian: for the wrinkle you talked about mastony tpl area
<bramus> … possibly we could add an optional keyword int he grid syntax that if you only have 1d it applies tot he primary direction
<bramus> … and in grid/masrony they have different meanings
<bramus> ; if you only use 1d, it uses the syntax
<bramus> … no need to deep dive, but its an option that might ease things
<astearns> ack fantasai
<bramus> TabAtkins: sounds fair
<bramus> fantasai: about authors to now knowing when to use grid-tpl-rows or cols
<bramus> ; dont think that will happen
<bramus> … if they get confused its about a prop that switches axies
<bramus> TabAtkins: agree that its a bit confusing there
<bramus> fantasai: about tpl syntax: arugment that tab is making is that its confusing that the syntax is differne between two differnt axis
<bramus> … but if we made it the same
<bramus> ; for both axis in masonry then in the masonry layout for in the row axis the tpl syntax would be diff from a grid layout
<bramus> … would be introducing that as an inconsistency
<bramus> … tpl syntax was designed for ascii art
<bramus> … still works for masonry
<bramus> … if you create cols you write your foo bar baz in a single string and then write track sizes
<bramus> … if you creata bunch of rows you put the names in a stack
<bramus> … as separate strings
<bramus> … and next to the name of the area you put the size
<bramus> … that lets ytou diagram your layout
<bramus> … was designed for that
<bramus> … its a feature of the tpl syntax carrying through into masonry
<TabAtkins> (we're pushing the `grid-template` shorthand to later, I have a much stronger objection to `grid-template`)
<bramus> … in the example you see two layouts. one is masonry and other is creating a strecthed alignmetn because its a grid
<bramus> … the grid tpl syntax supports both
<bramus> … much easier
<bramus> TabAtkins: tihe grid template shorthand and the grid shorthand is discussed later
<bramus> … much strong objection to the shorthand, dont want to discuss now
<bramus> fantasai: (missed)
<bramus> TabAtkins: no, the longhands
<bramus> … pseically the area one
<bramus> fantasai: when we look at diffs between grid tpl props and masrony tpl props there is very little difference
<bramus> … no need to introduce a lot of new props
<bramus> … bc authors could reuse the existing ones
<bramus> jensimmons: issue here is intended to shoot any of the other debats into silence
<bramus> … its a higher level question
<bramus> … can we make some progress around this 1 idea
<bramus> astearns: and the current high level idea is can we resolve on using grid-* props for masorny layout in general where it makes sense with case by case basis about when we actually need a new prop
<fantasai> grid-template-*/grid-auto-*/grid-row/grid-column vs masonry-template-*/masonry-auto*/masonry-track
<fantasai> Currently *only* about templating and placement properties
<bramus> … before we go to straw poll, anyone has concerns to this general principle of reusing grid props where appropriate?
<bramus> iank_: find it still more funky than masonry props
<bramus> TabAtkins: I think I outlined those objections before
<bramus> astearns: straw poll
<ntim> astearns: re-use the grid-template-areas properties or something else
<bramus> … 1. Reuse the grid template emplacement properties for masonry layout
<bramus> fantasai: this is about the longhands
<kbabbitt> s/emplacement/and placement/
<bramus> … 2. Have separate masonry versions for all of these
<fantasai> POLL: 1) Re-use grid template and placement properties for masonry layout VS 2. introduce dedicated templating and placement properties for masonry layout
<jensimmons> s/issue here is intended to shoot any of the other debats into silence/the issue is NOT to silence any further debates about details, but to
<florian> 1
<ntim> 1
<iank_> 2
<miriam> 1
<jfkthame> 1
<kizu> 1
<TabAtkins> 2
<alisonmaher> 2
<kschmi> 2
<schenney> 1
<fantasai> 1
<smfr> 1
<astearns> 1
<bts> 1
<emilio> 1
<jensimmons> 1
<lea> 1
<hober> 1
<oriol> 2
<rachelandrew> 2
<bkardell_> 1
<ethanjv> 2
<romain> 2
<dholbert> 1 but weak dependency on later decision about display value
<ChrisL> 1
<bramus> 2
<emilio> (+1 dholbert)
<emeyer> abstain
<ethanjv> (+1 dholbert)
<bramus> astearns: seeing slight but not overwheleming preference for 1
<bramus> emilio: e.g. i voted for 1 but could live with 2
<jfkthame> looks like 17 vs 9, or nearly 2:1
<ydaniv> abstain
<bramus> TabAtkins: this seems like a weak resolution for 1 and if people’s opinions shift we can adjust
<nicole> abstain
<bramus> astearns: proposal to take resolution for option 1 for now
<bramus> … objections?
<ntim> i don't think 2:1 ratio is a weak preference :)
<lea> 🎉
<fantasai> RESOLVED: Re-use grid templating and placement properties for masonry layout

@juanrgon
Copy link

I’m trying to fully understand the resolution. Which of these is correct:

  1. Masonry will be part of display: grid and will not introduce new masonry- properties?
  2. If masonry were to be built into display: grid, it would reuse Grid properties rather than adding new masonry- props?
  3. Regardless of whether masonry is implemented within display: grid or as display: masonry, it will still reuse existing grid properties?

@tabatkins
Copy link
Member

Those minutes are part of a multi-part discussion that's still ongoing, so they're not answered yet. ^_^

@tabatkins
Copy link
Member

Ah, sorry, thought those were three questions. Its (3); regardless of how we trigger masonry layout, we'll use the grid-template-* and grid placement properties on it.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed Masonry Layout Switch.

The full IRC log of that discussion <fantasai> Subtopic: Masonry Layout Switch
<fantasai> github: https://github.com//issues/11243
<fantasai> scribenick: fantasai
<fantasai> TabAtkins: Question 3 is how do we actually trigger masonry layout?
<fantasai> TabAtkins: We already resolved to use grid-* for defining template, but that doesn't decide this question
<fantasai> TabAtkins: Options are a) New 'display' value, b) 'item-pack: collapse' as shown earlier c) specialized property 'masonry-something' d) grid-template-row/column: masonry-keyword
<fantasai> TabAtkins: I lean toward 'display: masonry'. It avoids the item-pack question. But anything works here
<iank_> `display: masonry` could also be similar to `table-*` e.g. `display: grid-masonry`
<fantasai> TabAtkins: Now that we've agreed on grid-* properties, I'm fine with doing a grid switch for thise
<florian> q?
<TabAtkins> scribe+
<TabAtkins> florian: when yous aid we can do a display value for now and later activate it thru item-pack
<fantasai> TabAtkins: That wouldn't work. Only if we did a dedicated property.
<astearns> q+
<astearns> ack fantasai
<TabAtkins> (we could do a dedicated proeprty now, and later move it to item pack; or do a `display` keyword, and never put it in item-pack)
<TabAtkins> fantasai: i think we shouldn't do with (d) (grid-template-rows: collapse).
<TabAtkins> fantasai: if you set 'collapse' on both axises it's unclear what that means
<TabAtkins> fantasai: now that we have item-pack that's a beetter place
<TabAtkins> fantasai: i dont' think we should intro a specialized property just for this one thing
<miriam> q+
<TabAtkins> fantasai: if we dont' want to ddig too deep into item-pack for now, we can put it into grid-auto-flow where it lives alongside dense, which is already about packing
<TabAtkins> fantasai: when we figure out how that rolls into item-pack, it would roll up in the same way
<oriol> q+
<florian> q+
<astearns> ack astearns
<fantasai> astearns: Now that we've adopted the grid properties etc, I'm leaning more towards using 'display'
<fantasai> iank_: if we're using grid-prefixed properties, we could do a grid-prefixed display keyword. Like tables have table-
<TabAtkins> iank_: do display:grid-masonry, for example
<astearns> ack miriam
<TabAtkins> miriam: the one i udnerstand the least is item-pack, only briefly saw it in a different convo
<TabAtkins> miriam: not sure if that's something you want to flesh out more
<fantasai> TabAtkins: Under that proposal, if you set `item-pack: collapse` in a grid you're doing masonry.
<fantasai> TabAtkins: If you set only one of grid-template-columns/rows, then we go with the axis you didn't set for the masonry
<fantasai> TabAtkins: if you set both, default to making columns
<TabAtkins> fantasai: you forgot to say that if you set item-track:row, it explicitly gives the masonry direction (regardless of the grid-template-* properties0
<TabAtkins> fantasai: if you *don't* set item-track, the "auto" keyword (initial value) looks at grid-template-* and determines the masonry axises
<emilio> TabAtkins: I think fantasai hit everything I wanted to say
<emilio> miriam: I don't think I have other questions
<emilio> fantasai: can you summarize what you understood?
<emilio> miriam: no
<emilio> ... seems to be a lot going into it
<emilio> ... item-pack seems to be doing dense packing as well as balanced packing and potentially collapsed packing
<iank_> q+
<emilio> ... not sure all three track in my mind but gotta think more about it
<TabAtkins> (miriam just stated my own objection better than i have)
<astearns> ack oriol
<emilio> ... there are various normal/auto interactions that play out with other properties, which I think I mostly followed but couldn't summarize
<emilio> oriol: I don't like using grid-auto-flow
<emilio> ... because it decides how you flow order into the explicit grid or if you want to add implicit rows / columns
<alisonmaher> q+
<emilio> ... here it'd be destroying rows/cols
<emilio> ... don't think it mixes well with what it's doing
<emilio> ... would also be opposed to resolving now about the item pack thing
<emilio> ... these need a lot more fleshing out
<emilio> ... in the future when we have better definitions maybe
<ethanjv> strong +1 to oriol
<emilio> ... if we want to resolve I'd prefer display: masonry or grid-template-{rows,columns}
<astearns> ack florian
<emilio> florian: somewhat similar to oriol / astearns comments
<emilio> ... I was on "use grid all the way"
<emilio> ... prev resolution gave us flexibility
<emilio> ... I agree with oriol that grid-auto-flow feels like a weird fit
<emilio> ... display might be fine, ok also with separate prop, ok with separate prop that we roll into item-pack if we figure out, not ok with grid-auto-flow, not ok with grid-template-{rows,columns}
<astearns> ack fantasai
<Zakim> fantasai, you wanted to let's get clear on this
<kbabbitt> q+
<emilio> fantasai: wanted to go over the rest of the table
<astearns> ack iank_
<astearns> +1 to item-pack being too new (for now)
<emilio> iank_: similar to oriol, given item-pack, I think I also agree about grid-auto-flow being not-great
<jensimmons0> q+
<astearns> ack alisonmaher
<emilio> alisonmaher: wanted to go back to what is a display type
<emilio> ... spec says it determines how the child boxes are laid out
<astearns> ack kbabbitt
<emilio> ... grid and masonry have different enough layout models that I feel a display keyword (tbd) is probably fine
<florian> q+
<bramus> +1
<emilio> kbabbitt: agree with alisonmaher
<fantasai> if item-pack feels too new, then maybe we need to work on settling it first
<emilio> ... I think a new display type is my favorite. My mental model is that we refactored the two prev proposals into a set of pieces that are reusable
<emilio> ... grid-template... could be renamed to row-tracks/column-tracks or something like that to be clearer
<fantasai> -1 on that, I think authors really think of these as grid lines
<ydaniv> q+
<emilio> ... but they're shipped as-is
<emilio> ... so not super important
<emilio> ... other pieces we have is the item properties, which I really like
<emilio> ... sharing concepts like dense packing
<emilio> ... the other important thing is changing the masonry keyword out of grid-template, so they keep defining tracks
<emilio> ... so it doesn't get mixed up
<emilio> ... a display type defines how the items are arranged so that's my favourite of the proposals here
<astearns> ack jensimmons0
<TabAtkins> i think, too, that "collapse" in item-pack is the odd one out - it really *only* applies to grid, not flexbox (and probably not future display modes)
<TabAtkins> q+
<TabAtkins> it is solely the "make grid into masonry" switch
<emilio> jensimmons0: item-pack or some tbd details, that's pretty much the whole reason to create the whole unified item situation
<emilio> ... to give us a more elegant masonry
<emilio> ... if you're an author what do you write, display: masonry, grid-template, item-flow, gap
<emilio> ... four totally unrelated properties
<emilio> ... our hope was that item-pack or some other variation ...
<emilio> ... one of the early points of masonry was that grid-template: masonry was not ideal
<emilio> ... it also feels that is not a different display type
<astearns> q+
<emilio> ... it's an existing layout mode and we change it
<emilio> ... item-pack is that switch that tells you how you pack the grid items together
<emilio> ... where is the elegance for the author?
<emilio> ... how can it feel a more unified system which is what the TAG asked ofr
<emilio> ... that's the idea behind item-*
<emilio> iank_: I think item-pack is the clunkiest of the item-* properties
<astearns> ack jensimmons0
<astearns> ack jensimmons
<emilio> jensimmons0: maybe item-* needs some more work
<astearns> ack florian
<emilio> florian: as I said I no longer object to this being a display value
<emilio> ... but I do have a preference to put it in item-pack or a separate thing that can be rolled into item-pack
<emilio> ... reasons are (1) interaction with subgri
<emilio> ... weird to talk about subgrid if this is not a grid
<emilio> ... everything as a grid where you tweak the collapsiness of it is better
<emilio> iank_: does that stand if we say display: grid-masonry
<emilio> ?
<emilio> florian: it helps if you put grid in it
<emilio> ... but something: collapse also gets us away from the masonry word which isn't great
<emilio> ... it's also tricky from i18n point of view
<emilio> ... if we can call it something-collapse seems better
<emilio> ... display: collapse doesn't seem sensible
<iank_> q+
<emilio> ... the interaction with subgrid + collapse making more sense makes me thing that a separate prop that can be rolled into item-pack would be better
<astearns> ack ydaniv
<emilio> ... but then again this is a preference not an objection
<emilio> ydaniv: back to jensimmons0 and florian's comments
<emilio> ... I was on the display: masonry team
<emilio> ... but the TAG review made me reconsider
<emilio> ... given the new item props
<emilio> ... I'd like to hear lea's or someone who has been in the TAG, do the new item-* props answer the TAG's concerns?
<emilio> ... is this something that would satisfy the problems you found?
<kizu> I am thinking about `display: masonry-grid` (as a way to have it as a part of display, but still connect to all the grid properties)
<emilio> lea: When the idea was first proposed I think that item-* is the right direction
<emilio> ... haven't considered the details deeply tho
<emilio> ... because we have just heard of them today
<emilio> astearns: given this direction do you think there's an argument that item-* should influence us towards display or item-* switch?
<emilio> lea: that seems like a step backwards
<emilio> florian: which one?
<emilio> lea: having a separate display mode
<emilio> jensimmons0: agreed
<emilio> astearns: so you'd prefer the switch to be in the item-* set?
<emilio> lea: my understanding is that you do it based on the item-* props
<emilio> ... what's the counter argument?
<emilio> iank_: we are not putting it on the template
<emilio> TabAtkins: current options are display, item-*, or new magical property
<dholbert> RE kizu (and I think iank_'s) mention of `masonry-grid` or `grid-masonry`, those potentially get more confusing with `inline-` prefix. (`display: inline-grid-masonry` etc)
<astearns> q?
<astearns> ack TabAtkins
<emilio> TabAtkins: looking back at item-pack it seems collapse is the odd one out
<emilio> ... dense exists for grid
<emilio> ... balance isn't defined anywhere but can be wide
<emilio> ... collapse only applies to grid
<lea> `balance` is certainly useful for both, and is SO HARD to do rn for grid
<emilio> ... only purpose is to switch to masonry mode
<emilio> ... doesn't apply to flex/grid
<kizu> RE dholbert — in theory, we have the two keyword display syntax… `display: inline masonry-grid`
<emilio> ... so it seems we should not use it for this
<dholbert> kizu: right, but in practice people use `display: inline-block` etc
<emilio> ... we should use either a new prop or display
<emilio> ... I lean towards the later
<bramus> s/kizu: right, /kizu, right,
<dholbert> er, sorry, s/kizu:/ RE kizu, .../ (not quoting him for minutes)
<emilio> jensimmons0: feels like there's folks who see items-* pack as the right direction
<emilio> ... and others that prefer display
<emilio> ... I haven't heard why
<emilio> ... have seen impl concerns
<emilio> ... is item gonna work out
<emilio> ... but haven't heard from the pov of 15 years in the future why is display better instead of unified item-* syntax
<astearns> ack astearns
<emilio> astearns: was on the queue for a similar thing
<emilio> ... I wanted to get into the motivations
<emilio> ... we have the prospect of these item props that will have effect on all the layout modes
<emilio> ... and question in my mind is, are grid and masonry sufficiently different for these values
<kizu> dholbert, yes, could be a good way to educate people about the two keywords syntax :)
<emilio> ... that it makes sense to have an external switch that would change how all these props behave
<emilio> ... because there are sufficient differences that this is a different layout type
<emilio> ... or are things like items- consistent between them
<lea> q?
<emilio> ... if that one item property switch has rippling effects to all the other item properties seems wrong to me
<emilio> ... it should be another switch
<emilio> ... but if it just does that other thing, then I'm fine with it being in the item set
<emilio> TabAtkins: re. jensimmons0 I think I have been discussing this in more toward-the-future looking
<emilio> ... in particular collapse not being useful in non-grid layout mode
<emilio> ... I like the other combined props
<miriam> q+
<florian> q+
<emilio> ... and they should be with this generic set
<kbabbitt> +1 to TabAtkins
<emilio> ... but I don't think collapse satisfies that
<astearns> right, that's the other bit I was thinking of. What does a masonry switch mean to flex?
<emilio> ... re astearns, while some of the properties are reusing between grid/masonry, I do thing the item props work differently between masonry and grid
<emilio> ... in the same way they work between grid and flexbox
<emilio> ... the auto-flow of masonry are very different of the behavior on grid
<astearns> ack fantasai
<Zakim> fantasai, you wanted to suggest we settle the item-* stuff and then come back to this, since it seems some people want to understand better
<emilio> ... so I think that's a good argument for display or an external switch
<lea> It's not just about the future, it's also that this does not seem sufficiently distinct from existing display modes. It seems like a slight tweak over how (wrapped) flexbox works or how grid works (depending on what you see as the switch).
<emilio> fantasai: I think key question might be how do authors think about this?
<lea> Conceptually I'm having trouble thinking how I'd explain it to students as a separate display mode. Even explaining the distinction between grid and flexbox is already somewhat hard to describe, but at least you can piggyback on "one is for 2D alignment, the other not"
<emilio> ... do they prefer seeing masonry as a separate display mode or as a variant of grid layout
<emilio> ... several people have said they want to understand better the item stuff
<astearns> ack iank_
<emilio> ... so might be worth revisiting
<lea> I don't think this is something that authors can evaluate without actually trying it out
<astearns> ack miriam
<bramus> +1 to Lea
<emilio> miriam: I think understanding items-* better would help
<emilio> ... in some way I was trying to think about the cross axis
<emilio> ... so maybe it doesn't belong on the generic items-*
<argyle> q+
<emilio> ... so I lean to either different display (but that's weird because we want grid properties)
<iank_> `display: flow-root`
<iank_> :P
<emilio> ... Not convinced in the hyphenated names
<lea> I think I just realized what gives me pause about a new display type: display types are essentially modes, and modes have established usability issues (mode errors)
<emilio> miriam: I'm thinking of it about how grids handle the cross axis, in my mind
<emilio> ... which leads me towards template-{rows,columns} keyword
<emilio> ... understand the arguments against
<schenney> I agree with framing: How grid packs in the off-axis.
<emilio> ... so maybe this is a new prop?
<TabAtkins> lea, is that a general argument agaisnt display:block and display:flex, for example? Or more specifically about grid and masonry?
<dholbert> iank_, ah right, I forgot we've got that one with a hyphen already
<miriam> that's fair
<emilio> jensimmons: I don't believe there's a mandate for items-* to apply for every layout type for every value
<emilio> ... I don't think we have consensus that e.g. balance could do anything in grid
<lea> TabAtkins: often modes are unavoidable. But it's a good rule of thumb to try and limit them.
<astearns> zakim, close queue
<Zakim> ok, astearns, the speaker queue is closed
<emilio> ... I don't think we agree that if collapse only applies to grid it doesn't belong on items-*
<miriam> I wasn't thinking of it as a mandate, as much as an awkwardness :)
<astearns> ack florian
<emilio> ... might be interesting to think about how collapse could apply to flexbox
<kbabbitt> I think a lot of the value of the item-* properties is that they do describe concepts that can apply to several display modes. I put them in the same mental bucket as e.g. `gap`
<dholbert> jensimmons, 'collapse' already means something in flexbox, via `visibility:collapse`, which makes this a bit tricky in terms of term-overloading
<emilio> florian: I think we should defer and explore items-* a bit more
<emilio> ... it feels somewhat in between
<emilio> ... in some ways it's a different display mode
<emilio> ... but it's grid-ish
<TabAtkins> (and that "collapse" behavior is definitely completely distinct from what's happening with grid/masonry)
<dholbert> (visibility:collapse creates "struts" in flex, though I recall those not being entirely interoperable)
<emilio> ... kinda separate but only later
<emilio> s/later/partly
<emilio> ... maybe it fits display, maybe items, maybe separate
<miriam> this is `grid-flex` in my heart
<fantasai> `visibility: collapse` collapses a flex item that it's set on
<emilio> ... we've changed a lot of stuff
<emilio> ... not a lot has proved that this is the same thing
<emilio> ... gap applies to a lot of things, doesn't mean that cols is a flex
<astearns> ack argyle
<emilio> ... still this is the more grid like
<emilio> argyle: I've heard lots of things that I didn't know I wanted
<emilio> ... like balancing / sorting
<emilio> ... packery instead of masonry
<emilio> ... if we don't commit so hard to the concept of masonry
<fantasai> s/packery/JS library named packery/
<emilio> ... gap / cols / etc... I think there's a power to find more subtypes
<emilio> ... so I think we can make it better
<emilio> ... masonry++ or somesuch
<emilio> ... the one thing I thought I'd be convinced of
<emilio> ... flexbox has an axis
<emilio> ... grid has more, collapsing an axis feels weird
<emilio> ... so I think of masonry of a different non-flex / grid
<emilio> ... I think it's a good direction we're going towards tho
<lea> q?
<emilio> astearns: agree with florian we need to digest items-* and come back
<emilio> ... I think it's a good way of framing both proposal, but we need to break for lunch
<lea> are the slides available somewhere? Or their content?

@kbabbitt
Copy link
Collaborator

kbabbitt commented Feb 1, 2025

I think I did a poor job of articulating my position on the Masonry Layout Switch in the room today, so I'd like to try again.

What I like about the item-* properties, as an idea, is that they factor out concepts that make sense, and can represent the same concept, across multiple layout types: whether a 2d layout is arranged principally in rows or columns; the wrapping behavior for a 2d layout; the amount of "wiggle room" when placing items in a 2d layout. That lets me mentally group these properties into the same bucket as other property families that work across these contexts: gap, rule, even backgrounds and borders.

I feel the same way about grid-template-rows and grid-template-columns with the masonry keyword dropped from the syntax. Given a time machine I might rename them to something without the word "grid" to indicate that tracks/guidelines are a more general concept; I don't know that aliasing them now for that reason would be high value. The point is that tracks/guidelines make sense across multiple 2d layout types.

item-pack: collapse as a grid/masonry switch isn't quite there yet for me. Thinking about it from a greenfield design scenario - or through the eyes of someone learning these for the first time - I think "collapse tracks of a 2d container in one direction" could be interpreted either as masonry or as wrapping-flexbox*. There's a missing ingredient which is how the descendant items are laid out - which, as @alisonmaher pointed out, is exactly the inner display type expressed by the display property - and it's how we currently differentiate between grid and wrapping-flexbox. Perhaps there's an item-* which could supply that information in a consistent way. But with what we have so far, that's why I still prefer display: masonry to complement the great work that's been done so far to refine the proposals.

*edit - or as a third layout, which is e.g. given aligned rows and collapsed columns, place one item in each row in row-order, then place a second item in each row in row-order, and so on.

@schenney-chromium
Copy link
Contributor

I really appreciated the thorough discussion at the F2F and it helped a lot. I support the item-blah properties and would wait until we sort that out before deciding finally on the switch.

After listening and thinking, there doesn't seem to be any strong reason to favor one approach over the other (display vs property). Each side has reasonable arguments, I don't think the developer ergonomics are different enough to force a decision. So how to come to agreement after many years of discussion?

Browser performance and binary size comes to my mind. Could implementors comment on how often they would write if (display == grid || display == masonry) in layout code vs if (someProperty == doMasonry) in layout code? If the former, in which more code is common between masonry and grid, then make the property the switch. If the latter, where more code differs between layout and grid, then use display as the switch.

Sorry if this has been considered already, but it did not come up in the latest discussion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Friday morning
Development

No branches or pull requests