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
.
- Add
display: masonry
and get a masonry layout with auto sized tracks for columns and the layout filling in using masonry. - Want to control the columns? No problem, use track sizing just as you know if from grid.
- 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:
- Add
display: grid
, to get a single column grid layout. - Add
grid-template-columns: <track-listing>
, and at the moment there’s no way to auto-fillauto
sized tracks so you’ll need to decide on how many. Usinggrid-template-columns: repeat(3, auto)
, for example. - Add
grid-template-rows: masonry
. - Want to define rows instead? Switch the
masonry
value to apply togrid-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 .
75 Comments
@rachelandrew That and masonry isn’t a flippin’ grid.
@rachelandrew Excellent points!
@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]
@mattwilcox @rachelandrew Literally.
@rachelandrew I initially thought that masonry belonged on flexbox but now I agree that it being its own thing might be easier all around. It’s crazy that we’ve dreamed of this feature for a long time but now it’s a meh style to use.
Likes
Reposts