Masonry (with Animation) in CSS
Masonry (with Animation) in CSS êŽë š
Perhaps youâve seen the good news that display: grid-lanes; is starting to arrive in browsers which replicates what we generally call âmasonryâ layout in CSS. Itâs in Safari and feature-flagged in Chrome and Firefox. It gives this staggered grid item layout (with lots of possibilities) reminiscent of a brick wall, hence the name.
The name really comes from David DeSandroâs original library Masonry.js (and also Packery and Isotope). Those libraries accomplished the staggered layout well. But the foundation of them was a bunch of elements floated. Hereâs an original demo of Masonry.js:
If you resize that, youâll see that Masonry.js had another trick up its sleeve: animation!
See, Masonry.js supported fluidity, such that if the number of items (based on an ideal width) that could âfitâ on a horizontal row had to change, it would redo its calculation magic and animate the elements into new positions. Hereâs a video of that.
I thought about this when I saw a mind-blowing demo from Bramus (bramus) in which grid items would animate to new positions under the same conditions. But Bramusâ demo uses actual grid layout! And the re-calculating grid was by virtue of repeat/auto-fill magic that grid has always been good at, like grid-template-columns: repeat(auto-fill, 6rem);
The trick in Bramusâ demo is that itâs not actual the grid items themselves that animate into new positions. Itâs actually a child element of the grid items, which is set to cover the entire grid area by virtue of anchor positioning and an inset value that tracks the parent cellâs position. Super cool.
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, /* ... */);
.cell {
anchor-scope: --grid-cell;
anchor-name: --grid-cell;
.cell-content {
transition: inset 0.2s ease;
position: absolute;
position-anchor: --grid-cell;
inset: anchor(inside);
}
}
}
You donât have to nest it like that; I just did it to make the structure clearer.
That feels pretty darn magical to me. I donât know I would have thought of it, as it feels like to cover the cell youâd do inset: 0; and then there is nothing really to animate as that never changes. But apparently the anchor(inside) is dynamic enough that it animates even if the end result it essentially the same as inset: 0;
So hereâs Davidâs original demo, with the JavaScript and floating ripped out, and a grid layout put in place instead, with the magical CSS from above:
Hereâs a video of that, which is pretty darn close to the same as the JavaScript version.