Re: [csswg-drafts] [css-grid][css-flexbox] Pinterest/Masonry style layout support

I don't think we can effectively define a masonry layout as an extension of either flexbox or grid layout. There needs to be a new `display` type.

But I *do* think that it can be defined without any new properties, by re-using [column layout properties](https://drafts.csswg.org/css-multicol-1/).

A `display: masonry` value on a container would cause child nodes to be treated as distinct items (like in grid/flex layout), and to be assigned according to the agreed-upon rules for masonry layout: one item at a time, into the column that has the least total height.

But the sizing of those columns would be defined by `column-width` and/or `column-count`, and `column-gap` (and sure, why not `column-rule`, too). Column breaks wouldn't have an effect. Multi-column spans also probably don't make sense (unless someone comes up with a logical proposal of how it would work). 

That said, a few properties from grid/flex could be borrowed for more control:

- [`row-gap`](https://drafts.csswg.org/css-grid/#gutters), to specify a gap between masonry items in each column. That's already conveniently been redefined with a layout-mode-agnostic name.
- [align/justify contents/self properties](https://drafts.csswg.org/css-align-3/) to apply for positioning fixed-width items within their column, and for spacing columns across the container (if both `column-width` and `column-count` are constrained, or if there aren't enough items for the number of calculated columns).  

But other than the column assignments for items, this isn't new layout math, just re-using existing properties in different combinations.  Column widths are defined by the properties on the container. Item sizes are defined by the normal block layout rules when fit into a column of that width.

(@bfgeek How hard would it be for you to tweak your Houdini demo to use the multicol properties to define the column sizes, instead of custom props?)

As an important side benefit to reusing the existing properties, a basic column layout is an acceptable fallback for most masonry layouts. (It looks similar, but the reading/tab order requires scrolling down a column then back up, and the column assignments are not stable if you add new elements to the end of the list.). So in most cases you wouldn't need any fallback code for browsers that don't recognize `display: masonry`.

______________________________________

Of course, as a few people have mentioned, the other missing piece of the puzzle is a way to define aspect ratios for fit-to-available-width replaced content elements, so that the layout doesn't jump around erratically as images download and change the heights of the masonry items.  But that's a feature that is useful well beyond Masonry layout, and should be defined separately.

______________________________________

<aside>

I started playing with existing CSS today, trying to fake Masonry, in a constrained case, as a flexbox layout with `:nth-of-type()` used to adjust `order` (Spoiler: even after constraining the container size to match the content & number of columns, [it didn't work](https://codepen.io/AmeliaBR/pen/35ed956873b0d5b338fb3cbf76625041/?editors=0100)).

I even started to write up a full proposal defining masonry as a new value for `flex-wrap` (the idea being that you'd assign items to flex lines by going across the cross axis, instead of by filling up a single line on the flex axis). But that made me realize that you would need to define the cross-axis line height/width before assigning items, and that's not how flexbox works. But it *is* how columns work: the column sizes are defined by the container size, and content fits to the columns. So I wrote up this proposal, instead.

</aside>

-- 
GitHub Notification of comment by AmeliaBR
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/945#issuecomment-372085811 using your GitHub account

Received on Sunday, 11 March 2018 03:09:16 UTC