Nothing Special   »   [go: up one dir, main page]

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] Designer/developer feedback on masonry layout #10233

Open
jensimmons opened this issue Apr 19, 2024 · 119 comments
Open

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

jensimmons opened this issue Apr 19, 2024 · 119 comments
Labels

Comments

@jensimmons
Copy link
Contributor
jensimmons commented Apr 19, 2024

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.

@w3c w3c deleted a comment from Loirooriol Apr 19, 2024
@TALlama
Copy link
TALlama commented Apr 19, 2024

I used the Masonry jQuery plugin back in the day for a few things, and I've missed it in a number of places since then. I've even built similar systems with JavaScript and CSS Grid, by defining absurd numbers of rows and dynamically calculating a row span for each item, which allowed me to do some of the neat column-spanning and column-picking seen in Jen's examples.

Extending CSS Grid with "masonry rows" seems like a great idea to me, and the right place for it. That would allow us web devs to grow our existing knowledge as the possibilities grow, and to leverage our existing code and understanding as we do so. We've already seen how flexbox and grid are (wrongly) viewed as competitors; adding yet another fundamental layout would just confuse things more. Empowering the layouts we have is the better option.

@hermosawave
Copy link

I agree that masonry is a type of grid and should be implemented as such.
I also used the Jquery plugin back in the day, it would be nice to have this functionality in CSS. I've had to implement a sub-optimal version of this as a result.

@chrisarmstrong
Copy link
chrisarmstrong commented Apr 20, 2024

I think masonry (or whatever it ends up being called) should be a part of CSS Grid, for a few reasons:

  • As a designer, a masonry grid is conceptually still just a grid. It has all the same considerations as a regular grid (column width, gap size, etc), except for the way elements stack. Everything that is useful in CSS grid (subgrid, multi-column elements, asymmetrical grids) would also be useful for masonry grids.
  • As a front-end developer,I already struggle to wrap my head around the differences between flexbox and grid, and when to use one vs the other (though I appreciate the power both afford). Adding another conceptual model to that mix is just adding to the confusion, with no clear user benefit... the only benefit seems to be for the browser developers (which is important too, but surely the additional effort required to integrate and maintain masonry within grid will be outweighed by time saved with reduced developer confusion).
  • As a business owner, I have substantial commercial evidence that masonry layouts are valued by users. Niice.com’s business has been effectively built on offering an easy way for customers to create microsites with masonry-style layouts (including, importantly, elements that span multiple columns). Customers like PlayStation, Nordstrom, Paramount, Fox and more have chosen us specifically because of the layouts they can build on our platform, and we’ve had hundreds of thousands of brand designers, photographers, fashion designers, interior designers, boat designers, product designers, jewellery designers, illustrators and more use it to create layouts that wouldn't be possible without the upside-down Tetris logic of masonry (as you can tell from that list, it’s particularly valuable when presenting visual content). I’ll try to pull together some examples we can share.

~

Side note: One thing we've discovered over the past 10 years has been the importance of being able to intuitively predict how a masonry grid will re-flow when content is added to or rearranged within it. Let’s say you have a Pinterest-style image grid, and you load in an additional 50 items... if all the existing items suddenly jump around and switch columns etc that gets really disorienting for users. Same goes for making an element span multiple columns... you don’t expect that to suddenly rearrange the entire grid, simply the content below that element (like upside-down Tetris). I’m hopeful CSS grid’s ability to specify a column position will help with this, which is another reason to build on the existing Grid spec.

@DanielHeath
Copy link
DanielHeath commented Apr 20, 2024

Key thoughts on this proposal:

  1. Should this be part of CSS grid? I agree it should, if (and only if) it can be implemented orthogonally to other grid features. By that, I mean it should do something sensible when combined with every other grid option. If that's not likely to happen (consistently, in each browser), I don't think it should. This really needs to have a suite of conformance test pages fairly early on.

  2. It's unclear whether grid-template-columns would be equally supported - IMO not doing so would be a serious mistake, because everything else in grid works equally on either axis

  3. I've seen various requirements RE the slot fill order for masonry layout. grid-auto-flow doesn't appear to work with masonry layout in safari tech preview.

  4. Other grid features: Spanning and track sizing are very common requirements. I struggle to think of a sensible way to use explicit placement with masonry, although I'm sure someone will. Subgrid might be useful with spanning, although it feels very complex and I'd expect implementations to vary sufficiently that I probably couldn't rely on it for authoring.

  5. Spanning columns is of virtually no use (I'll still end up having to use JS or something anyways) without a way to control how the extra whitespace this creates is positioned (eg I set justify-content: space-between; align-content: space-between, but the extra whitespace all ends up below the image - see image).

Minor nits on the demo at https://webkit.org/demos/grid3//photos/ :

  • [EDIT: somehow I failed to see the extremely obvious "number items" checkbox] It would be nice to have a title attribute with "item 1", "item 2", "item 3" etc so you can hover to visualize the grid flow without resorting to the devtools
  • There's heaps of CLS on a slow connection because the img tags lack an aspect-ratio
  • making the <code> block live-editable would be very nice.

@charlesmunson
Copy link

I've worked with CSS for what, twenty years, and been a web dev since 1995. Yes, we want this. Masonry layout would solve so many problems for my art and photography websites. Even today I had to fire up Gimp to resize photos for different aspect ratios.

@LorenAmelang
Copy link

I see Jen's promotion of this in my Fedi feed, and I just tried some of her demos, especially the photos demo. I guess my concern is not particularly with 'Masonry' but with the 'modern' trend toward web pages designed for huge screens. I have two main routes (limited by lousy vision). The smallest iPhone, where after a confusing delay the photos demo reverted to a vertical scroll of single images (that didn't seem connected to the grid images I'd been able to see). And a 1920x1080 Linux view where what's left of the browser window after headers and toolbars took about a minute to fill up with one-third of the full example - many images a half-inch across. Scrolling to the other 2/3 happened painfully slowly, with the image grid filling in random order.

Maybe I missed it, but is there any 'Responsive' technology being discussed to make these new web features work for people who don't have the huge screen area to take advantage of them? Or for people dependent on Alt text? WAVE shows no Alt text at all in the demo. And if there was, a grid of 51 images would be a bit much to navigate...

In that vein, WAVE finds no headings! "Headings ... provide important document structure, outlines, and navigation functionality to assistive technology users." There really needs to be some rational structure within the page for those of us who can't just glance at the whole wall of images at once!

If someone knows a better place to post this issue, please suggest!

@LorenAmelang
Copy link

@DanielHeath
Just noticed this:
There's heaps of CLS on a slow connection because the img tags lack an aspect-ratio

Is that why my view loaded so slowly? Granted I'm at the far end of 30 miles of WISP radio, but my 10 Mb usually loads web pages in milliseconds, not minutes.

@SaraSoueidan
Copy link
SaraSoueidan commented Apr 20, 2024

Anyone who's been a part of the dev community long enough and who has been talking and listening to designers and developers in the community knows that we do want masonry layout. We may not all be working on "big websites", but we are the ones building the Web.

I cast an additional vote to including masonry as part of the CSS Grid layout system, not a separate display value, for all the reasons @jensimmons mentioned in the article. All of them.

I have been waiting for this layout for to become possible in CSS for years. And it only makes sense that we get enough control over it like we would with other layouts. I believe one of the reasons CSS Columns are not as widely used as one would hope is because they are limited and not flexible. We do want control over column widths. And it only makes sense that Grid Level 3 be able to leverage all the capabilities of Grid Level 1 and Level 2.

Thank you Jen and the Webkit team for pushing to make this feature actually usable.


UPDATE: I've read Rachel Andrew's post which explains the alternative proposal for Masonry. I think this post was a much-needed clarification.

Seeing that both proposals would give us the flexibility to design and implement the layouts in Jen's post, I no longer have a strong preference as to which property or spec Masonry goes into. As a developer, I want the flexibility to build creatively. Whichever way we get to do that will be welcome. I appreciate everyone involved in this discussion and who is working to push this feature forward.

@tomchiverton
Copy link

Masonry, however implemented, should exist. Photo albums would be a use case I would put this too. Non-symetric would be nice to have because of a mix of aspect ratio.

@michaeltugby0
Copy link
michaeltugby0 commented Apr 20, 2024

We recently implemented a masonry grid as part of our website's dashboard, which held a list of infinite-scrolling cards, and we opted to use CSS Grid for it because we wanted control over the columns (using grid-template-columns: repeat(auto-fill, ...)) like you mentioned. For the rows, for now, we used a bit of JS to give them all a grid-row: span ... based on each childs height. It's definitely something I'd love to have to be able to progressively enhance this behaviour and remove the need for JS.

In general, it would also be much easier to progressively enhance too in grid. Just add a grid-template-rows: masonry, if it's not supported, no problem, we get the default grid row generation with cards stretching to fit, which is what I would want as the fallback. Whereas with display: masonry, that would most likely require an @supports and/or duping layout rules.

@chriskirknielsen
Copy link

While I already agree with everything mentioned, just adding my own thoughts below:

I've recently shipped a project that could have made great use of masonry layout for a "mega menu". We ended up using standard multicol to get a similar behaviour, but each group has to be manually placed to optimise how much space they take (some have 2 sub-items, other have 8), so it ends up being tedious to place all the pieces. Masonry would make that very easy and solve common layout problems on many projects.

As far as the display debate, I'd be in favour of keeping everything as grid. This allows me to remember a single set of properties that work consistently, simply expanding what I know instead of learning new rules, and to easily switch between the behaviours should I need to revert — or more likely, progressively enhance an existing grid.

Regarding the naming, the obvious alternative is columnar but holy heck would that be confusing: grid-template-rows: columnar (and if you read further ahead in my comment, would grid-template-columns also be columnar…?). I like the off idea, short and sweet, though I could also see something like:

  • stagger, maybe there's a better, similar term?
  • loose, authors can have trouble with this word vs lose and it might induce typos… alt: free?
  • unbound, as in, not bound to any track (which feels only half-true), alt: detach/detached?
  • float, okay now this is worse… but the "floaty" idea seems right, or like how oil and water have different buoyancy values, they "float" at different levels… though this is also a metaphor, and not a better one that masonry
  • (would have loved auto but like none that is already a valid value)

Finally to piggyback on @DanielHeath's comments:

It's unclear whether grid-template-columns would be equally supported - IMO not doing so would be a serious mistake, because everything else in grid works equally on either axis

I am wondering about this too. While I wouldn't need it as much, I'd definitely like that flexibility.

And a nitpick of my own:

There's heaps of CLS on a slow connection because the img tags lack an aspect-ratio

Not only the lack of width/height (which, ironically, I now consistently do because of Jen's push on that some years ago 😄) but also the 1MB+ PNGs in the article can easily be optimised.

TL;DR: Overall, feeling very positive about all of this!

@keller-mark
Copy link
keller-mark commented Apr 20, 2024

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

As part of CSS yes, but I am more agnostic about whether it should be part of grid vs. a different display mode.

It seems to me the main pro for being part of grid would be that the fallback behavior would be more reasonable.

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

The article only discusses (and shows demos of) a column-based / vertical orientation. However, the feature should also support row-based / horizontal orientation for a use case like the Flickr gallery layout:

Even if not supported initially, the syntax should be designed with this future possibility in mind, so

display: masonry-columns (or display: masonry; masonry-direction: columns) as opposed to simply display: masonry. The grid-template-rows: off would also be sufficient.

EDIT

It was pointed out by @rileybathurst in a comment below that the demo includes two Horizontal options: Horizontal Masonry and Horizontal Flexbox.

Screen Shot 2024-04-27 at 11 07 23 AM

However there are nuances to the Flickr version that differ from both of these:

  • With Horizontal Masonry, the page simply scrolls horizontally instead of vertically.
  • With Horizontal Flexbox, the contents of the images are cropped.

The big difference with the Flickr masonry is that the heights of the rows are dynamic based on the aspect ratios of the bricks in each row. The CSS masonry should also support this option to have dynamic row height (in the case of Flickr) or dynamic column width (in the case of the column-based support described in the blog post) based on the aspect ratios of the contents, so that the ends of the rows/columns are flush with the right/bottom sides of the container, respectively, and the clipping of brick contents is avoided.

@brandonmcconnell
Copy link

I think keeping everything part of grid would be simplest in terms of use with other properties.

@chartgerink
Copy link

Hi 👋 Thanks for the opportunity to share some thoughts - I really liked the article and it comes at a fantastic time as we are doing redesigns of our website. This has been inspirational!

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

Yes.

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?

Variable column sizes would be preferable. These allow for wider range of design options, and I would expect it to not be an uncommon design pattern. The use of subgrid would also be a fantastic capability that I would prefer to see included.

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

We offer users a way to curate (research) works and are looking to provide them with a visually appealing, dynamic, and scalable way to present the curated content. We want to provide them with an option to present their curated works in magazine/print quality layouts, without having to put in much work to do so. The columnar grid would be perfect for this.

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

I also wondered about horizontal options, similar to a previous comment raised. I can imagine this also to be an interesting design element if at all possible.


I have not previously contributed to a W3C discussion, so if I missed anything in how to contribute, I am happy to expand further upon request 😊

@kitgrose
Copy link

I prefer this being part of CSS Grid too.

If all the columns are intended to be the same width, it makes this feature feel very similar to the columns behaviour—one container separated into multiple columns—albeit with children flowing across the columns rather than down them. In fact, it feels somewhat related to the column-fill: balance property, since it's similarly attempting to pack each column evenly.

If this was to be implemented as a new display style where all the columns were the same width, it should also support the use of the order property, which provides a lot more flexibility in responsive layouts to get elements balanced nicely.

In any case, if it doesn't end up being implemented as part of Grid, you can expect that authors will often embed grids inside each element to align captions, etc., which seems inherently more work for the UA to handle than a single shared base grid accessed through subgrid.

Some usage scenarios that would benefit me:

  • I'm currently emulating masonry layout on some sites for things like testimonial grids using Flexbox containers in side-by-side grid columns, but that has proven a real hassle when implementing responsive design, since the DOM contains the explicit column containers, and the DOM and screen-reader order doesn't reflect the order experienced by sighted users.
  • I've also done similar layouts in mega menus, similar to the one shown in the article.
  • Dashboard layouts with many cards, each containing charts, alerts, or other infographics. Visually these end up making an arrangement similar to the ones Apple uses for their summary slides at their keynotes (which I concede could probably be done with conventional grids today, albeit with less flexibility for tile sizes).

@desandro
Copy link

Hi! Author of the Masonry JS library here 👋 . I am stoked to see Jen and the WebKit team prioritize making Masonry a first-class citizen in the browser. My heart-felt gratitude ❤️

Custom track sizing vs uniform column width

In my experience, the vast majority of users want uniform column width. CSS grids provide so much power over layout with track sizing. I think that amount of customization over the tracks is an unwanted feature when working with masonry layouts. Typically with a masonry layout, you want the item to have the same size regardless of its position in the grid. So, if you want to be practical, go with display: masonry, this will satisfy 95% of masonry layout usage.

"display: masonry" vs "grid-template-rows: masonry"

Having said that, grid-template-rows: masonry maps to my mental model of how Masonry works, now that CSS grid is an established convention. Personally, I'd like to see "masonry" used as the value name, as it's the convention with 14 years of history. I could also go with grid-template-rows: collapse, as it describes the behavior better.

Follow-up issues

Here are some issues that I know will come up. I don't think they need to be solved in this spec/implementation. But they are worth thinking about during this concepting phase.

Loading images

Day 2 issue for implementing a Masonry layout is dealing with shifting layout caused by loading images. With a masonry layout, the problem is exacerbated as taller cell element causes subsequent cells elements to move to a different column. The issue is best address by setting aspect-ratio or better yet width and height attributes on the <img>. I'd say it's outside the scope of this proposal to solve for unloaded images in the spec. But, the issue should be addressed in documentation.

Expanding cells and maintaining position

@chrisarmstrong mentions above:

One thing we've discovered over the past 10 years has been the importance of being able to intuitively predict how a masonry grid will re-flow when content is added to or rearranged within it.

The classic Masonry layout will shift a newly expanded cell element to the next possible position

masonry.resize.mov

But users just want the item to open up where they clicked it. I actually had to build a separate layout library, Packery, with a bin packing algorithm to solve for it

packery.fit.mov

Maybe something like grid-row: maintain could address this

Keeping horizontal order with a masonry layout

A good amount of people requested that Masonry have more leeway in its layout algorithm so that horizontal order could be maintained. I eventually added a horizontalOrder option to Masonry.

WQVtdGp


Thrilled to see this work. I'll be following this thread merrily.

@jeff-wolff
Copy link
jeff-wolff commented Apr 22, 2024

Yes. Seems like the logical progression of CSS grid. Something that shouldn't be done with JavaScript anymore.

@scriptype
Copy link
scriptype commented Apr 23, 2024

Hi all, while reading the article, I thought about the possibility of having the masonry as a new display value that can sufficiently interoperate with grid properties, like the flex currently does (e.g. gap, justify-* / align-*).

This would perhaps ease the mental model for developers and designers, and perhaps simplify the browser implementations, since it will not automatically (and possibly incorrectly) force every grid feature to work with the proposed masonry mode. Instead, the masonry could grow its own vocabulary free of other grid features.

But on the other side, the new display type would just work™ with the most relevant parts of the grid layout (e.g. fine control over columns, gap).

I personally have no strong preference/opinions on either way. Masonry in any form would be a leap forward.

Also, I think the spec should warn us of possible accessibility pitfalls, like:

Maybe I missed it, but is there any 'Responsive' technology being discussed to make these new web features work for people who don't have the huge screen area to take advantage of them? Or for people dependent on Alt text? WAVE shows no Alt text at all in the demo. And if there was, a grid of 51 images would be a bit much to navigate...

In that vein, WAVE finds no headings! "Headings ... provide important document structure, outlines, and navigation functionality to assistive technology users." There really needs to be some rational structure within the page for those of us who can't just glance at the whole wall of images at once!


Thanks! 💛

p.s. Just found a much better explanation to the idea of "segregation with some interoperability" here (from @rachelandrew): #9733 (comment)

@dougalg-js-tw
Copy link

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.

@seyedi
Copy link
Contributor
seyedi commented Apr 23, 2024

Lots of devs seem to find CSS Grid difficult to understand and use. They'd love a super easy way to do Masonry, like this:

main { 
  display: masonry;
  columns: 28ch;
}

But this other way, with all the brackets and stuff, is almost as scary as CSS Grid syntax itself, so I wouldn't go for it:

main {
  display: masonry;
  masonry-columns: repeat(5, minmax(28ch, 1fr)); 
                   /* where only one repeating width is allowed */
}

However we will eventually need those extra syntax for more controls, so...

For the reasons Jen mentioned, I'm all for adding masonry to CSS Grid layout.

@DanielHeath
Copy link

@desandro That's a great point RE horizontal order - eg item 11 in the mega-menu demo being positioned to the right of item 12 is correct, but looks totally wrong (see screenshot).

image

@oscarotero
Copy link

I think masonry should have its own display value instead of being integrated in the grid spec. Reasons:

  • The difference between a regular grid and a masonry grid is just as different as grid and flex.
    • In fact, if masonry had to be integrated in one of both, I think it should be integrated in flex rather than grid because the behavior is more similar to a flexbox (one-dimenson flow).
  • Grid is already a pretty complex feature. Adding masonry features will make it even more complex and hard to understand.
  • There are already some new properties like masonry-auto-flow, justify-tracks and align-tracks that were created only for masonry but don't make sense for other grid use cases, which is confusing.
  • In the same way than grid and flex share some properties like gap, align-items, justify-content, etc, grid and masonry can share only the properties that make sense for both.
  • In general, it's better to have multiple small solutions than one-fit-all solution.

@kbrilla
Copy link
kbrilla commented Apr 23, 2024

Please, mayby create an questionnaire like with nesting, to gather more votes on the matter.

@txdm
Copy link
txdm commented Apr 23, 2024

Lots of devs seem to find CSS Grid difficult to understand and use. They'd love a super easy way to do Masonry, like this:

main { 
  display: masonry;
  columns: 28ch;
}

But this other way, with all the brackets and stuff, is almost as scary as CSS Grid syntax itself, so I wouldn't go for it:

main {
  display: masonry;
  masonry-columns: repeat(5, minmax(28ch, 1fr)); 
                   /* where only one repeating width is allowed */
}

However we will eventually need those extra syntax for more controls, so...

For the reasons Jen mentioned, I'm all for adding masonry to CSS Grid layout.

I believe both could be made to work, eg: masonry-columns: 28ch for a simplified/shorthand version, or masonry-columns: repeat(5, minmax(28ch, 1fr)); if someone wants to be more specific.

I think it should be masonry-columns instead of just columns to disambiguate it from the existing columns

@saivan
Copy link
saivan commented Apr 23, 2024

I know there was no mention of column masonry layouts, I'm just wondering "why not". I'm all for display: grid being extended, it's also quite logical in my view. I think the proposed syntax is a logical syntax, you're effectively independently defining a masonry layout in either direction. One difficulty for me would be, how should the following behave?

display: grid;
grid-template-rows: masonry;
grid-template-columns: masonry;

This could be a messy layout as follows:

image

Or should this be an error condition? If this shouldn't be allowed, it would be a slight problem for me, because it seems to break the line independence of css. Now by adding line 3, you've effectively broken the way line 2 should work. So this case would need to lead to a reasonable layout.

But then my question would be, is this still a grid?

Also, how do I specify the layout direction, because this would also be a valid way to lay out the exact same boxes:

image

Then we have problems of "how we should align them" or how they should be reflowed to fill the available space. But these are all initial issues that I'm running into when imagining this.

@tabatkins
Copy link
Member

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

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

Alternately, cases like this can be solved within Grid using grid-flow, as I proposed in #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
Copy link
Contributor

@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
Copy link
steffchep commented Jun 10, 2024

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
Copy link
benface commented Jun 12, 2024

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
Copy link
rol4nd909 commented Jun 13, 2024

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.

@harunaamadu
Copy link

There's no harm in trying. I think display masonry and waterfall will best fit in the grid because they come much in common. But separating them too is not bad as it will reduce the code lines making things simpler.

In any way they appear creative people will use it to achieve great and eye-catching designs.

Or better still they can be versatile that is, they can be used independently or as in display grid.

@rileymcmaster
Copy link

Thanks Jen Simmons and Rachel Andrews for writing such in-depth articles about the future of CSS!

After reading both the Jen's Webkit and Rachel's Chrome articles, I would say I'm leaning towards masonry being its own display type. The masonry layout is more concerned about one axis like flexbox, rather than grid's concern over both axes.

If masonry was added to the grid spec, I think the amount of properties that do not cross-over from one layout to the other would make troubleshooting issues a big pain. Some values seem logical with masonry while should throw errors in grid : repeat(auto-fill, auto).

I use grid constantly and am well versed in the syntax and I think masonry should share a lot of the terminology and functionality but they should still be separate display types.

One is issue I have with the Webkit article is their case for subgrid. I've tried shoe-horning subgrid into projects several times and it never really makes sense to me. In their example (I understand it's an example and maybe not the best real-world scenario), I think it would make more sense to define the layout of the card so that the cards are all uniform. Their use of subgrid seems arbitrary since every card is taking up two columns, one of those columns on the parent is just to align child's content. That seems like classic case of over-parenting.

@sgarciagallego
Copy link

Great to see the discussion at WebKit and Google alike, both with differing opinions on whether masonry should be an extension to grid or it's own display type. I personally believe, from a visual standpoint, that masonry is a type of grid, and as such should be able to be implemented through the grid-template-rows: masonry; declaration.

As well as this, I was looking into how Google were looking into an implementation of the masonry/waterfall layout, and was confused by what seemed like a top-to-bottom then left-to-right approach to ordering items, even if not explicitly mentioned. I believe this should be able to be implemented left-to-right then top-to-bottom, following the current natural reading patterns.

@Aps-x
Copy link
Aps-x commented Jul 30, 2024

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

Recently, I was working on a timetable website that displayed information about class times. The user could have any combination of different classes, so the layout would have to respond dynamically to different content (per column). Just like this example (that uses JavaScript):

Demo

I think this is a perfect use case for horizontal masonry.

I tried to achieve this layout with just CSS and no JavaScript, but I found that I was unable to. CSS Grid with auto columns comes close, but I couldn't get the cards to fill in available space. If the content was static, it would be no problem, but the content is dynamic and I can't provide an explicit column span ahead of time.

I wanted a layout option that was in-between Flexbox and Grid; in other words, I wanted a single-axis grid. In this case, I needed rigid rows without columns so the cards could be explicitly placed on rows but have flexible widths.

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

Not exactly the model, more a specific implementation, but I messed around with the current masonry implementation in Firefox and it came close to what I needed. For the use case I was talking about, it would be great if I could set a card to have a width of 1fr and have it fill in available space. Also, grid-auto-flow: dense; only seems to pack in one item rather than as many that can fit.

@ddamato
Copy link
ddamato commented Jul 30, 2024

I tried to achieve this layout with just CSS and no JavaScript, but I found that I was unable to. CSS Grid with auto columns comes close, but I couldn't get the cards to fill in available space. If the content was static, it would be no problem, but the content is dynamic and I can't provide an explicit column span ahead of time.

IMO, I think your example is better suited for CSS Grid than masonry. In fact, this would be great with named lines:

#calendar {
  display: grid;
  grid-template-columns: [monday] 1fr [tuesday] 1fr ...;
  grid-template-rows: [t0900] 1lh [t0915] 1lh ...; /* Probably needs to be generated, needs a lot of lines. */
}

#COMP3704_S2_1 {
  grid-column: monday;
  grid-row: t1000 / t1130; /* Must start with alpha, omitting special chars */
}

For conflicting events (like the first events on Tuesday in your example), I'd probably consider subgrid to continue aligning with the times but try repeat(auto-fill) for the column. Definitely an interesting problem regardless! Might even give it a shot myself in my free time. Thanks for sharing.

@Aps-x
Copy link
Aps-x commented Jul 31, 2024

@ddamato Thank you for your reply! I am admittedly not super experienced with CSS, so there might be something obvious I am missing.

Here is a demo of the layout I think would be good with horizontal masonry (I messed up the code embed):
index.txt

I think seeing the problem visually might do it more justice than my attempt at explaining it in writing. Grid doesn't have an equivalent to flex-grow where cards can grow to fill in a fraction of the space. They have to span discrete columns and you have to explicitly provide this ahead of time. To be clear, the issue is having cards fill in all available space when the cards are placed dynamically.

Sorry if I am wrong, I don't mean to derail the conversation, but is this not a problem that could be solved with grid-template-columns: masonry; ? Is it already possible to do this with just CSS?

@nt1m
Copy link
Member
nt1m commented Sep 10, 2024

I found this layout: https://x.com/dwinawan_/status/1833369698282476018

@Link2Twenty
Copy link

I found this layout: https://x.com/dwinawan_/status/1833369698282476018

The bento grid is quite easy to replicate in the existing grid. I don't think masonry layout would be used to create it.

@ShaunaGordon
Copy link

I feel like I'm in the minority with @tryoxiss, who has pointed out that it's possible to have masonry layouts that have neither fixed rows nor fixed columns. I've read through all of the comments and if there are any others noting this, they're few and far between, despite it being what I'd consider to be a "true" masonry layout. In fact, I like the distinction they make between masonry and waterfall, because those are two fundamentally different layouts that just happen to achieve a somewhat similar result if you don't look too closely. I get the sense that the responses so far have been kind of stuck by the current limitations of masonry implementations, stymieing the potential of this feature to break free of those limitations.

If "masonry" is only ever defined as "defined rows, undefined columns" or "defined columns, undefined rows," then sure, put it into grid, but if there's ever the possibility of allowing the "fit them together like a jigsaw" style that tryoxiss illustrates, then shoehorning it into grid is shortsighted, in my opinion, because you end up throwing out most of grid's features, instead of just some of them to make this layout, and you inhibit your ability to add features that would pertain to waterfall or masonry, but not to grid, without having to make concessions that those additional features are just invalid with certain other combinations. In light of that, it seems better all around to separate them -- it's clearer for the front end developer what display paradigm an element is working under and more predictable for what does and doesn't work, and it doesn't take as much overhead for implementers to figure out all the combinations that do and don't work for directives that are otherwise valid for that display paradigm.

Now, if it is part of grid, it does create a rather obvious solution to the question raised earlier of "what happens when grid-template-rows and grid-template-columns are both set to off?" At that point, it would/could be the "true" masonry, whereas when only one or the other is off, it creates a waterfall layout. ...But at that point, if we turned off both rows and columns, are we even talking about a grid anymore? Isn't the whole purpose of a grid...rows and columns? Not having one is stretching it, in my opinion. Discarding both breaks it entirely.

To me, having grid, waterfall, and masonry as separate options for display makes the most sense. display concerns itself with content flow, both of the element in relation to its siblings (block, inline-block, inline) and in relation to its contents (grid, flex, table), while the individual settings determine the details of how the elements flow, without significantly changing the overall flow model set by display -- spanning a row or column doesn't mean the element is no longer working within the context of a grid or table, for example. Waterfall and masonry are different flow models from grid and flexbox, for the aforementioned reasons, and thus warrant their own options on display.

(tl;dr - +1 for display: masonry)

@essenmitsosse
Copy link

This feedback might not align exactly with the original intent of this issue, but since the discussion is happening here, I’ll share it anyway:

TL;DR: Masonry is a good grid to have, but the proposed implementation is too specific and opinionated. Instead of adding more and more "predefined" layouts, CSS should offer more general tools for developers to define their own layout logic.

I believe that while flex and grid introduced useful features, they represent a step in the wrong direction overall, and implementing Masonry via CSS Grid Level 3 would likely make things worse. My main issue with these technologies is that they implement highly opinionated constraint-solving algorithms, which can be opaque in terms of both the layouts they enable and how to achieve them. Both flexbox and grid allow for a wide range of layouts, but there are also many that feel like they should be possible, yet aren’t. I expect the same will be true for Masonry — there will inevitably be certain layouts it won’t support, forcing developers to fall back on JavaScript for manual implementation. Worse still, it’s likely to be unclear where those limitations lie.

Moreover, Masonry is a very specific design that solves a narrow set of problems while creating a distinctive, but somewhat dated, visual style. It’s less of a general UX pattern and more of a late-2000s aesthetic. I’m not sure CSS properties should encourage such specific design choices; rather, they should function as general-purpose tools. Adding a feature like Masonry will only encourage more uniformity across websites. And if we add Masonry, why stop there? Should we also add other grid layouts tailored to different styles? While flex and grid are justifiable as general-purpose tools, Masonry feels like it crosses into being overly opinionated.

At this point, CSS is becoming more like a full programming language, but instead of moving toward making it more general-purpose, we’re adding new predefined functions (display: grid, display: masonry) with increasingly convoluted arguments (grid-template, align-self, etc.). I think we should acknowledge this trend and consider making CSS more flexible and general instead of more specific. Rather than adding more predefined layouts, we should provide developers with tools to define their own constraint-solving algorithms. Features like calc() and variables have already brought CSS closer to this ideal, and custom layout algorithms seem like the logical next step. Introducing Masonry feels like add() and mult() would have been added, instead of the general purpose calc() we luckily got.

In summary, while the ability to create a Masonry layout in CSS would be valuable, I don’t believe an overly specific specification is the right solution. Developers should rather get the tools to implement their own Masonry.

@ShaunaGordon
Copy link

@essenmitsosse What kinds tools do you suggest that would be sufficiently generic enough and easily provide the ability to create masonry style layouts?

@Loirooriol
Copy link
Contributor

@ShaunaGordon Not sure if it's what essenmitsosse was referring to, but there is https://drafts.css-houdini.org/css-layout-api/

@essenmitsosse
Copy link

@Loirooriol ah thank you! Wasn't aware of that proposal. Your link doesn't seem to be working (currently), but here is a good explanation.

And: Yes! The Houdini proposal is definitely something I would prefer over "hardcoding" another algorithm, as per the arguments I mentioned in my initial comment.

@oscarotero
Copy link

IMO, Houdini proposal is a way to insert JavaScript in CSS, which means if JavaScript fails for some reason (and probably fail), the CSS will fail too.

CSS is a powerful programming language that should be enough by itself, we don't need to "complete" it with JavaScript.

@essenmitsosse I understand your point of view, but keep in mind that CSS is a declarative programming language to build interfaces, is not imperative like JavaScript. Declarative languages are always opinionated and domain specific (the oposite of a general-purpose language). I don't think a complex language that force you to create a two-columns layout from scratch at low level (having to implement the algorithm by yourself) is a better option. Surely it will be more powerful but also more complex (in the same way C is more powerful than PHP but nobody will want to create a website in C).

@essenmitsosse
Copy link
essenmitsosse commented Oct 8, 2024

I just want to point out: My initial comment left out JavaScript on purpose as a solution. It most certainly would be an obvious one, but the discussion shouldn't rely on it being solved with JavaScript.

@oscarotero I absolutely see your point and I agree that it is the best counter-argument to the point I made. But I think this is exactly the kind of discussion that needs to happen.


The counter argument that could be brought up is: Why not complete it with JavaScript, if we already have it? I think the concept of a website, that runs without JavaScript is basically dead by now. This wouldn't be about removing all of CSS and replacing it with JavaScript. It would only means to add an option to add more custom algorithms via a new general purpose tooling that would solve dozends, hundreds or even thousands of layout problems at once, instead of adding one very specific trendy layout algorithm every 5 years or so. And then waiting each time until all browsers have implemented it (correctly).

Houdini (or something like it) wouldn't take away anything from CSS. But Masonry won't be the last layout algorithm people will want and would set the precedence of having these things added via hardcoded logic, with a convoluted API surface. Even experienced front-end developers already complain about the complexity and convolutedness of flex and grid. Masonry most certainly wouldn't end up being a simpler implementation.

So for me it's about if we prefer to be able to run custom scripts (which could be much more focused on the specific use case) or if we prefer making CSS harder and harder to learn with each year.

The good thing about a Turing-complete language is, that you only need a finite set of things to express anything. The nature of CSS is, that every time you want to do something new you need to increase its surface. I can't think of many systems that have improved by continuously adding more specialized features while neglecting versatile, general-purpose tools.

@oscarotero
Copy link

@essenmitsosse

I think the concept of a website, that runs without JavaScript is basically dead by now.

I think it's the opposite. Most of the stuff that needed JavaScript in the past (like animations, scroll snap, anchor position, etc) can now be achieved with pure CSS (unless you want to translate all these features to JavaScript again, which is what I understand in your latest comment 😛).

experienced front-end developers already complain about the complexity and convolutedness of flex and grid.

I don't think flex and grid are harder than creating a responsive layout with all elements with position absolute and placing them using JavaScript.

I can't think of many systems that have improved by continuously adding more specialized features while neglecting versatile, general-purpose tools.

CSS is an advanced language, with a lot of features. Selectors can be very powerful. Properties like color manipulation, 2D/3D transformation, animations, open type features, variables, math functions, etc make CSS the most advanced language ever created to build interfaces. All these features are general-purpose. You can combine them and create infinite designs.

Grids and flex are properties that distribute elements over a surface. They were designed to be the most flexible as possible. Grid, for example, allows the build layouts in a declarative way (using named areas, grid-lines, configuring auto-flow, etc), imperatively (using line numbers to place every element over a surface of fixed columns and rows), or a mix of both (probably the best in most cases).

Masonry, (that probably should change the name for something more generic to avoid this kind of misinterpretation) is just another way to distribute elements in a surface, similar to grid and flex, but with a different algorithm to open new possibilities that grid and flex don't allow. It's not only to build "Pinterest-like" interfaces (although you can) but there are many other use cases like magazine-like interfaces, etc.

@Ultinio
Copy link
Ultinio commented Oct 8, 2024

Alright, I didn't have an opinion about one or the other (part of grid or its own display type), but let's admit plenty of developers are confused when they have to choose between grid or flex. So it's already not really clear.

As @essenmitsosse wrote, it might be a step in the wrong direction.
Instead of making things even more confusing for developers, why not giving them the possibility to define ways to fill a container in a more general way ?

Not mentioning Javascript or the solutions adding some JS-or-similar-system into CSS because it shouldn't be like that and this whole conversation is actually to avoid JS in the first place.

But if there is no possibility to change the whole system in the short term, here it feels like grid-auto-flow is the property designed to tell the browser where and how to add new elements. Isn't it why this property is there ?

So it could be added to grid-auto-flow, as masonry or waterfall (whatever). Columns are defined as usual with grid-template-rows, and the algorithm knows what to do with new elements.

Or maybe I am wrong and please feel free to show me some examples where this cannot work.

@alcinnz
Copy link
alcinnz commented Oct 8, 2024

I think the concept of a website, that runs without JavaScript is basically dead by now.

I think it's the opposite. Most of the stuff that needed JavaScript in the past (like animations, scroll snap, anchor position, etc) can now be achieved with pure CSS (unless you want to translate all these features to JavaScript again, which is what I understand in your latest comment 😛).

Indeed, exciting times for CSS! I will add that amongst the indie web circles I like to surf... JavaScript-reliant sites are the exception, not the norm.

The old web never disappeared, it just got built up around. Same city, new skyline.

experienced front-end developers already complain about the complexity and convolutedness of flex and grid.

I don't think flex and grid are harder than creating a responsive layout with all elements with position absolute and placing them using JavaScript.

I find flex & grid easier to use! And understand!

@fearthelettuce
Copy link

IMO, display: masonry is much cleaner. Shoehorning it into grid makes both more confusing.

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

No branches or pull requests