Skip to content

fix: responsive Mermaid SVG sizing via startOnLoad: false + auto-fit#17

Open
digitall-it wants to merge 2 commits intonicobailon:mainfrom
digitall-it:fix/mermaid-svg-responsive-sizing
Open

fix: responsive Mermaid SVG sizing via startOnLoad: false + auto-fit#17
digitall-it wants to merge 2 commits intonicobailon:mainfrom
digitall-it:fix/mermaid-svg-responsive-sizing

Conversation

@digitall-it
Copy link

Problem

Mermaid renders SVGs with hardcoded pixel width/height attributes. When those SVGs land inside flexbox-centered containers (.mermaid-wrap with align-items: center), they appear tiny — the fixed-size SVG floats in a sea of dead space rather than filling the card.

Additionally, startOnLoad: true fires with no render callback, so there's no way to post-process the SVGs after Mermaid finishes.

Solution

startOnLoad: false + await mermaid.run() + auto-fit loop

After mermaid.run() resolves, strip the pixel dimensions, preserve viewBox, and apply width: 100%; height: auto:

await mermaid.run({ nodes: document.querySelectorAll('.mermaid') });
document.querySelectorAll('.mermaid-wrap').forEach(wrap => {
  const svg = wrap.querySelector('svg');
  if (!svg) return;
  if (!svg.getAttribute('viewBox')) {
    const w = parseFloat(svg.getAttribute('width')) || 800;
    const h = parseFloat(svg.getAttribute('height')) || 400;
    svg.setAttribute('viewBox', `0 0 ${w} ${h}`);
  }
  svg.removeAttribute('width');
  svg.removeAttribute('height');
  svg.style.width = '100%';
  svg.style.height = 'auto';
  svg.style.display = 'block';
});

Also remove display: flex; align-items/justify-content: center from .mermaid-wrap — that was the layout causing the centering issue.

Files changed

  • references/css-patterns.md — replaced "Centering fix" with "Responsive sizing" + new "Auto-fit after render (required)" section with the JS snippet
  • references/libraries.md — updated CDN example to use startOnLoad: false pattern; added note that ELK can produce inconsistent sizing (dagre preferred for most diagrams)
  • templates/mermaid-flowchart.html — CSS and script fixes applied to the reference template

Verified

Tested on a complex multi-diagram page (architecture flowchart + two sequence diagrams + ER diagram). Before: all diagrams rendered at ~200px centered in 600px+ cards. After: all diagrams fill their containers edge-to-edge and scale correctly on resize.

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings March 1, 2026 09:03
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the Mermaid reference template and documentation to render diagrams via startOnLoad: false + await mermaid.run(), then post-process the generated SVGs so they responsively fill their containers (removing fixed pixel sizing issues in centered/flex layouts).

Changes:

  • Switch Mermaid initialization to startOnLoad: false and explicitly render via await mermaid.run().
  • Add an “auto-fit” post-processing step that preserves/sets viewBox, strips width/height, and applies responsive sizing.
  • Update Mermaid container CSS guidance (remove flex-centering approach; prefer responsive SVG sizing + top-centered zoom origin).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
templates/mermaid-flowchart.html Applies mermaid.run() rendering + SVG auto-fit logic and adds SVG responsive CSS in the reference template.
references/libraries.md Updates CDN usage examples to the startOnLoad: false + mermaid.run() pattern and documents rationale.
references/css-patterns.md Replaces prior centering guidance with responsive sizing guidance and adds a required auto-fit snippet.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +11 to +23
**CDN — always use `startOnLoad: false` with explicit `mermaid.run()`:**
```html
<script type="module">
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';

mermaid.initialize({ startOnLoad: true, /* ... */ });
mermaid.initialize({ startOnLoad: false, /* ... */ });

await mermaid.run({ nodes: document.querySelectorAll('.mermaid') });
autoFitMermaidDiagrams(); // see css-patterns.md → Auto-fit after render
</script>
```

**Why `startOnLoad: false`?** `startOnLoad: true` fires an internal `DOMContentLoaded` listener with no render callback, so there's no hook to post-process the SVGs. `mermaid.run()` returns a Promise that resolves once every diagram is rendered — making it the only reliable place to strip the hardcoded pixel dimensions and apply responsive sizing (see css-patterns.md → Auto-fit after render).
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

The new wording says to always use startOnLoad: false, but later in this same doc the “Deep Theming” example still uses startOnLoad: true. This creates a direct contradiction for readers. Either soften this guidance to “recommended when you need a post-render hook (e.g., auto-fit)” or update the later examples to the mermaid.run() pattern as well so the doc is internally consistent.

Copilot uses AI. Check for mistakes.
Comment on lines +265 to +269
/* SVG responsiveness — applied by the auto-fit JS after mermaid.run() */
.mermaid-wrap .mermaid svg {
width: 100%;
height: auto;
display: block;
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

This comment is a bit misleading: the CSS rule isn’t “applied by” the auto-fit JS; rather, the JS removes Mermaid’s fixed width/height so this CSS can take effect. Consider rephrasing to avoid implying that JS injects the CSS, and to clarify the division of responsibilities (JS: strip attrs / ensure viewBox; CSS: responsive sizing).

Copilot uses AI. Check for mistakes.
Comment on lines +390 to +392
svg.style.width = '100%';
svg.style.height = 'auto';
svg.style.display = 'block';
Copy link

Copilot AI Mar 1, 2026

Choose a reason for hiding this comment

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

The SVG sizing is now set in two places: via CSS (.mermaid-wrap .mermaid svg { width: 100%; height: auto; display: block; }) and again via inline styles in this loop. Inline styles override CSS and create a second source of truth. Consider limiting the JS to viewBox/attribute cleanup and rely on the CSS rule for sizing/display to keep future tweaks in one place.

Suggested change
svg.style.width = '100%';
svg.style.height = 'auto';
svg.style.display = 'block';

Copilot uses AI. Check for mistakes.
Mermaid renders SVGs with hardcoded pixel width/height attributes, which
caused diagrams to appear tiny when centered inside large card containers.

Changes:
- Switch from `startOnLoad: true` to `startOnLoad: false` + explicit
  `await mermaid.run()` so we have a Promise to await before post-processing
- After render, strip fixed pixel dimensions, preserve viewBox, and apply
  `width: 100%; height: auto` so SVGs scale to their container
- Remove `display: flex; align-items/justify-content: center` from
  .mermaid-wrap (was centering tiny fixed-size SVGs in a sea of dead space)
- Add `.mermaid svg { width: 100%; height: auto; display: block; }` to CSS

Updated files:
- references/css-patterns.md — new "Responsive sizing" + "Auto-fit after render" sections
- references/libraries.md — startOnLoad: false pattern, ELK sizing caveat
- templates/mermaid-flowchart.html — CSS + script fixes applied to reference template
- libraries.md: soften "always use startOnLoad: false" to "use when you need
  a post-render hook"; update Deep Theming example to startOnLoad: false for
  internal consistency
- css-patterns.md: clarify that CSS handles sizing, JS only strips Mermaid's
  hardcoded attributes so the CSS rules can take effect
- templates/mermaid-flowchart.html: remove inline style assignments from the
  auto-fit loop; rely on CSS (width:100%; height:auto; display:block) as the
  single source of truth for SVG sizing
@digitall-it digitall-it force-pushed the fix/mermaid-svg-responsive-sizing branch from 1e5c7ae to 814df8b Compare March 1, 2026 09:18
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