w3c / csswg-drafts

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

[css-grid-3] Designer/developer feedback on masonry layout #10233

Closed jensimmons closed 6 days ago

jensimmons commented 6 months ago

We just published an article about Grid Level 3 / Masonry layout on webkit.org, https://webkit.org/blog/15269/help-us-invent-masonry-layouts-for-css-grid-level-3/, and at the end of the article, we asked web designers and developers to weigh in with their thoughts.

We opened this issue to provide a place for people to leave their input after reading the article, to especially answer these questions:

What do you think? Try it out. Write about it on your own blog. Describe what you do and don’t like about current implementations. Create some demos of your own to explore what else is possible.

  • Should “masonry”/“waterfall” be part of CSS Grid or a separate display type??
  • Do you want the capabilities to define a single-axis grid with CSS Grid — to use subgrid, spanning, explicit placement, and combining different track sizes? Or do you only want the ability to define a classic masonry layout with equal-sized columns?
  • Will you use this at all? What might you do with it?
  • Do you have links to demos you’ve made? We want to see your ideas and use cases.
  • Are there things you want to do that you can’t do with this model?

If you are finding this issue through the typical CSSWG channels, please read the article before commenting. It provides 4,000 words of context.

romainmenke commented 6 months ago

Only for the simplest examples of masonry do I want this to be part of grid. Just throw a grid-template-rows: masonry; in there and you get a neat effect.

But I think that this is a classic example of making the simple things even simpler while making the hard things worse or impossible.

Keeping them separate makes it easier to teach and learn about the complex uses of a masonry layout.

It also preserves more implementation space for both grid and masonry to diverge in non-compatible ways.

kevin-powell commented 6 months ago

I've spent some time thinking about this before commenting because I think there are good arguments to be had from both sides (adding it to Grid vs. display: masonry (or whatever it ends up being called), and my main thoughts are:

edit: sorry this ended up being a lot longer than intended!

Where I'm coming from

I've seen some people pointing to potential performance issues based on repaints and layout shifts, and other things on the technical side of how it will be implemented. I'm simply coming in on this from a "in an ideal world, this is how I would like to use it, and how I think, from my experience helping people learn CSS, will be the easiest for them to pick up."

We do need this

  1. We wouldn't have multiple JS solutions for this type of layout unless it is something that people want to create.
  2. I get a fair amount of emails and DMs asking me how to create this type of layout. It is also something that's frequently asked in my Discord community. The answers are always "either use columns if you don't mind the content flowing vertically, or use a JS solution."
  3. Perhaps most importantly, we already have CSS-only solutions for other things we've traditionally used JavaScript to solve, such as scroll-driven animations. While those are amazing and I'm very happy to have them, I don't understand how scroll-driven animations can be seen as something that is needed in CSS, but controlling a layout is something we're okay having to rely on JavaScript for.

It should be a part of the CSS Grid spec

I feel like it should be a part of the Grid spec, rather than creating a new display type.

"Most uses cases" shouldn't be good enough

Several people have pointed out that display: masonry will cover most of the potential use cases of what people will want. I agree with that. However, there will be times when we want/need to do more, whether it's a narrower column here, a span there, or the use of subgrid somewhere.

If we close off some doors because this other method covers most use cases it seems like a missed opportunity to me (subgrid being a big one for me, as I don't see how it could be compatible in any way if we break it into its own display type).

Caveat

One thing I haven't understood is why a display: masonry would have to be more limited than grid, but it seems that's the case, which is my primary reason I wouldn't want to see it go that route. If it has it's own version of subgrid, is able to have uneven columns (or rows, if you have a horizontal masonry), and all those types of column/row definitions we can currently do with Grid, I'm far less opinionated on which direction we go.

My main worry is, we don't know what people are going to do with this, but people will do things with it that we can't anticipate. The more feature rich it is, the more creative people will be with it.

We haven't seen layouts that take advantage of these all of thse things because we don't really have a way to create them now, even with the existing JS solutions. Those often limit you to even columns, and there is no way to have things like subgrid or other grid features we have now.

It fits well with common uses of grid

This new proposal is almost an in-between between flexbox and grid, so I do understand the argument for having a different display value, but from what I see, a large majority of grid layouts don't define rows to begin with. Instead they rely on the implicit creation of them while explicitly defining the columns.

To be able to toggle between the implicit rows we have now to a masonry style layout with a grid-template-rows: off (or waterfall or masonry) feels like the simplest approach when writing the CSS.

It's (potentially) easier to learn

As someone who spends most of my time teaching CSS, I feel that it's a lot easier to introduce the layout as a small addition to Grid rather than to have to jump into a new display type, even if there are many similarities.

I realize that there will potentially be more to it all than simply toggling our rows on and off, but like a display: masonry will cover a large majority of use cases, simply defining columns and then changing the template-rows will cover those same use cases.

In my experience of helping people learn CSS and seeing how they progress through it, this feels like the easiest way for a learner. You learn how to define columns and rows then simply how "let the rows do their own thing" becomes a natural progression, rather than an "alright, now take everything we've learned, and we're going to bring it to this other display type".

This isn't a big deal by any means, but imo, the less friction when learning something, the better.

From there, it definitely has the potential to get more complicated, but that doesn't matter which syntax or display type we go with, at one point, if you want to get past the basics of how something works, you need to learn more about it.

While there might be some values that might only be available after changing the behavior of our rows (masonry-auto-flow, for example), is that more complicated than understanding the difference between a top: 0; between the different position values we have, and when containing blocks do or don't come into play?

To me, with justify-tracks being only part of this spec will be just as confusing as to why justify-items is only available in Grid and not Flexbox. I don't see why it would be more confusing if the new properties "unlocked" with a grid-template-* value, rather than a display value.

There would be confusion on why certain things work in grid columns and not masonry columns as well, even if they have different display types. People see all of these as "layouts", and when it comes to setting up columns and placing things in those columns, the same questions and confusion will happen either way.

Sidenote on columns or masonry-columns

If, in the end, a display: masonry (or other name) is the direction this goes, I don't understand the idea of going with columns or masonry-columns.

Don't get me wrong, the names make sense, but we've just spent years training people to use grid-template-columns and grid-template-rows, I feel like a masonry-columns then will just add another inconsistency to CSS.

My guess here is we wouldn't need a masonry-column to explicitly place and element in a column, so there won't be the confusion of masonry-column and masonry-columns (though, why not? I could see wanting to have one element in a specific column and letting the rest flow).

I get we all want to write less characters, but if it's going to work even a little similarly to grid-template-columns (and I'm guessing the most common use case will be a repeat(auto-fit, minmax(250px, 1fr)) or something like that, then could we simply make it masonry-template-columns and avoid even more confusion?

"Yes, when it's a grid, it's a template column, but when it's a masonry layout it's just a column... no, there isn't really a difference in how they work, we just named them differently like that, so try to remember it correctly." 🤷

If I'm misunderstanding why we'd go with a different name here, please let me know!

What should we call it?

From all the questions I see about layouts like this, I've noticed that people have no idea what to call it and have trouble searching for solutions because of that, so I don't think there is a "wrong" answer here. If all you're doing is wanting to make some simple columns, it's not like flex is obvious either.

That said, as an added bonus, I do feel like keeping it in the grid spec also makes it easier to come up with a less confusing name.

When I first read of the idea of grid-template-rows: off I didn't particularly like it, but the more I've thought about it, the more I do think it fits, and is probably the easiest way to understand what it means for a lot of people who are coming in with zero knowledge about what something like this is called, since, in a sense it will act as a toggle.

Coming from the perspective of a teacher, I see this being the one that gets the most head-nods when explained, and this can be reinforced with a quick opening of the dev tools with a grid inspector and showing how things don't live on rows anymore, whereas a masonry or waterfall then has to be accompanied by a slide that shows some imagery to help people understand why we called it that.

oscarotero commented 6 months ago

I'd like to extend my comment above with a couple of additional points.

benbyford commented 6 months ago

Part of the Grid spec seems reasonable, can we have this now please, I've literally been waiting years.

ebisucomtechlab commented 6 months ago

Should "masonry"/"waterfall" be part of CSS Grid?

Yes. When compared to the masonry-like layout created with CSS Grid Level 1, grid-template-rows: masonry simply creates a grid without rows. This made me naturally accept it as a part of CSS Grid. So a value like "off" being proposed is understandable.

grid-and-masonry-layout-large

I also wrote about this in my blog: https://medium.com/@ebisucom/css-grid-and-masonry-layout-24a5dff6ba8e

Yejneshwar commented 6 months ago

I'd say Masonry should be its own display property.

Step back from being a dev for a moment, in layman's terms. A grid would denote order, one knows where and how everything goes or should go beforehand. Whereas the entire reason for masonry is not knowing what or how items exists.

As an implementer, having masonry be its own display property will help deal with specific edge cases.

jponch commented 6 months ago

I really like the approach you described and have wondered for a while why masonry/collapse was not a part of CSS Grid. The only question I had was the one mentioned by @saivan regarding the expected outcome of setting both columns and rows to masonry. I still think the approach you've described makes sense, I'm just curious what should happen in this instance. Sorry if someone already answered this. I've not yet had the chance to read this entire thread!

meadowsjared commented 6 months ago

I prefer the display: grid;

but regarding grid-template-rows I like either: grid-template-rows: cascade; or grid-template-rows: flow; I'm torn between those two! ✌️

note: I don't really like grid-template-rows: off; or anything like that, because it doesn't hint at what it's really doing with the rows, not to mention, it could become a future mistake if they later come up with some other way of using weird non-defined rows 🫠

Fyrnx commented 6 months ago

what about something like grid-template-rows: flexible; or grid-template-rows: auto-sizing;

i know it can't be grid-template-rows: auto; but i think i can be something that mean it take the same height as the children in this cell

small opinion: i hate the problems with cascade in css when it fires in my face so please no grid-template-rows: cascade;

codewisenate commented 6 months ago

I'm all for having this part of the grid spec. I would recommend simplicity over the friction of adding a new display type or even language that is not consistently used across regions (eg: masonry vs waterfall). I would go further to recommend simplifying the feature by using grid-templates-rows: collapse as this is what is actually happening. I find the rows 'off' usage a bit misleading but I would be fine with either.

Again simplicity/less friction in usage for the user seems key and having a single option to implement this as a layout option, while retaining the full power of grid and subgrid as part of the capability without adding more or divergent syntax seems like a massive win for the web developer.

eckmo commented 6 months ago

Front end develop here. I'd love to have an option for masonry within grid as described in the examples - especially as it seems to naturally fall within the realm of grid (really only changing one property vs having to implement a full new functionality for display). I think it functions well with subgrid and I'd enjoy the extra control and customization that seems to allow for. I've had designs presented from a client that were clearly designed to use masonry - I believe I wound up using columns to solve that particular need, but I was going down the rabbit hole of the various JS options before settling on columns. It was inelegant and lacked and kind of control, so this would have been a much better tool for that implementation. Given that masonry designs don't seem all that common (although maybe that's intentional, and a response to lacking a good tool to implement it), and in my opinion should be no more complex than the examples given in the article, I think this model would fit those needs well.

Would there ever be a time where the mixed tab order of items would disrupt accessibility?

marblewraith commented 6 months ago

Honestly?... I think these details are trivial.

1. Is there any use case in which the names of CSS properties impacts the end user experience?

No.

This isn't like HTML5 where proper elements / aria's are required for screen readers to function properly. These "semantics" are only relevant for the developer experience.

Consequently in this article, the following argument holds zero weight in my mind.

Another argument made by advocates of display: masonry is that that masonry is conceptually a fundamentally different layout type from CSS Grid, and therefore should have its own display type. They often describe CSS Grid as inherently being about “lining things up in two-dimensions”, and since masonry only lines things up in one dimension, “it’s not a grid”. (In fact, some have advocated that Masonry is more like Flexbox, since “both line things up in one direction”.)

Ok sure let's go with the "Akshually it's a different concept"... so what? If we're going to argue about things being be conceptually reasoned, we have bigger problems...

Coercion is still a part of JS 😑

Try explaining how some of the following examples are consistent from the simplest lexical concepts to a new coder, or even a seasoned coder who has never seen JS:

https://github.com/denysdovhan/wtfjs

The point is conceptuality can serve as a good guidepost but as demonstrated it is not necessarily binding, and once whatever the thing in question is learned, it just becomes semantic anyway.

2. Is there any use case in which the semantics of this CSS impacts the dev experience?

Given both options are being presented (masonry as part of grid, display: masonry), I have to assume either can be implemented without any performance hit?

That being true, we already know that no matter how ratchet a bit of code looks, if it gets the job done with great performance and no side effects, of course we're gonna use it.

In fact there's also an argument to be made, the more "hacky" a solution seems, provided it's not too verbose, the more enjoyable it is to learn/use as a dev. To the point where we fondly give them their own names: clearfix, OneDiv, IIFE's, Fast Inverse Squirt (Quake 3), etc.

3. Is there any use case in which the semantics of this CSS impacts the browser vendors?

Possibly? The article has the following:

we believe there’s an advantage to having these two types of grid layouts intertwined. This way the CSS Working Group will always define all new additions for both modular and columnar grids. There won’t be something added to display: grid that will be left out of display: masonry, or vice versa.

If i'm understanding correctly it means tying the details together in the spec necessarily ties the implementation together in browser engines, thus ensuring feature parity between both types of grid.

Also i find it curious it's prefaced with this:

And yes, while making CSS Grid more complex will make it harder to extend in the future

Extend... to what? Unless we're adding a Z dimension of depth for augmented reality or something? And in such a case those changes would necessitate the change of display type property for things other then masonry and grid anyway?

Direct answers

Should “masonry”/“waterfall” be part of CSS Grid?

Unanswerable by anyone not familiar CSS layout engines. My general view is, whatever's better for performance, if they're equivalent then whatever's easier to implement / maintain.

Throwing the question out to the internet, i'm reminded of the following quote (that was perverted by managers):

The customer is always right... in matters of taste.

Every dev is going to have their own take on the matter. Sure you might get some consensus islands happening, but ultimately it's going to be impossible to please everyone.

Do you want the capabilities to define a columnar grid with CSS Grid — to use subgrid, spanning, explicit placement, and all the many options for track sizing? Or do you only want the ability to define a classic masonry layout with equal-sized columns?

If there's no other "penalties", more flexibility is much more betterer.

Will you use this? What might you create with it?

I think this question is a little obvious 😑 Just think of where you've seen masonry layouts. Image gallery's (pinterest), traditional newspaper column layouts, etc.

Though there is one possibility i'd like to consider. Rendering a masonry grid takes quite a bit of calculation, it could be interesting if some of those internal functions were exposed via calc() or something.

Pelm3shka commented 6 months ago

Hello, UI Designer / Front end dev here. I've already had this type of layout several time and it always was a nightmare / so ugly to solve using only current css properties, masonry would be such a useful property to have. Here's are recent examples of this layout for my company's website :

Nos services – Suite applicative NeHo Nos solutions - Présentation générale

I vote to make it part of display: grid; as it is more intuitive to me given how similar the concept of the layouts are and to ensure we'll always have the same functionalities available than for grid.

I agree masonry and waterfall are poor terms. As a non-native english speaker, I searched ways to "offset" columns, or offset childrens in columns, so maybe grid-template-rows: offset;, with a default to grid-template-rows: align; would be a better approach than metaphors ?

andrilla-francis commented 6 months ago

First, thank you WebKit team for addressing this, and writing such a detailed blog post.

Should “masonry”/“waterfall” be part of CSS Grid or a separate display type?

It should be part of CSS Grid

To keep it short, I'll just say I agree with what those have already made a defense for masonry being part of CSS Grid. It makes the most sense to me and would offer the most functionality in a logical way.

I would also like to second @desandro's thoughts on the naming. Although "masonry" makes sense to me, I know it's an odd word that many do not understand, so grid-template-rows: collapse; would be best for an accurate description of what it does.

Will you use this at all? What might you do with it? Do you have links to demos you’ve made? We want to see your ideas and use cases.

I already use it in production

…with @supports (grid-template-rows: masonry)

I recently worked on a project for a church youth retreat. In this project, I included account pages so registrants could view and edit information after registering. Due to the nature of different inputs requiring more space than others, the masonry layout makes this section look a lot cleaner and easier to navigate.

This first picture is what most people will see, since the masonry feature flag has to be enabled. This is what you would expect by not setting grid-template-rows at all. It ends up leaving a large gap next to the address input fields, since they take up a lot of vertical space, in contrast to the conduct agreement.

Screenshot 2024-04-30 at 12 51 22 PM of normal grid layout

When I turn on the masonry feature flag, we get this consistent layout that collapses the checkmark/xmark fields to fit cleanly next to the address field. It's a small detail, but it goes a long way in making the data easy to navigate.

Screenshot 2024-04-30 at 12 51 42 PM of masonry grid layout

I'm sure you all know, I could have used two separate grids and divided the fields between them to create the two columns, but it would have taken a lot of extra work making the order of the fields flow correctly and keep relevant information together. Unlike using the masonry layout for displaying a photo gallery, displaying form info requires the grouping of relevant information, or you'll end up with a terribly confusing user interface and a frustrating user experience.

Are there things you want to do that you can’t do with this model?

grid-template-columns

As many have already said, the exclusion of grid-template-columns would be a mistake. Although grid-template-rows would surely be the primary use-case for the masonry layout, excluding grid-template-columns would be very confusing and limiting in creating responsive designs.

As more of a reach goal, but it would be nice to be able to use this masonry layout in both the columns and rows at the same time. I'd be content if we could only use one at a time, but to have them both together would be amazing for creating unique responsive layouts.

A feature that allows the developer to specify whether the last element in the grid should stretch to fill the remaining area would be great too. This would allow for an easy "bento box" layouts—especially if masonry could be used in rows and columns at the same time.

mdesco-crgl commented 6 months ago

I am creating a dashboard of widgets and cards and was looking for the perfect display option. After fiddling with grid for a couple hours, and being unsatisfied with the extra spacing between sections created when they weren't all the same aspect ratio in a row or column, I settled on flex-wrap. I am ecstatic to have found this article linked by fridayfrontend which perfectly described what I was looking for. I see masonry as a natural progression for CSS grid.

itsmanojb commented 6 months ago

This is 'grid paper' grid-paper

Q: Can somebody design a masonry layout using it? A: Yes masonry

So, this should be a part of css-grid. like, bento-grid, masonry-grid.

luxuryluke commented 6 months ago

It is similar to both flexbox and grid, and we could make several comparisons to both, but it appears to me to be a hybrid of both and lack features of both. It has columns but no rows. Or it has rows and no columns. Also, I always thought of it as "reverse masonry" since it cascades downwards. I think it should use similar attributes from both but be a specific display type.

chrisarmstrong commented 6 months ago

Would it be fair to say that the arguments so far fall into roughly two camps?

If so, then perhaps the question is: which of these approaches is more consistent with the principles of how the rest of CSS has been architected? Should declarations be based more on what a thing does, or how it does it?

sergio9929 commented 6 months ago

@dougalg-js-tw https://github.com/w3c/csswg-drafts/issues/10233#issuecomment-2071279204

I recently came across a use-case at work where we want a 2-column layout on desktop, and a single column on mobile. But we want the top item of the right column to be "in the middle" of the single column, and the bottom item of the right column to be at the bottom of the single column like so:

image

Currently as far as I know there is no way to achieve this in CSS, but with masonry grid it is quite simple to achieve, as shown in this codepen:

https://codepen.io/dougalg/pen/GRLPZea

The benefits of grid here are ability to pull items naturally into different columns following the standard grid syntax, and doing so allows to maintain tab order easily to achieve the desired flow both on mobile and desktop.

You can easily achieve it with CSS using order and display: contents, here is an example: https://codepen.io/sergio9929/pen/zYXQwPQ

schuelermine commented 6 months ago

Hi, I was directed here from this article. My opinion is that it makes sense from a functionality perspective to consider this to be grid, even if the name is “incorrect”. The functionality is useful in both layouts. However, it would also be possible to make them distinct syntactically but specify it in a way that tightly couples the options available in both layouts.

tryoxiss commented 6 months ago

NOTE: I have no hands-on experince with this yet, I didn't realise browsers had implemented anything relating to it yet. I will go play around with it soon, which may change some of my opinions.

What do you think? Try it out. Write about it on your own blog. Describe what you do and don’t like about current implementations. Create some demos of your own to explore what else is possible.

  • Should “masonry”/“waterfall” be part of CSS Grid or a separate display type??

I think that depends on how it ends up working. If it ends up being a complex layout type with many of its own options and switches, it should be seperate so long as it covers all use cases. However, in its current state its basically "grid without lining up rows", which is a pretty minor change.

Another argument for using grid is that it will inherit all of the improvements that come to it (styling grid lines (if that ever happens), template-columns, etc).

  • Do you want the capabilities to define a single-axis grid with CSS Grid — to use subgrid, spanning, explicit placement, and combining different track sizes? Or do you only want the ability to define a classic masonry layout with equal-sized columns?

To me, calling one where all columns are the same size a "masonry layout" does not sit right, but is absolutely desired.

At lesat the way I think about it:

Masonry items are slotted where they best fit, row or column. No size or number of rows/columns is determined, and items can be scaled to fit best within the layout. image

Waterfall: a set number of rows OR columns is determined, and items are placed within them to the best fit possible. Items can be scaled to fit better. image

I would be fine with using one term to contain both, in which case it should be masonry (rationale: masonry can include both, waterfall is more specific so it cant). I would like to see support for both layout types. Examples of sites that use what I described as "masonry" are DeviantArt and Steam (community art submissions mostly). Examples of what I classified as a waterfall layout are numorus.

I know that short and simple names are often prefered, and for good reason. I also understand that none isn't a possible value. May I suggest grid-template-[rows/columns]: implicit;, off, or no-rows/no-columns?

  • Will you use this at all? What might you do with it?

I would absolutely use this. I deal a lot with images (concept art, showcases, etc) and illustrations (icons, etc, vector art basically) and its annoying to need to specify grid-row- and grid-column- spans to get things looking about right. This would save me a ton of trouble.

Having this be a thing offically would encourage me to use it more aswell, such as to lay out text snippets next to each other more easily.

  • Are there things you want to do that you can’t do with this model?

What I mentioned above as masonry layouts, for which you can't really determine a column/row size.

EDIT: Changed the masonry image to one that better shows my idea.

ddamato commented 6 months ago

sWhat a ride this discussion is; so many interesting thoughts.

A few points to note before I braindump: I'm the author of gridless.design and have spent a great deal of time thinking about grids in general. Ironically, there is a masonry-like layout on my personal site; it uses the CSS column layout as I don't care much about the order, only the presentation. I've also read the blog post by Rachel Andrew regarding the alternative direction.

What I'll say is that I know from the decades of web design trends, I know the industry would benefit from the basics of a layout such as being described above. I say basics because there are certainly more complicated possibilities (some outlined in the blog post at the top of the issue) that many other folks may never need. As @desandro mentioned, the typical use is equal columns, but from the further examples there probably isn't much stopping us from defining varied column widths because the logic of how to define columns has already been in use through CSS grid. I think there is value in considering the possibility of complex layouts but it also could be scope creep. I don't think I can speak to the later questions because I probably don't have the need for these additional complexities. I just used subgrid for the first time in my latest site (the cards at the bottom) and I would have also been fine without it.

So thinking about the first question, where does the concept belong in the family of CSS properties that we could place it, I'm considering what it would mean to rethink layout entirely. I'm not suggesting what I'm about to describe as an approach, but instead using it to inform my thinking in the categorization of where this might live.

The way we describe flex vs grid is often 1D vs 2D layouts. However, grid does nearly behave like flex if it weren't for the column definitions. Children will wrap to the next line if allowed or be forced onto a single line. They both achieve this in different ways. Grid does this because of the number of columns and children, meanwhile flex will only allow wrapping when explicitly turned on. So I'm imagining a hybrid of both grid and flex, where children exist as taking up available space, packed densely until some definition comes in to influence how the packing occurs. If you only define columns, you'd get children to be sorted into the columns (in the layout we're describing here). If you only define rows, you get children sorted into the rows (a la flexbox) and if you define both, you get the grid. Children would be placed by writing mode such that all configurations will always set children left-to-right in LTR settings.

All that said and looking at both approaches, personally I'd like to see something like the following:

.my-items {
  display: block | flex | grid | masonry;
  columns: repeat(auto-fill, auto);
  gap: 1rem;
}

I see no reason why we namespace columns where CSS has a history of only being valid with certain combinations of properties and values; such as top having no affect unless a position other than static is set or when poor CSS gradient syntax is written. If the CSS written is not well formed, then it doesn't do anything special. So in this case setting display: flex; doesn't provide any column definitions even if the columns property is set. This is also related to our move from grid-gap to just gap, it is useful in other layouts.

I'm also avoiding the matter of people learning a new syntax. If someone wants it, they'll figure it out. We've gotten used to flexbox and grid after that. Whatever comes out of this we'll learn too. It's more important that this can support a need; even if the syntax isn't precisely what we might have been expecting.

meandmimicry commented 6 months ago

Sorry I don't have much to offer here but I do want to add my thoughts; I would love to see a waterfall feature implemented into CSS Grid. I believe the benefits of utilising Grid features alongside a waterfall layout far outweigh any potential performance or future enhancement pitfalls that might come along when furthering the spec for Grid.

To be honest, I would use the waterfall feature whether or not it is added to Grid, but in my mind they belong together.

I would use it within Grid to create the kind of engaging designs that Apple has demoed, I've had to make layouts like these before and often wondered why it can be so tricky when it feels to me like an intrinsic design layout people want to use regularly.

Ultimately, for me the power of Grid is its ability to let the browser do the hard work and allow for interesting layouts to emerge from experimentation, so adding waterfall to Grid would make it that much more powerful.

gorlanova commented 6 months ago

Hi, I'm quite excited to see everyone discussing to finally make masonry happen ! I've read both Webkit and Chrome articles about the subject and after thinking about it :

That's it, that's my two cents, hope it can be useful to those who will get to work on the implementation !

GrimLink commented 6 months ago

After reading Rachel Andrew's points on why this should be a separate display property, I am convinced this should not be part of the grid spec.

Same with flex it's a different way of defining a layout, although it does share many things with grid.

chasm commented 6 months ago

I refuse to use JS to get this layout, so I am effectively masonry-disabled, even if it is self-inflicted. So adding this to the CSS spec is something I am strongly in favor of.

But how it is added, too. While my initial thought was a separate display type, I am persuaded by the benefits of integrating it into grids. I like the idea of being able to suspend rows or columns. So the masonry could flow either way.

This is something clients ask for all the time. It's astonishing to me that you could need any proof at all (with examples) of the need for it. It is, truly, long, long overdue.

So +1 for leveraging the power of grids to provide masonry layouts and keeping the language consistent.

alcinnz commented 6 months ago

Another (brief) +1 for extending CSS Grid to add Masonry support, I like the builtin graceful degradation! So that any page using it won't look that bad in older browsers.

Also I might have a use for Masonry Layout personally...

eckmo commented 6 months ago

Front end develop here. I'd love to have an option for masonry within grid as described in the examples - especially as it seems to naturally fall within the realm of grid (really only changing one property vs having to implement a full new functionality for display). I think it functions well with subgrid and I'd enjoy the extra control and customization that seems to allow for. I've had designs presented from a client that were clearly designed to use masonry - I believe I wound up using columns to solve that particular need, but I was going down the rabbit hole of the various JS options before settling on columns. It was inelegant and lacked and kind of control, so this would have been a much better tool for that implementation. Given that masonry designs don't seem all that common (although maybe that's intentional, and a response to lacking a good tool to implement it), and in my opinion should be no more complex than the examples given in the article, I think this model would fit those needs well.

Would there ever be a time where the mixed tab order of items would disrupt accessibility?

I will say, the Chrome Developers make a pretty compelling argument as to why masonry should be its own display: https://developer.chrome.com/blog/masonry

The fact of dimensionality is the most convincing part for me, and the notion that some parts of grid won't be available to us when using masonry, and it will be up to us to remember those things.

Ultinio commented 6 months ago

The masonry (or waterfall, whatever we wanna call it) layout is similar to a grid, so it shouldn't have its own display type.

We can use display:grid, define the column layout (for vertical waterfall) or the row layout (for horizontal masonry), so we can have the benefits of grids, including the new features when released. our topic is rather about FILLING the grid.

Maybe a property "filling" or "grid-filling" could be masonry or waterfall (depending on the direction we wanna use). And I'm sure we can find other new values for this "filling" property...

As for names, as @ddamato mentioned, I don't understand why grid properties have to be prefixed. Ex: grid-template-columns should be columns or template-columns. But I guess, that is a total different topic

gilsonnunesfilho commented 6 months ago

Should “masonry”/“waterfall” be part of CSS Grid or a separate display type??

Including "masonry" or "waterfall" layouts within CSS Grid makes sense. It's a natural fit for the Grid model and reduces unnecessary complexity.

Do you want the capabilities to define a single-axis grid with CSS Grid — to use subgrid, spanning, explicit placement, and combining different track sizes? Or do you only want the ability to define a classic masonry layout with equal-sized columns?

There's no need to sacrifice features when we can have both. Providing the flexibility of CSS Grid for various layouts, including classic masonry, ensures versatility without limitations.

Will you use this at all? What might you do with it?

Yes, for sure. I'm aways a fan of sprinkling some asymmetry here and there.


The problem of invalid API

As highlighted by by @saivan and elaborated on by Max Hoffmann in this comment, a significant concern arises from the potential for users to inadvertently create invalid layouts.

.invalid-masonry {
  display: grid;
  grid-template-rows: off /* or masonry, or whatever*/;
  grid-template-columns: off;
}
/* invalid but still possible */

To mitigate this, introducing a new property such as grid-axes seems prudent. This property could offer options like both (default), column, or row, providing clearer guidance for developers.

.columnar-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-axes: column; /* proposed new property */
}

Handling cases where a user declares grid-template-* and subsequently disables it with grid-axes should mirror behavior seen with display: flex and align-content without flex-wrap: wrap. In such instances, functionality should be disabled, potentially accompanied by an informative message.

css-grid-3

Thus, if grid-axes is set to column, grid-template-rows would be disabled. Similarly, when grid-axes is set to row, grid-template-columns would be disabled. This approach promotes clarity and resilience through the cascade, aiding developers in making informed decisions while avoiding unintended consequences.

zarahzachz commented 5 months ago

+1 to team Safarifox on this one.

The masonry layout solution should be part of Grid, not its own display. As someone pointed out in another comment, it is sometimes hard distinguishing Flex from Grid, and being able to use features of Grid with a masonry layout feels very nice. Honestly, the masonry layout kinda feels like being able to marry Flex and Grid in a very natural way.

caraya commented 5 months ago

+1 to team Safarifox on this one.

The masonry layout solution should be part of Grid, not its own display. As someone pointed out in another comment, it is sometimes hard distinguishing Flex from Grid, and being able to use features of Grid with a masonry layout feels very nice. Honestly, the masonry layout kinda feels like being able to marry Flex and Grid in a very natural way.

How much complicated would this make the grid specification? You will have to learn all the ways where masonry and grid are different in addition to what they have in common. I don 't believe this will be trivial.

Having a separate display: masonry value means that you keep grid as is and can learn masonry as something different and specific.

justinasmussen commented 5 months ago

Wouldn't this new spec be very similar to grid-auto-flow: dense? Can we amend it to handle content of varying size, to the developer/user that appears to be the only difference? I am aware that grid is 2D and "masonry" 1D but to a dev it very similar. I'm sure there are many low level engineering reasons (or ego driven opinions) why grid-auto-flow: dense is different or can't be amended and I would like know what they are. Rachel Andrews briefly mentions this but shares no detail on why a separate spec is required.

If "masonry" is added I think it should be a new display type not part of grid. Adding it to grid will be redundant and it will be confused with grid-auto-flow: dense. Either way there will be many posts in the future asking: "What's the difference between grid-auto-flow: dense and 'masonry'?" and "Why does grid-auto-flow: dense exist and why use it?"

I really like the ideas of "sub-masonry", spanning rows/columns and being able to explicitly place items with-in a "masonry" grid.

Some name ideas: stagger, condense, offset, compact, matrix, stack. Or simply call it what it actually is: "flexgrid"

I would like to see vertical/column, horizontal/row and auto (auto arrange even if out of order) options. e.g. stagger: auto, stagger: row or stagger: column

Has the csswg even agreed on what a "masonry" layout is? There are many variations.

kbrilla commented 5 months ago

For me auto-flow-dense should work in grit-template-row: off as well. Normally they should be added as they flow in html, but with dense they should try to fill holes that were created by normal flow.

W dniu wt., 7.05.2024 o 10:51 justinasmussen @.***> napisał(a):

Wouldn't this new spec be very similar to grid-auto-flow: dense https://developer.mozilla.org/en-US/docs/Web/CSS/grid-auto-flow#:~:text=columns%20as%20necessary.-,dense,this%20leaves%20holes%20that%20could%20have%20been%20filled%20by%20later%20items.,-Formal%20definition? Can we amend it to handle content of varying size, to me that appears to be the only difference? I'm sure there are many low level engineering reasons why grid-auto-flow: dense is different or can't be amended and I would like know what they are. Rachel Andrews briefly mentions https://developer.chrome.com/blog/masonry#:~:text=grid%2Dauto%2Dflow%20doesn%27t%20apply%20to%20masonry%20and%20masonry%2Dauto%2Dflow%20doesn%27t%20apply%20to%20grid.%20Merging%20them%20would%20create%20problems%20of%20things%20that%20are%20invalid%20due%20to%20the%20layout%20method%20you%20are%20in. this but does not go into detail.

If "masonry" is added I think it should be a new layout type not part of grid. Adding it to grid will be redundant and it will be confused with grid-auto-flow: dense. Either way there will be many posts in the future asking: "What's the difference between grid-auto-flow: dense and 'masonry'?" and "Why does grid-auto-flow: dense exist and why use it?"

Some name ideas: stagger, condense, offset, compact, matrix, stack.

I would like to see vertical/column, horizontal/row and auto (auto arrange even if out of order) options. e.g. stagger: auto, stagger: row or stagger: column

Has the csswg even agreed on what a "masonry" layout is? There are many variations.

— Reply to this email directly, view it on GitHub https://github.com/w3c/csswg-drafts/issues/10233#issuecomment-2097781610, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFKBQQPTJDSQHJVQEJLSKDLZBCIYPAVCNFSM6AAAAABGPZCFRGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAOJXG44DCNRRGA . You are receiving this because you commented.Message ID: @.***>

xaddict commented 5 months ago

I want to give a +1 to display: masonry (or stack, stagger, columns, etc) here, too.

It reads better, has a single purpose and doesn't make x-template-x invalid. It lets users build upon the rules and knowledge they have of grid without complicating the syntax. Although maybe add block-align-x and inline-align-x instead of align and justify ;)

jgthms commented 5 months ago

I'm late to the party but wanted to cast a vote for display: masonry because for me, a Masonry layout is not a grid.

I just implemented CSS Grid to my framework Bulma, and the amount of properties is already high, even if some of them are shared with Flexbox. And for me:

A grid is two-dimensional because it has rows and columns. These rows and columns can be explicitly or implicitly defined. Cells can span multiple columns and/or rows.

When I'm using display: grid, I focus on defining my columns. I rarely specify the rows I want, but even then, the browser will implicitly create rows for me. And I would sometimes use these implicit rows for specific cells (like spanning a cell across 2 rows).

In a Masonry layout however, I only care about the columns. I've used and created Masonry layouts with JavaScript, and I never cared about the rows.

Take a look at this Masonry layout, taken from Webkit's blog post.

This simple Masonry layout already has a whopping 60 rows:

60 rows

I don't see any scenario in which I would actually use these implicit rows, like telling an item to "span 2 rows", because that's not how a Masonry layout works.

The usual mechanics of a Masonry layout are to:

At no point did the concept of rows come into action.

And if you look at the documentation of Masonry by @desandro (probably the best library out there), you can see how you can specify the columnWidth but there is no rowHeight, because it's irrelevant here.

That for me is why I don't consider Masonry layouts as a type of grid, but rather as another type of 1-dimensional layout.

In any case, I appreciate all the effort put into this by browser developers and the feedback provided by the community, and hope to see it implemented soon.

SelenIT commented 5 months ago

@jgthms but how treating Masonry as 1-dimensional layout could account for items spanning multiple columns, as most examples in the documentation of Masonry by @desandro show? It clearly seems to introduce the horizontal dependencies between columns (you have to check the height of neighbouring columns as well while choosing where to put the next element), and these dependencies can be considered "virtual row lines". And limiting the possible layout to single-column version would exclude "magazine layouts" like in this example.

To me, Masonry is still 2-dimensional, and @desandro himself describes his library as a "Cascading grid layout library". I see the key difference from the regular Grid, which works "from layout in" in both direction, that Masonry works from layout in in one direction and from content out (like Flexbox) in another. However, differentiating 2-dimensional "masonry grids" and 1-dimensional "masonry columns" (like "masonry" vs. "waterfall" in the comment above) might make sense.

tounsoo commented 5 months ago

Hi, a UX designer turned design technologist(which I am still confused what that title means) here.

I would agree with what @itsmanojb demonstrated in his comment.

As a designer, grid is just lines that helps me align my content. When designing a screen with masonry(waterfall) content, I would rely on the grid to design them.

Because of this reason, when I'm researching ahead before communicating with the FE who is going to make my design come to life, my google search terms would be things like css grid masonry. This aligns well with the idea of display: grid; + grid-template-row: masonry;(or what @kevin-powell suggested grid-template-row: off;.

andrewCodes commented 5 months ago

Should masonry be part of grid? Absolutely not. It should definitely be a display type in its own right. However I really don't think this is a valuable use of anyone's time. There are so many defined things in CSS yet to be implemented across browsers not to mention significant inconsistency between browsers and browser bugs. Time and effort would be far better spent getting up to speed and collaborating more rather than trying to define and make something with relatively few applications all the while arguing over the best way to do it. This entire debate strikes me as a case of browser creators making what they want to make rather than what the web, users and developers actually need.

keithjgrant commented 5 months ago

I agree that masonry should be it’s own thing apart from grid, using display: masonry or similar. I just posted a quick write up why I think so.

There are plenty of other arguments beyond this. For instance, masonry truly is a hybrid layout, more like grid in one direction and flexbox in the other. But the biggest thing for me is the learning path. It's a lot easier to learn masonry, then discover a lot of that knowledge can be applied to grid than it is to learn all of grid and selectively piece together which parts of it can and cannot apply to masonry.

I think a huge number of developers only interact with grid using grid-template-areas and that level of understanding has almost nothing that transfers over to masonry.

I think it’s okay to have a number of parallel properties between masonry and grid. That's kind of how placement already works between flex and grid (e.g. align-items works in both but justify-items only in grid). This also makes clean which grid behaviors don’t apply to masonry, since there would be no corresponding masonry property.

michaeltugby0 commented 5 months ago

Yeah, I think upon reflection, I'm adding a +1 to the display: masonry side of this debate. There are too many edge cases like what happens if both columns and rows are declared as masonry, what happens if we do a grid-row: span 2, how could we support grid-template-columns: repeat(auto-fill, auto) which would only be valid in a masonry context, etc etc. And a lot of the extra properties wouldn't work outside of a masonry context, like align-tracks, justify-tracks and masonry-auto-flow. Someone new to CSS grid would find all of this quite confusing.

To me, it would feel almost like a kitchen sink layout methodology if this went through, cramming what is essentially two different layout methods into one. And I worry about the performance implications, and future maintainability of this too (a grid level 4 would have to not only consider normal grid layout + subgrid, but masonry too - in which there may be some things added to that spec that don't make sense for masonry). If this is kept separate, we can optimize the performance for that specific layout type, and future specs can be more focused on features for either normal grid or masonry.

For my own personal use case, creating a grid with a fluid track definition, alignment options, direction options, and the ability to span an item over columns or rows would cover pretty much all my use cases.

stubbornella commented 5 months ago

@tabatkins can you speak to how you would achieve this use-case? I think you can remove the header and footer from the equation since they can be handled separately. But I'm wondering if your proposal accounts for the optional banner ? Could you still ensure that the right content, secondary nav and ads, end up in the sidebar?

Screenshot 2024-05-31 at 10 27 05 AM

I recently came across a use-case at work where we want a 2-column layout on desktop, and a single column on mobile. But we want the top item of the right column to be "in the middle" of the single column, and the bottom item of the right column to be at the bottom of the single column like so:

image

Currently as far as I know there is no way to achieve this in CSS, but with masonry grid it is quite simple to achieve, as shown in this codepen:

https://codepen.io/dougalg/pen/GRLPZea

The benefits of grid here are ability to pull items naturally into different columns following the standard grid syntax, and doing so allows to maintain tab order easily to achieve the desired flow both on mobile and desktop.

FremyCompany commented 5 months ago

@stubbornella I don't think this particular layout makes sense as a masonry layout, it's so constrained it doesn't use any mechanism of masonry anymore. I feel like the easiest and most semantic solution is to wrap the asides (secondary content, ads) in an <aside>and the rest in a <main>, then layout each as side-by-side flexboxes (desktop) or set display:contents on them (mobile) and layout all children in one single flexbox, defining relative priorities using "order". You can already do this today interoperably.

tabatkins commented 5 months ago

@tabatkins can you speak to how you would achieve this use-case? I think you can remove the header and footer from the equation since they can be handled separately. But I'm wondering if your proposal accounts for the optional banner ? Could you still ensure that the right content, secondary nav and ads, end up in the sidebar?

Of course, it would be something like:

@media (wide) {
 body {
  display: masonry;
  /* two tracks, named main/sidebar */
  masonry: "main sidebar" 1fr 200px;
 }

 #main-nav, #footer {
  masonry-track: 1 / -1;
 }
 #banner, #content {
  masonry-area: main;
 }
 #sub-nav, #ads {
  masonry-area: sidebar;
 }
}

@media (narrow) {
 body {
  display: masonry;
  /* just one track, no need for a name */
  masonry: auto;
  /* Or, I guess, just switch to Flexbox or something. Whatever. */
 }
}
/* and since there's only one track, no need to position
   the children manually */

Header and footer work just fine, you can still span multiple tracks. And of course order can be used if they need to be reordered somewhat between the two modes, just like in Flexbox/Grid.

tabatkins commented 5 months ago

I don't think this particular layout makes sense as a masonry layout, it's so constrained it doesn't use any mechanism of masonry anymore.

Nah, as I've played in the space I've found that "columns you can assign things to" is a very reasonable use-case, and fits within the confines of a Masonry spec very naturally. Literally the only thing you need to support this entire layout is the ability to have items span multiple tracks (already a well-established core use-case) and the ability to assign items to a specific track (less common, but trivial to adopt, and very natural when reusing concepts from Grid for the placement properties; it would be weirder to not allow that, actually).

The only downside of shoving this use-case into Masonry is that you still get the limitations of "size as you place", which restricts how you can size tracks, even tho all the items have a known placement location up-front. But still, that's a relatively small price to pay, I think (and is theoretically fixable in the future, if we decide to...)

tabatkins commented 5 months ago

Alternately, cases like this can be solved within Grid using grid-flow, as I proposed in https://github.com/w3c/csswg-drafts/issues/9098. The example given at the end of that first comment is extremely close to what @stubbornella was asking about. Then you don't have the layout downside, either.

FremyCompany commented 4 months ago

@tabatkins Strong +1 for grid-flow as the proper solution in a grid context.

I didn't intend to say that this layout should not be achievable in masonry (good that it is!) but it doesn't feel like natural fit to me. Also, I wanted to push back on the claim this is not implementable natively today, it totally is, with just flex, order and display: contents.

steffchep commented 4 months ago

in follow-up to Tab's excellent presentation at #cssday 2024, regarding wether it should be part of the grid, or a separate display: I would prefer to see it as a separate display: masonry. It's just enough different from what a grid does to lead to confusions, and the grid is already very powerful and as such, complex, without the extra of having another layout built into it.

benface commented 4 months ago

I didn't intend to say that this layout should not be achievable in masonry (good that it is!) but it doesn't feel like natural fit to me.

I totally agree @FremyCompany. In fact, before I stumbled upon this thread, I posted my thoughts on that layout here after seeing @stubbornella's talk at CSS Day 2024, in which she presented it. :) While it is possible to achieve that layout with Grid + Flex + display: contents like you mention, it would be nice if Grid alone supported it, with a flat HTML structure. And I've had the need for the "grid flow" behavior in other places, too; it's nice to see that it's being talked about.

rol4nd909 commented 4 months ago

I recently came across a use-case at work where we want a 2-column layout on desktop, and a single column on mobile. But we want the top item of the right column to be "in the middle" of the single column, and the bottom item of the right column to be at the bottom of the single column like so:

image

Currently as far as I know there is no way to achieve this in CSS, but with masonry grid it is quite simple to achieve, as shown in this codepen:

https://codepen.io/dougalg/pen/GRLPZea

The benefits of grid here are ability to pull items naturally into different columns following the standard grid syntax, and doing so allows to maintain tab order easily to achieve the desired flow both on mobile and desktop.

Hi I have more or less the same use case, and I think it's a common pattern for a e-commerce product-detail page.

Most of them have a Product image/gallery on the left and next to it a buy-block and on a smaller screen they should stay together, but you don't want any whitespace below the image or below the buy-block

I made a screenshot so I hope you will understand it a bit better.

Screenshot 2024-06-13 at 16 17 31

first (brown block) is Image/Gallery, the (blue block) is buy-block and the rest are al kinds of blocks that can come in all kinds of types.

The current situation is that they use 2 templates a single column for small devices with a device check, and 2 columns for desktop like devices. But Ideal you just want 1 template for it.