Skip to content

Gallery Block: Add masonry style variation#77615

Open
dan-zakirov wants to merge 1 commit into
WordPress:trunkfrom
dan-zakirov:add/masonry-gallery-28247
Open

Gallery Block: Add masonry style variation#77615
dan-zakirov wants to merge 1 commit into
WordPress:trunkfrom
dan-zakirov:add/masonry-gallery-28247

Conversation

@dan-zakirov

Copy link
Copy Markdown

What?

Adds a Masonry block style variation to the Gallery block. When active, the gallery lays out inner Image blocks with CSS columns and break-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
masonry.mp4

Why?

Fixes #28247.

The Gallery block currently supports a single flex layout with fixed rows and object-fit: cover cropping. 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.json

Registers a styles array with two entries: default (marked isDefault: true so existing posts are unaffected) and masonry. That is the whole opt-in surface — the variation adds no new attributes and relies on the standard is-style-masonry class that block style variations generate.

packages/block-library/src/gallery/style.scss

Adds a single nested rule block under the existing .wp-block-gallery.has-nested-images:

  • &.is-style-masonry switches display: block, sets column-gap: var(--wp--style--unstable-gallery-gap) (the same variable the flex layout already uses, so theme gap settings carry over unchanged), and maps columns-1 through columns-8 onto column-count, including the mobile default of 2 and the desktop default of 3 behind the existing break-small mixin.
  • Inner figure.wp-block-image gets width: 100%, break-inside: avoid, display: block, and aspect-ratio: auto !important. The !important is needed to neutralise the inline aspect-ratio that the shared Aspect ratio control sets on each figure — see the UI note in edit.js below.
  • The nested a, img rule overrides the is-cropped rules' height: 100% and object-fit: cover back to height: auto and object-fit: initial, again because is-cropped is a sibling class that can co-exist with is-style-masonry on the wrapper.

packages/block-library/src/gallery/edit.js

One line detects the variation from the attribute (not the className prop, which can be filtered by other APIs before reaching this component):

const isMasonry = !! attributes.className?.includes( 'is-style-masonry' );

isMasonry is used to hide two ToolsPanelItems (Crop images to fit and Aspect ratio) whose flex-based behaviour the CSS columns layout cannot honour. In their place a small inline notice renders:

The Masonry style manages image cropping and aspect ratio automatically. Switch to the Default style to change these options.

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.scss

Adds the .wp-block-gallery__masonry-notice rule: neutral grey help text styled to match the surrounding ToolsPanel help copy.

Backward compatibility

  • No block attributes added, removed, or renamed.
  • Existing galleries render byte-identical HTML — the new styles array marks default as isDefault: true, so posts without an explicit className keep the current flex layout.
  • All CSS additions are scoped under &.is-style-masonry, so nothing leaks into default galleries.
  • Inside the masonry variation, all other Gallery options (crop toggled on, aspect ratio forced to 1:1 / 16:9, random order, different image resolutions, lightbox, linkTo media/attachment, alignments wide/full) continue to work: aspect ratios turn the gallery into a squared / widescreen grid, crop decides whether those tiles get object-fit: cover or 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.
  • No changes to save.js / deprecations required: the className attribute already round-trips through the block's existing supports.anchor / default className handling.
  • *.native.js mirrors 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

  1. Start Gutenberg locally (npm run dev + wp-env start) or use the built plugin on a WordPress install.
  2. Create a new page and add a Gallery block with 6–10 images of mixed aspect ratios (tall portraits, wide landscapes, a square or two).
  3. Click the gallery once to select the block. If the right-hand block sidebar is not visible, toggle it via the top-bar Settings button (the icon showing two vertical panels, top right of the editor, or Ctrl+Shift+, / Cmd+Shift+,).
  4. With the Gallery selected, look just below the block's name (Gallery — Display multiple images in a rich gallery.) in the sidebar. There are three tab icons in a row:
    • List View (horizontal lines icon) — inner block tree.
    • Settings (gear / cog icon) — Columns, Resolution, Crop, Aspect ratio, etc.
    • Styles (two-tone circle, half-filled) — this is the new tab to use.
  5. Open the Styles tab. Two preview cards are shown:
    • Default — current flex layout, selected by default.
    • Masonry — new CSS-columns layout added by this PR.
      Click the Masonry card. The preview card becomes the active style, is-style-masonry is added to the block's wrapper in the canvas, and the layout updates immediately.
  6. Open the Settings tab (gear icon). Confirm that Crop images to fit and Aspect ratio are 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:

  • Columns slider 1 → 8 — the column count maps one-to-one onto CSS 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.
  • Resolution LargeThumbnail — inner images reload at the smaller size and masonry adjusts to the new natural heights without any layout shift in the wrapper.
  • LinkTo: Media file / Attachment page — each figure gains an anchor tag; the masonry layout is preserved and clicking an image opens the expected destination.
  • LinkTo: Enlarge on click (lightbox) — the lightbox opens the full-size image and honours Phase 1 (Image Block: Restore captions in lightbox overlay with Gallery-level toggles #77477) captions if that PR has landed.
  • Randomize order — every front-end load reshuffles the inner images; the column flow adapts.
  • Alignment Wide / Full — the gallery widens, the masonry keeps its column structure, no overflow.
  • Captions<figcaption> renders over the bottom of each figure using the existing gallery caption styling; break-inside: avoid keeps the caption tied to its image.
  • Switch back to Default — the inline notice disappears, Crop images to fit and Aspect ratio return, and the gallery reverts to the flex layout with no leftover masonry classes on the wrapper.
  • Existing galleries — load a post authored before this PR with a regular Gallery block. No visual or HTML diff should be visible.
  • Mobile — resize the viewport below the break-small breakpoint; the gallery falls back to two columns.
  • RTL — the column flow should mirror correctly in right-to-left locales (CSS columns follow 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:

cc @melchoyce (original issue author), @jameskoster, @mtias, @ryelle (WordPress/wordpress.org#524), @dd32 (Meta committer who confirmed the overall direction).

Fixes #28247.

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.
@github-actions

github-actions Bot commented Apr 23, 2026

Copy link
Copy Markdown

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 props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: dan-zakirov <alexodiy@git.wordpress.org>
Co-authored-by: t-hamano <wildworks@git.wordpress.org>
Co-authored-by: aaronrobertshaw <aaronrobertshaw@git.wordpress.org>
Co-authored-by: jasmussen <joen@git.wordpress.org>
Co-authored-by: glendaviesnz <glendaviesnz@git.wordpress.org>
Co-authored-by: melchoyce <melchoyce@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@github-actions github-actions Bot added [Package] Block library /packages/block-library First-time Contributor Pull request opened by a first-time contributor to Gutenberg repository labels Apr 23, 2026
@github-actions

Copy link
Copy Markdown

👋 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.

@jameskoster jameskoster requested review from a team and scruffian April 24, 2026 13:13
@scruffian scruffian assigned scruffian and unassigned scruffian Apr 24, 2026
@t-hamano t-hamano added [Block] Gallery Affects the Gallery Block - used to display groups of images [Type] Enhancement A suggestion for improvement. labels Apr 27, 2026
@t-hamano

Copy link
Copy Markdown
Contributor

Thanks for the PR.

Are you aware that the implementation of display: grid-lanes is being considered to ideally achieve Masonry layouts using only CSS? Personally, I would like to propose that we consider enhancing the Gallery block after this CSS specification is finalized and implemented in all major browsers.

P.S. If you could keep the pull request description as concise as possible, it would reduce the burden on reviewers.

@dan-zakirov

Copy link
Copy Markdown
Author

Thanks for the PR.

Are you aware that the implementation of display: grid-lanes is being considered to ideally achieve Masonry layouts using only CSS? Personally, I would like to propose that we consider enhancing the Gallery block after this CSS specification is finalized and implemented in all major browsers.

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.

display: grid-lanes is Safari Technology Preview only and the spec isn't finalised yet. Recent precedents: subgrid took 6 years from spec to all-browser support, and Mozilla's earlier grid-template-rows: masonry shipped behind a Firefox flag in 2020 only to be deprecated 5 years later. A realistic wait for grid-lanes across all browsers is 3–5 years, on top of the 5 years #28247 has already been open.

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 column-count for grid-lanes later is an internal CSS change — no migration needed. #42240 stays the right place to track that upgrade.

If keeping it out of WP Core minors is the concern, happy to gate the registration behind IS_GUTENBERG_PLUGIN.

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

@aaronrobertshaw

Copy link
Copy Markdown
Contributor

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 column-count to grid-lanes is incorrect. The order of the images will change making it a breaking visual change for some users.

Additionally, the grid-lanes proposal should offer a lot more options and functionality. Things that will likely need settings to be configured rather than styles only, making block style variations potentially inadequate long term.

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.

@dan-zakirov

Copy link
Copy Markdown
Author

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 imageCrop: off produces uneven column heights and visible vertical gaps between rows, and there's no current plan to address that in core. The PR is the simplest CSS-only fix for that, using a feature stable across browsers for 10 years.

image

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:

Reference What Status
#28247 "Flowing Masonry Gallery" Open since Jan 2021, labelled [Status] In Progress, only one comment in five years, no implementation work
#29244 Earlier filter-based attempt by you Closed in 2021 ("filter approach decided against") with no alternative path proposed
imageCrop: off flow gaps Existing visible row gaps Never addressed
#49958 Masonry in Gutenberg's own template pattern modal Merged 2023, using the exact same column-count + break-inside: avoid approach this PR proposes

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:

  1. Style variation + concession: rename to is-style-masonry-columns, gate registration behind IS_GUTENBERG_PLUGIN. Keeps it out of Core minors while grid-lanes matures; addresses the "not true masonry" framing.
  2. Layout type: re-scope as supports.layout.allowedTypes: ['flex', 'masonry'] so future grid-lanes settings have a UI home - directly answers the "style variation inadequate long-term" concern.

A few questions, if I may:

  • Which of the two paths above would be more workable from your side? Simply waiting for grid-lanes to be adopted across all major browsers is realistically several years away, and New Block: Flowing Masonry Gallery #28247 has already been open for five.
  • If neither feels right, would you have a concrete near-term direction in mind that could close New Block: Flowing Masonry Gallery #28247 within the next 6–12 months?
  • Separately from this PR - is there any plan to address the existing imageCrop: off gaps in Gallery, or is the current behaviour considered acceptable?

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.

@aaronrobertshaw

Copy link
Copy Markdown
Contributor

Thanks for the continued thoughts and effort here @dan-zakirov 👍

You'll get no arguments from me that the imageCrop: off results aren't ideal. The plan as I'm aware of is that once there is a native CSS masonry layout, it will be ready for Core.

The PR is the simplest CSS-only fix for that, using a feature stable across browsers for 10 years.

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.

the project already considers this technique production-grade for its own UI

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.

Which of the two paths above would be more workable from your side?

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.

  • Register a new block style
  • Enqueue the desired CSS (including something to enforce correct aspect ratios, no cropping etc)

If neither feels right, would you have a concrete near-term direction in mind that could close

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.

Separately from this PR - is there any plan to address the existing imageCrop: off gaps in Gallery, or is the current behaviour considered acceptable?

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 grid-lanes feature.

@jasmussen

Copy link
Copy Markdown
Contributor

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Block] Gallery Affects the Gallery Block - used to display groups of images First-time Contributor Pull request opened by a first-time contributor to Gutenberg repository [Package] Block library /packages/block-library [Type] Enhancement A suggestion for improvement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

New Block: Flowing Masonry Gallery

5 participants