Native CSS Masonry Layout In CSS Grid
Original Source: https://smashingmagazine.com/2020/11/native-css-masonry-layout-css-grid/
A Level 3 of the CSS Grid specification has been published as an Editor’s Draft, this level describes a way to do Masonry layout in CSS. In this article, I’ll explain the draft spec, with examples that you can try out in Firefox Nightly. While this is a feature you won’t be able to use in production right now, your feedback would be valuable to help make sure it serves the requirements that you have for this kind of layout. So let’s take a look.
What Is A Masonry Layout?
A masonry layout is one where items are laid out one after the other in the inline direction. When they move onto the next line, items will move up into any gaps left by shorter items in the first line. It’s similar to a grid layout with auto-placement, but without sticking to a strict grid for the rows.
The most well-known example of masonry is on Pinterest, and you will sometimes hear people refer to the layout as a “Pinterest layout”.
There are a number of JavaScript tools to help you create this kind of layout, such as David DeSandro’s Masonry plugin.
Can’t We Already Do This In CSS?
We can come close to a masonry layout in a couple of ways. The closest way to achieve the look of this type of layout is to use Multi-column Layout. In the example below, you see something which looks visually like a masonry layout. However, the order of the boxes runs down the columns. Therefore, if the first items have the highest priority (e.g. if this were search results), then the apparent first items in the top row aren’t actually the ones that came back first.
That’s all you need to do to get a simple masonry layout. Using Firefox, you can see that in the CodePen example below.
Note: You can use any of the values used for align-content for align-tracks and justify-tracks. There are some nice examples in the spec of different combinations.
If you set align-tracks: stretch, then any auto-sized items in the layout will stretch. The masonry effect is retained, but anything with a definite size on that axis will not be stretched out of shape.
See the Pen Masonry align-tracks: stretch by Rachel Andrew (@rachelandrew) on CodePen.
The align-tracks and justify-tracks properties can take multiple values. One for each track in the grid axis. This means that in our four-track grid we could have the first track stretching, the second aligned to start, the third aligned to end, and the fourth aligned to center.
This did not seem to work at the time of writing in Firefox.
The spec details that if there are fewer values than tracks, the remaining tracks will use the final specified value. If there are more values than tracks, additional ones will be ignored.
Fallback Behavior
The inclusion of this feature into the grid specification has a definite benefit where creating a fallback layout is concerned. As masonry behaves in a similar way to auto-placement, if a browser doesn’t support masonry then regular auto-placement can be used instead. This is likely to create the gaps in the layout as seen in the earlier example, but is certainly not terrible.
You can see this in action by looking at any of the demos so far using a browser with no support for masonry. You still get a layout. If you wanted to do something entirely different then you could check for support for masonry with feature queries. You could perhaps do the layout with multicol for non-supporting browsers.
@supports (grid-template-rows: masonry) {
/* masonry code here */
}
If the masonry layout is vital then you could check for masonry support using CSS.supports and only use the JavaScript masonry script if there is no support. This would mean that as browsers implement native masonry they would lose the overhead of the scripted version, but it would be there as a polyfill.
Potential Accessibility Concerns
While masonry in CSS is exciting, it is yet another place where content reordering and a disconnection of the document order from the visual order may happen. As I noted on a recent issue that was raised, I feel that we are creating exciting layout possibilities and then needing to tell people to be very careful how they use them.
I’ve written about this problem in Grid, content reordering, and accessibility. I hope that as we move forward with this specification, there are also renewed efforts to find a good way forward with regard to content vs. display order.
Your Feedback Is Needed
We are really lucky to not only have this new spec, but to have a browser implementation to test it in. If you have examples where you have used masonry, why not try replacing your JavaScript with the grid version and see if it works for you? If you run into problems or can’t do something you were able to do in your previous implementation, please let the CSSWG know by raising an issue.
While things are in an experimental state, this is your chance to help influence any changes and point out any problems. So please do, and help make this really great feature even better!
Leave a Reply
Want to join the discussion?Feel free to contribute!