Masonry and good defaults

I’ve been writing about and teaching people CSS layout for a very long time. People sometimes call me an expert in CSS. I don’t know about that, but I’m confident in claiming expertise in teaching and writing about CSS. I’ve been doing this for a long time, about 25 years. Over that time I’ve learned which things are tricky for the majority of people to understand, and it’s that knowledge I try to bring to the CSS Working Group.

The Chrome team believes that we should define masonry as a separate value for display—display: masonry, you can read in detail why in Feedback needed: How should we define CSS masonry?. However this post isn’t about what my colleagues think, this one is just my opinion.

My opinion is, as it was in 2020, that defining masonry as part of grid would be a mistake. 

Good defaults

The thing with switching to a new formatting context, as we do with flex and grid layouts, is that the minute you use display: flex or display: grid, a set of initial values get applied to the container and direct children. Those initial values should do something useful, or at least not do something weird. And, they are different depending on the formatting context. In flexbox, the items immediately default to a row, they don’t stretch, or wrap. This gives you reasonable behaviour. In grid you get a single column grid, to do anything else would be weird as we’d have had to decide for you how many column tracks you wanted. 

Good defaults make things easier to teach. They point to what the layout method is designed for. Flexbox is really designed for putting things into a line and distributing spare space. So that initial behaviour of putting all your things in a row is a great starting point for whatever you might want to do. It may be all you need to do. It’s not difficult as a teacher to then unpack how to add space inside or outside items, align them, or make it a column rather than a row. Step by step, from the defaults.

I want to be able to take the same approach with display: masonry.

  1. Add display: masonry and get a masonry layout with auto sized tracks for columns and the layout filling in using masonry.
  2. Want to control the columns? No problem, use track sizing just as you know if from grid.
  3. Want to define rows instead? Change masonry-direction to row.

We can’t do that as easily with grid, because of the pre-existing initial values. The good defaults for grid don’t work as well for masonry. Currently you’d need to:

  1. Add display: grid, to get a single column grid layout.
  2. Add grid-template-columns: <track-listing>, and at the moment there’s no way to auto-fill auto sized tracks so you’ll need to decide on how many. Using grid-template-columns: repeat(3, auto), for example.
  3. Add grid-template-rows: masonry.
  4. Want to define rows instead? Switch the masonry value to apply to grid-template-columns and now define your rows. Once again, you have to explicitly define rows.

This might be improved in future if we can have repeat(auto-fill, auto)in grid, though the default for grid is still likely not going to be what’s best for masonry.

This example also demonstrates that good defaults mean less configuration. The proposed masonry with display: grid needs more configuring than the display: masonry version because you have to tell grid to do something other than the initial values, which are designed for a two-dimensional model where both dimensions behave in the same way.

Less configuring means you can lean on shorthands more easily. The grid shorthand is complex, because it needs to let you configure both dimensions of the grid—rows and columns. Therefore the order of items in the shorthand matters, the browser needs to know which dimension you are defining. It’s anecdotal, but I’ve been sent a lot of grid layouts to look at over the years, I rarely see anyone using the grid shorthand and when I’ve taught it in person people will say they won’t ever use it, it’s too hard to read.

Adding masonry to the grid shorthand is messy, as explained in the post on developer.chrome.com. I don’t think there’ll be a way around the need to switch the order of values even if we manage to find a way to improve my first example.

Teaching masonry

My colleagues think they have found a way to prevent the major performance implications of going with masonry in grid. That’s great, but even if everything else is equal I’m going to continue to argue that combining the two is a mistake. It would be a mistake because it means we have to teach a whole bunch of things that behave differently even though you are in the same formatting context. We’ll have to teach places where you have to do more work, unintuitive work, because the defaults are not ideal. I’m also thinking about the things we might want to define in the future, which will then mean making difficult choices around defaults, possibly adding more weirdness into masonry. 

Whether you agree or disagree, please add your thoughts. In the comments here is fine, but even better if you can comment on issue 9041 .

#

53 Comments

Matt Wilcox September 21, 2024 Reply

@rachelandrew That and masonry isn’t a flippin’ grid.

David Anson September 21, 2024 Reply

@rachelandrew I get why we are where we are with HTML/CSS, but golly do I think we’d all benefit from a programmable layout system like XAML has/had. Once that is possible, there’s no pressure to get things perfect before adding them (as here). Web has won over XAML for me for many reasons, but I always get frustrated with layout because it’s so much harder than it could be.

Here’s a simple example from long ago of what’s possible with programmable layout:

https://dlaa.me/blog/post/10147845

Each one is the best – for different definitions of “best” [The BestFitPanel collection of layout containers provides flexible, easy-to-use options for Silverlight, WPF, and Windows Phone applications]

Haneen albrqouni September 21, 2024 Reply

@iamdtms @rachelandrew ‏Hi ,how are you ? ‏Iam Hanin from northern Gaza ‏I lost my home and my husband lost his job. I was preparing…

Leave a Reply