Image Block: Restore captions in lightbox overlay with Gallery-level toggles#77477
Image Block: Restore captions in lightbox overlay with Gallery-level toggles#77477dan-zakirov wants to merge 2 commits into
Conversation
…toggles Renders the inline caption inside the lightbox overlay (hidden since PR WordPress#58835 shipped in WordPress 6.5) and adds two Gallery-level toggles so authors can control where captions appear. Image block: - Extract caption in `block_core_image_render_lightbox()` and pass it to the Interactivity API state (plain text via `wp_strip_all_tags`). - Add a `<figcaption class="wp-lightbox-caption">` inside the overlay template, bound via `data-wp-text`. - New `block_core_image_apply_gallery_caption_visibility()` filter to strip the inline caption when the parent Gallery opts out. Gallery block: - New `showCaptionInGallery` and `showCaptionInLightbox` optional attributes exposed via `providesContext`. - New `Captions` section in the Settings panel with two toggles. Styles fade the overlay caption in after the zoom animation settles, with `prefers-reduced-motion` disabling the transition. This unblocks the WordPress.org Plugin Directory screenshot migration (WordPress/wordpress.org#524, meta#8083). A follow-up PR is planned for per-image overrides. Fixes WordPress#60469
|
Warning: Type of PR label mismatch To merge this PR, it requires exactly 1 label indicating the type of PR. Other labels are optional and not being checked here.
Read more about Type labels in Gutenberg. Don't worry if you don't have the required permissions to add labels; the PR reviewer should be able to help with the task. |
|
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 Unlinked AccountsThe following contributors have not linked their GitHub and WordPress.org accounts: @mamaretti. Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases. 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. |
|
One testing note is that the option toggled Show in gallery: off did not remove the captions from appearing in the gallery in the block editor as I expected it to. It did remove the gallery captions for the published front end page. Thank you for working on this feature. |
Addresses testing feedback that `Show in gallery: off` only affected the published front end and left the caption visible in the block editor. - `image.js` now reads `showCaptionInGallery` from the provided block context and skips rendering the `<Caption>` component when it is explicitly false. - Added `"default": true` to the `showCaptionInGallery` and `showCaptionInLightbox` attributes in `gallery/block.json` so the context value is a stable boolean; otherwise the serialized block context would have coerced the missing attribute to `false`, which would have hidden the caption for every gallery in the editor.
Pushed I'm not 100% sure this is the right call: hiding the caption in the editor also removes the UI for editing it. A few ways we could handle this:
Happy to go with whichever you think fits the block-librarys patterns best |
|
Worth mentioning why this matters on our end - it's Phase 1 of the plan outlined in WordPress/wordpress.org#524 (comment): replace the Plugin Directory's React screenshot gallery with native Gallery + core lightbox (meta#8083). Phase 2 will add masonry as a Gallery layout/style variation (#28247) - keeping scope tight here so each phase lands cleanly. |
What?
Restores
figcaptionrendering inside the Image block lightbox overlay so captions authored via the inline caption field become visible when an image is enlarged via the core lightbox. Adds two Gallery-level toggles (Show captions in gallery/Show captions in lightbox) so authors can choose where captions are displayed without editing each image individually.chrome_9TRMnb5y51.mp4
Why?
Fixes #60469.
Captions have been hidden in the lightbox overlay since #58835 shipped in WordPress 6.5. Since then, users who enable Expand on click on an Image block — or Enlarge on click on a Gallery block — lose the contextual information their caption provides exactly when users most need it: when the image is enlarged and isolated from its surrounding content.
The two Gallery toggles solve the separate-but-related problem that the inline caption is overloaded: it renders both under the image on the page and inside the lightbox. Sometimes authors want both; sometimes they want a compact grid with descriptions surfacing only on enlarge. The toggles cover the full matrix without introducing a separate caption field.
This also unblocks an effort to replace the wordpress.org Plugin Directory's legacy React screenshot gallery with native Gallery + core lightbox (see meta#8083 and WordPress/wordpress.org#524). Plugin screenshot captions typically explain what the screenshot shows, which is only useful when the screenshot is actually enlarged — and plugin pages work best when the grid itself stays compact.
How?
Five files, ~157 lines. All changes scoped to the Image and Gallery blocks.
packages/block-library/src/gallery/block.jsonAdds two optional boolean attributes (
showCaptionInGallery,showCaptionInLightbox) and exposes them throughprovidesContext, so inner Image blocks can honour them without having to read the parent's state directly.packages/block-library/src/gallery/edit.jsAdds a single
ToolsPanelItemlabelled Captions under the existing Navigation button type control, rendered only when the gallery has images with the lightbox enabled. Inside aBaseControlheading (to match the visual weight of the other sections) it renders aVStackof twoToggleControls:ononResetting the panel item clears both attributes back to
undefined(treated astruein PHP), so the default behaviour is full backward compatibility.packages/block-library/src/image/block.jsonAdds
showCaptionInGalleryandshowCaptionInLightboxtousesContext.packages/block-library/src/image/index.phpTwo small additions:
block_core_image_render_lightbox()now extracts the caption from the already-rendered block content and stores it inwp_interactivity_state(). When the parent Gallery's context reportsshowCaptionInLightbox === false, the stored caption is an empty string so the overlay stays empty for those images. The caption is passed throughwp_strip_all_tags()because the Interactivity API renders it viadata-wp-text, which outputs plain text.block_core_image_print_lightbox_overlay()adds a<figcaption class="wp-lightbox-caption">inside each of the two overlay<figure>elements, bound viadata-wp-text="state.selectedImage.caption"anddata-wp-class--has-caption="!!state.selectedImage.caption".block_core_image_apply_gallery_caption_visibility()filter (priority 20, after the lightbox filter) strips the<figcaption>from the rendered Image block when the Gallery context reportsshowCaptionInGallery === false. Running after the lightbox filter means the caption is still captured for the overlay before it is removed from the on-page output.packages/block-library/src/image/style.scss.wp-lightbox-overlay .wp-block-image figcaption { display: none }rule is narrowed tofigcaption:not(.wp-lightbox-caption)so it keeps hiding any stray inline figcaption nested inside the overlay but leaves our explicit caption element alone..wp-lightbox-captionrule positions the caption as a bottom-aligned bar over the image with a top-fading dark gradient for legibility;pointer-events: nonelets clicks on the empty gradient area still close the overlay..wp-lightbox-overlay.active .wp-lightbox-caption.has-captionrule fades the caption in once the zoom animation has had a chance to settle (transition: opacity 200ms ease-out 200ms). The inverse fade-out uses a faster120ms ease-indeclared on the base rule.@media (prefers-reduced-motion: reduce)clears the transition on both rules so users opted into reduced motion see the caption appear and disappear instantly.No JavaScript (
view.js) changes were required —setButtonStyles()already accounts for caption height when measuring the figure, so overlay sizing calculations remain intact.Backward compatibility
undefined, which is treated astruein PHP, so existing posts behave as before — plus they now actually show captions in the lightbox (the behaviour that existed before Image block: refactor and removedata-wp-body#58835).figcaption { display: none }rule inside the overlay is preserved, just narrowed via:not(.wp-lightbox-caption).*.native.js) were not modified — the new attributes are optional and the native UI simply ignores them.A note on rich-text captions
The inline caption attribute is a
rich-text, so authored markup like<strong>and<a>is preserved at the block level and still renders on the front-end figure. Inside the lightbox overlay the markup is stripped to plain text because the Interactivity API currently has no safe way to bind HTML from state —data-wp-textis the only text-rendering directive. Keeping links live inside the overlay (plus the focus/escape interactions that requires) is worth a separate design discussion.Testing Instructions
Expected default state: both toggles on, captions visible both in the grid and in the lightbox (the pre-#58835 behaviour). Click an image — the lightbox opens and the caption fades in at the bottom once the zoom settles.
Variations to cover:
prefers-reduced-motion: reduceset in the OS, captions should appear and disappear without a fade.<figcaption>inside the overlay is still read as the image's caption when the overlay is open.Screenshots or screencast
Before: caption hidden in the lightbox.
After: caption fades in at the bottom of the lightbox overlay, with Gallery-level controls for where captions should be displayed.
Related work
This PR unblocks the first phase of a longer effort to replace the wordpress.org Plugin Directory's screenshot gallery with core blocks:
A follow-up Gutenberg PR is planned to add per-image overrides for these settings (so an individual image inside a gallery can opt out of the gallery-wide default) and to look at richer caption options in the lightbox (e.g. link support, fixed positions). Those are not required to close this issue and are kept out of this PR to keep the scope focused.
Fixes #60469