Skip to content

Fix stacked modals on Mermaid diagrams and squished figure captions#405

Open
JakeSCahill wants to merge 2 commits into
mainfrom
fix/mermaid-modal-and-caption
Open

Fix stacked modals on Mermaid diagrams and squished figure captions#405
JakeSCahill wants to merge 2 commits into
mainfrom
fix/mermaid-modal-and-caption

Conversation

@JakeSCahill

@JakeSCahill JakeSCahill commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Problems

  1. Two stacked modals per click. The Antora Mermaid extension wraps every diagram in <div class="imageblock">, so 07-expand-images.js bound its generic lightbox to Mermaid diagrams in addition to the dedicated zoom modal from 20-mermaid-zoom.js. One click opened both overlays (Mermaid modal at z-index: 2147483647, generic at 9999). Closing the Mermaid modal revealed the generic lightbox underneath: a dimmed page showing through the cloned transparent-background SVG, with a stray close button in the corner.
  2. Squished captions. Mermaid SVGs have no internal bottom padding, so the standard 0.5rem figure-caption margin left the caption pressed against the diagram's bottom boxes.
  3. Duplicate #modal-overlay. feedback-forms.hbs shipped an empty <div class="modal-overlay" id="modal-overlay"> that nothing references. It duplicates the id of the expand-images overlay, so getElementById('modal-overlay') returns the dead element.

Fixes

  • 07-expand-images.js: skip imageblocks that contain a .mermaid diagram when binding the generic lightbox
  • mermaid.css: 1.25rem top margin for figure captions that follow a Mermaid diagram
  • feedback-forms.hbs: remove the dead duplicate overlay div

Second commit: subgraph label spacing

Mermaid v10 and v11 flowcharts never reserve vertical space between a subgraph label and nested subgraphs: the label overlaps the inner boxes' top borders, and no configuration changes this (flowchart.subGraphTitleMargin.bottom only grows the box downward, .top pushes the label down into the content, and flowchart.padding is a no-op for label-to-child distance; all measured at a constant -3px gap). A new 08-mermaid-label-spacing.js post-processes each rendered SVG: for any cluster whose label sits within 12px of a fully-contained child cluster, it shifts the label up, grows the cluster rect, and expands the viewBox for top-level clusters. Verified on the Stretch Cluster topology diagrams (label-to-content gap goes from -2px overlap to +8px clear space), with side-by-side and stacked sibling panels correctly left untouched.

Verification

Reproduced both bugs on the live deploy-preview for redpanda-data/docs#1820 (Chrome DevTools protocol: real click opened both overlays; closing the Mermaid modal left .modal-overlay.active behind). Rebuilt the bundle with these fixes, built the docs site against it, and re-ran the same click sequence: only the Mermaid modal opens, closing it restores the page with no lingering overlay and body scroll intact, and the caption spacing renders with clear separation. gulp lint and gulp bundle pass.

🤖 Generated with Claude Code

@netlify

netlify Bot commented Jul 23, 2026

Copy link
Copy Markdown

Deploy Preview for docs-ui ready!

Name Link
🔨 Latest commit ad9fde5
🔍 Latest deploy log https://app.netlify.com/projects/docs-ui/deploys/6a6201fd171ea80008c24a7b
😎 Deploy Preview https://deploy-preview-405--docs-ui.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 27 (no change from production)
Accessibility: 89 (no change from production)
Best Practices: 92 (no change from production)
SEO: 89 (no change from production)
PWA: -
View the detailed breakdown and full score reports

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The changes add top spacing for Mermaid diagram captions, prevent Mermaid-containing image blocks from opening the image expansion modal, and remove the trailing modal overlay element from the feedback form template.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Possibly related PRs

Suggested reviewers: kbatuigas

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the main Mermaid modal and caption spacing fixes.
Description check ✅ Passed The description accurately matches the implemented fixes and verification steps.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/mermaid-modal-and-caption

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Mermaid diagrams are wrapped in an imageblock div, so the generic
expand-images lightbox bound to them alongside the dedicated Mermaid
zoom modal. One click opened both overlays stacked, and closing the
Mermaid modal left the plain lightbox behind. Skip imageblocks that
contain a Mermaid diagram when binding the generic lightbox.

Mermaid SVGs have no internal bottom padding, so the 0.5rem figure
caption margin looked squished against the diagram. Give Mermaid
captions 1.25rem.

Also remove a dead, duplicate #modal-overlay div from the feedback
form partial. Nothing references it, and the duplicate id breaks
getElementById-based checks against the real overlay.
@JakeSCahill
JakeSCahill force-pushed the fix/mermaid-modal-and-caption branch from 9c3c62a to 36fa6fd Compare July 23, 2026 10:17

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/css/mermaid.css`:
- Around line 7-11: Update the Mermaid caption selector in the `.doc
.imageblock` rule to match `.title` elements that follow `.mermaid` even when an
intervening sibling wrapper exists, while keeping the match scoped to the image
block and preserving the existing margin.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f14c9eb2-52f3-408f-9bdc-2ee197a28d9c

📥 Commits

Reviewing files that changed from the base of the PR and between dc31210 and 36fa6fd.

📒 Files selected for processing (3)
  • src/css/mermaid.css
  • src/js/07-expand-images.js
  • src/partials/feedback-forms.hbs
💤 Files with no reviewable changes (1)
  • src/partials/feedback-forms.hbs

Comment thread src/css/mermaid.css
Comment on lines +7 to +11
/* Mermaid SVGs have no internal bottom padding, so the figure caption
needs more separation than a regular image caption. */
.doc .imageblock .mermaid + .title {
margin-top: 1.25rem;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -n -C 6 'mermaid|imageblock|class="title"|class="content"' . \
  --glob '*.hbs' --glob '*.adoc' --glob '*.html' --glob '*.js'

Repository: redpanda-data/docs-ui

Length of output: 20505


🌐 Web query:

Antora asciidoctor asciimath mermaid block imageblock generated HTML .mermaid .content .title

💡 Result:

In Antora, Mermaid diagrams are not supported out-of-the-box by Asciidoctor and require specific extensions [1][2][3]. There are two primary ways to handle them: via the @sntke/antora-mermaid-extension (client-side rendering) or via extensions like asciidoctor-kroki (server-side rendering) [1][4]. Client-side rendering with @sntke/antora-mermaid-extension: This extension preserves the Mermaid source in the generated HTML [1][5]. When a [mermaid] block is processed, it typically outputs a block element (often a div or pre) assigned the CSS class.mermaid [5]. The structure of the generated HTML generally includes:.mermaid: The container element for the diagram [5]..content: Within the container, the raw text definition of the Mermaid diagram is preserved [5]..title: If a title is provided for the block in AsciiDoc (e.g.,.Diagram Title), it is rendered by Asciidoctor and typically appears as a separate element (e.g.,.title) associated with the block [5]. Configuration: To use this, you must add the extension to your antora-playbook.yaml under the antora.extensions section, not the asciidoc.extensions section [1][6]. You will also need to ensure the Mermaid.js library is loaded via your UI bundle's scripts [1][7]. Server-side rendering with Kroki: Alternatively, using asciidoctor-kroki allows for rendering diagrams into image files (e.g., SVG or PNG) at build time [8][4]. In this approach, the output is typically a standard AsciiDoc block image [9]. This is configured by adding asciidoctor-kroki to the asciidoc.extensions list in your playbook [4]. Important Note: If you are using the @sntke/antora-mermaid-extension, be aware that misconfiguration of attributes in your antora.yml can sometimes interfere with block processing [5]. Always ensure you are targeting the correct extension facility (Antora vs. Asciidoctor) based on your chosen rendering method [6].

Citations:


Target the direct children when matching Mermaid titles.

The current selector depends on .title being the immediate sibling of .mermaid; if the rendered block contains a sibling child wrapper before the title, the spacing rule won’t apply. Use a more direct structural selector, such as .doc .imageblock .mermaid + .title, to reduce reliance on sibling ordering without losing the intended target.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/css/mermaid.css` around lines 7 - 11, Update the Mermaid caption selector
in the `.doc .imageblock` rule to match `.title` elements that follow `.mermaid`
even when an intervening sibling wrapper exists, while keeping the match scoped
to the image block and preserving the existing margin.

Mermaid v10 and v11 flowcharts never reserve vertical space for a
cluster label above nested subgraphs: the label overlaps the inner
boxes' top borders, and neither flowchart.subGraphTitleMargin nor
flowchart.padding changes the label-to-content distance (top shifts
the label down into the content, bottom only grows the box downward).

Post-process the rendered SVG instead: for each cluster whose label
sits within 12px of a fully-contained child cluster, shift the label
up, grow the cluster rect, and expand the viewBox for top-level
clusters.
@Feediver1

Copy link
Copy Markdown
Contributor

Suggestions for 08-mermaid-label-spacing.js (non-blocking)

  • Diagrams in hidden tab panes get marked "fixed" without being fixed. If a Mermaid diagram sits in a hidden tab (we use context-switcher tabs in the docs), getBBox() throws in Firefox — the cluster is skipped — yet fixSvg still stamps data-label-spacing="fixed", so the poll never retries and the label overlap survives when the user opens the tab. In Chrome, getBBox() on non-rendered content returns a zero-height box instead of throwing, which makes the gap check use lh = 0 — likely skipping the fix rather than corrupting it, but still wrong. Suggested fix: bail out of fixSvg without setting the attribute when the SVG isn't rendered (svg.getClientRects().length === 0), so later polls — or a tab-activation listener — can retry.
  • viewBoxGrow counts nested clusters too. The comment says the viewBox expands "for top-level clusters," but the code takes Math.max over every shifted cluster, so a shift on a deeply nested cluster also grows the outer viewBox — pure extra whitespace, cosmetic only. Related: cluster processing order affects results slightly (a child shifted before its
    parent is measured feeds the parent its new position); harmless, but a one-line comment acknowledging order-dependence would help the next reader.
  • Numbering collision: 08-mermaid-label-spacing.js sits next to 08-move-anchors.js. The repo already has 19-/20-/21- duplicates, so this follows local precedent — noting it only in case the team wants to start disambiguating.

@Feediver1 Feediver1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

non-blocking suggestions

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants