Gallery Block: Add masonry style variation#77615
Conversation
Register a "Masonry" block style variation that renders the gallery using CSS columns with break-inside: avoid, so images flow top-to-bottom keeping their natural aspect ratios. Caption, lightbox, linkTo, random order, and resolution work unchanged. The crop and aspect-ratio controls are hidden while the variation is active and replaced with a short inline notice, since both options are managed by the column layout. Fixes WordPress#28247.
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
|
👋 Thanks for your first Pull Request and for helping build the future of Gutenberg and WordPress, @dan-zakirov! In case you missed it, we'd love to have you join us in our Slack community. If you want to learn more about WordPress development in general, check out the Core Handbook full of helpful information. |
|
Thanks for the PR. Are you aware that the implementation of
P.S. If you could keep the pull request description as concise as possible, it would reduce the burden on reviewers. |
Hi @t-hamano, thanks for the review.
CSS multi-column is the only pure-CSS, cross-browser path to masonry today, and Gutenberg already uses it internally (#49958). Because this is a block style variation, swapping If keeping it out of WP Core minors is the concern, happy to gate the registration behind Got it on the description length - I'll trim this one in a follow-up push and keep future PRs more concise. Thanks for the heads-up |
|
Thanks for the ping 👍 Quickly catching up here, but I'm not sure about the masonry block style variation approach. This feels like plugin territory for me until there is a complete solution. One reason is this proposal isn't actually a true masonry layout. So the claim this is just a simple swap of Additionally, the With advancements to the Grid block and its layout capabilities, I wonder if there might be some way to leverage that in the future to achieve a full featured masonry layout for the Gallery block. It might even allow column spans, waterfall vs brick directions etc. |
|
Thanks @aaronrobertshaw - fair point on column-major flow. Before we close this PR, a couple of things worth raising: The screenshot below shows the actual UX gap motivating this: Gallery with
There's a broader pattern worth raising too. Each Gallery improvement has had its own context, but the cumulative result is the same - the block has effectively stood still on this kind of layout request:
The last row is the most direct: the project already considers this technique production-grade for its own UI. (A keyboard reading-order concern was raised post-merge there by @KevinBatdorf - fair point in general, but the impact is much smaller for an image gallery, where each figure is a single tab stop, than for a grid of interactive controls.) Each individual decision above has been reasonable on its own, but together they leave Gallery in a state where the same requests come back year after year and core ships nothing on them. This PR is intentionally narrow to break that loop with the smallest possible step. I'm proposing two paths:
A few questions, if I may:
To be clear, none of this is meant as criticism - just trying to understand how Gallery and layout requests of this kind fit into the project's broader direction. Happy to take whichever path makes sense, and grateful for the time you've spent reviewing. |
|
Thanks for the continued thoughts and effort here @dan-zakirov 👍 You'll get no arguments from me that the
As noted, what's proposed isn't a masonry layout, so conflating this proposal with a masonry layout isn't very helpful in moving things forward.
This is definitely a different context than rendering content on a site's frontend where we have backward compatibility commitments to honour. So it's use in the UI can't be used to justify it's use for the Gallery layout.
To me personally, neither path. This is still best left to a plugin or theme until a clean solution is available. What you've proposed is still a very simple extension for a theme or plugin to add.
No, I don't have a concrete near-term plan for this. Especially as my efforts and time are unfortunately directed elsewhere at the moment. I would love for core to have a native masonry layout but it is ok that some features are left to the broader plugin ecosystem until there is a canonical and clean approach to solving the issue. I know I also sound like a broken record here but it is worth reinforcing again for others reading along that what is proposed here still is not a masonry layout so even if this landed, it wouldn't and shouldn't close #28247.
I'm not aware of anything at the moment. As you note, it has been this way for forever and there are several plugin options that address the immediate need. So I think it is less of a case of this being "acceptable" and more that there are workarounds or simple enough solutions that lower the urgency for something to land in core that must be maintained in perpetuity. In other words, we have the time to wait until there is a native CSS option. This particular CSS proposal has taken a disappointingly long time to progress but my read there is sufficient reason to remain hopeful and excited for the |
|
Good PR, good motivation that I share. I've used text-columns myself to achieve this, but there's really no ideal solution. Not speaking authoritatively here, but I'm personally leaning towards echoing Aki that the cleanest and most accessible core solution should be to wait for the CSS spect to accommodate this on the browser level, and leave interim solutions in plugin territory. I realise this is disappointing to hear, but it also accounts for the complexity of core maintenance that this has, and the many possible permutations the userbase of this size has. |

What?
Adds a
Masonryblock style variation to the Gallery block. When active, the gallery lays out inner Image blocks with CSS columns andbreak-inside: avoid, so images flow top-to-bottom preserving their natural aspect ratios. The existing flex layout remains the default, and the new variation is opt-in via the block's Styles panel.masonry.mp4
Why?
Fixes #28247.
The Gallery block currently supports a single flex layout with fixed rows and
object-fit: covercropping. With mixed aspect ratios this either crops aggressively (distracting authored composition) or, when cropping is off, leaves large vertical gaps between rows. @melchoyce opened this issue back in January 2021 asking for a proper masonry option; five years later it is still the most-requested Gallery layout change that did not make it into core (see also #42240 for the related CSS-grid effort).Beyond core, this is the second phase of a wider effort to replace the wordpress.org Plugin Directory's legacy React screenshot gallery with native blocks (see meta#8083, meta#2273, WordPress/wordpress.org#524). Plugin authors upload screenshots in very different formats — tall, wide, square — and the current flex Gallery cannot present them well without either cropping away intent or leaving awkward empty rows. Phase 1 (#77477, captions in the lightbox) is already on review; this PR is the companion change that makes the underlying layout suitable for that content.
How?
Four files, +101 / -14. All changes scoped to the Gallery block. No PHP changes, no changes to the static save output, no new block attributes.
packages/block-library/src/gallery/block.jsonRegisters a
stylesarray with two entries:default(markedisDefault: trueso existing posts are unaffected) andmasonry. That is the whole opt-in surface — the variation adds no new attributes and relies on the standardis-style-masonryclass that block style variations generate.packages/block-library/src/gallery/style.scssAdds a single nested rule block under the existing
.wp-block-gallery.has-nested-images:&.is-style-masonryswitchesdisplay: block, setscolumn-gap: var(--wp--style--unstable-gallery-gap)(the same variable the flex layout already uses, so theme gap settings carry over unchanged), and mapscolumns-1throughcolumns-8ontocolumn-count, including the mobile default of2and the desktop default of3behind the existingbreak-smallmixin.figure.wp-block-imagegetswidth: 100%,break-inside: avoid,display: block, andaspect-ratio: auto !important. The!importantis needed to neutralise the inlineaspect-ratiothat the shared Aspect ratio control sets on each figure — see the UI note inedit.jsbelow.a, imgrule overrides theis-croppedrules'height: 100%andobject-fit: coverback toheight: autoandobject-fit: initial, again becauseis-croppedis a sibling class that can co-exist withis-style-masonryon the wrapper.packages/block-library/src/gallery/edit.jsOne line detects the variation from the attribute (not the className prop, which can be filtered by other APIs before reaching this component):
isMasonryis used to hide twoToolsPanelItems (Crop images to fitandAspect ratio) whose flex-based behaviour the CSS columns layout cannot honour. In their place a small inline notice renders:Everything else in the inspector (Columns, Resolution, Randomize order, Open images in new tab, Navigation button type, LinkTo toolbar, border / spacing / colour supports) is untouched.
packages/block-library/src/gallery/editor.scssAdds the
.wp-block-gallery__masonry-noticerule: neutral grey help text styled to match the surrounding ToolsPanel help copy.Backward compatibility
stylesarray marksdefaultasisDefault: true, so posts without an explicitclassNamekeep the current flex layout.&.is-style-masonry, so nothing leaks into default galleries.object-fit: coveror stay natural, etc. The notice in the sidebar tells authors which pair is managed by the layout rather than removing them from their mental model.save.js/ deprecations required: theclassNameattribute already round-trips through the block's existingsupports.anchor/ default className handling.*.native.jsmirrors were not touched — the variation is additive and the native UI simply does not render a Styles tab, so behaviour on React Native remains exactly as it was.Testing Instructions
npm run dev+wp-env start) or use the built plugin on a WordPress install.Ctrl+Shift+,/Cmd+Shift+,).Gallery — Display multiple images in a rich gallery.) in the sidebar. There are three tab icons in a row:Click the Masonry card. The preview card becomes the active style,
is-style-masonryis added to the block's wrapper in the canvas, and the layout updates immediately.Crop images to fitandAspect ratioare replaced by a short inline notice reading: "The Masonry style manages image cropping and aspect ratio automatically. Switch to the Default style to change these options."Expected default state after step 5: the gallery switches to a three-column masonry layout on desktop, two columns on mobile. Images keep their natural aspect ratios, there are no gaps between rows.
Variations to cover:
column-count, including the mobile breakpoint. At 1 column the gallery reads as a single-column stack. The slider's max is clamped to the number of images in the gallery (standard Gallery behaviour), so seven or eight columns require seven or eight images.Large→Thumbnail— inner images reload at the smaller size and masonry adjusts to the new natural heights without any layout shift in the wrapper.Wide/Full— the gallery widens, the masonry keeps its column structure, no overflow.<figcaption>renders over the bottom of each figure using the existing gallery caption styling;break-inside: avoidkeeps the caption tied to its image.Crop images to fitandAspect ratioreturn, and the gallery reverts to the flex layout with no leftover masonry classes on the wrapper.break-smallbreakpoint; the gallery falls back to two columns.direction).Related work
This PR is phase 2 of the effort to replace the wordpress.org Plugin Directory's React screenshot gallery with core blocks:
Related Gutenberg issues that this PR does not close but is adjacent to:
grid-template-rows: masonryand it ships beyond Firefox,&.is-style-masonrycan be upgraded to Grid masonry without touching any authored content.cc @melchoyce (original issue author), @jameskoster, @mtias, @ryelle (WordPress/wordpress.org#524), @dd32 (Meta committer who confirmed the overall direction).
Fixes #28247.