Summary
When a js-engine codeblock's build()/return value renders markdown containing two or more consecutive Obsidian callouts (via MarkdownRenderer.render()), the callouts visually overlap/bunch together in Live Preview mode. The exact same markdown renders correctly, with proper spacing, in Reading View.
Environment
SYSTEM INFO:
Obsidian version: 1.12.7
Installer version: 1.12.7
Operating system: MacOS
Language: en
Insider build toggle: off
Live preview: on
Base theme: adapt to system
Community theme: Minimal 8.2.1
Snippets enabled: 0
Restricted mode: off
Plugins installed: 12
Plugins enabled: 1
1: JS Engine v0.3.6
Minimal reproduction
Paste the following into a note and view it in Live Preview:
> [!danger]
> Contents
> [!info]
> Contents
```js-engine
const markdown = [
'> [!danger]',
'> Contents',
'',
'> [!info]',
'> Contents',
].join('\n');
const root = document.createElement('div');
await obsidian.MarkdownRenderer.render(app, markdown, root, context.file.path,
component);
return root;
```
Expected: Two distinct callout boxes, each with normal padding/spacing between them, matching how the same markdown renders in Reading View.
Actual: The two callouts visually overlap/bunch together in Live Preview.

Switching the same note to Reading View renders them correctly.

Additional observation
If the blank line between the two callouts is removed, the second callout is (correctly, per markdown/Obsidian callout semantics) absorbed into the first callout's body rather than rendered as a separate callout — this confirms the markdown being rendered is well-formed, and that a blank line is present between the two callout blocks in the repro above. The bunching bug in Live Preview only occurs even when the blank-line separation is present and correct.
Suspected mechanism (unconfirmed)
I don't have visibility into JS Engine's internals, so I want to be upfront that this hypothesis comes from an AI coding assistant (Claude, via Aider) that helped me investigate this issue in my own plugin, not from direct knowledge of your codebase. Take it as a possible lead, not a diagnosis:
The working theory is that whatever CodeMirror 6 block-widget wrapper JS Engine uses to host a codeblock's returned DOM node may be measuring/caching the widget's height once, at or shortly after the point the returned element is handed to CM6 — before Obsidian's own callout rendering machinery (e.g. fold-arrow injection, icon rendering) finishes any deferred layout/paint work on the returned DOM. If so, later growth in the DOM subtree wouldn't trigger CM6 to re-measure that widget's height, causing subsequent content to overlap the space CM6 already allocated for it.
I want to stress I haven't confirmed this against your actual implementation — it's an inference from black-box behavior (works in Reading View, breaks in Live Preview, reproducible in complete isolation with only JS Engine enabled) rather than something I've traced through JS Engine's source.
What I've ruled out
• Confirmed not caused by any other plugin, including my own—reproduced with JS Engine as the sole enabled community plugin, after a full Obsidian reload.
• The markdown being rendered is correctly formed (confirmed via the blank-line test above).
Happy to provide more detail, test a patch, or run further diagnostics if useful.
Summary
When a js-engine codeblock's build()/return value renders markdown containing two or more consecutive Obsidian callouts (via MarkdownRenderer.render()), the callouts visually overlap/bunch together in Live Preview mode. The exact same markdown renders correctly, with proper spacing, in Reading View.
Environment
SYSTEM INFO:
Obsidian version: 1.12.7
Installer version: 1.12.7
Operating system: MacOS
Language: en
Insider build toggle: off
Live preview: on
Base theme: adapt to system
Community theme: Minimal 8.2.1
Snippets enabled: 0
Restricted mode: off
Plugins installed: 12
Plugins enabled: 1
1: JS Engine v0.3.6
Minimal reproduction
Paste the following into a note and view it in Live Preview:
Expected: Two distinct callout boxes, each with normal padding/spacing between them, matching how the same markdown renders in Reading View.
Actual: The two callouts visually overlap/bunch together in Live Preview.

Switching the same note to Reading View renders them correctly.

Additional observation
If the blank line between the two callouts is removed, the second callout is (correctly, per markdown/Obsidian callout semantics) absorbed into the first callout's body rather than rendered as a separate callout — this confirms the markdown being rendered is well-formed, and that a blank line is present between the two callout blocks in the repro above. The bunching bug in Live Preview only occurs even when the blank-line separation is present and correct.
Suspected mechanism (unconfirmed)
I don't have visibility into JS Engine's internals, so I want to be upfront that this hypothesis comes from an AI coding assistant (Claude, via Aider) that helped me investigate this issue in my own plugin, not from direct knowledge of your codebase. Take it as a possible lead, not a diagnosis:
The working theory is that whatever CodeMirror 6 block-widget wrapper JS Engine uses to host a codeblock's returned DOM node may be measuring/caching the widget's height once, at or shortly after the point the returned element is handed to CM6 — before Obsidian's own callout rendering machinery (e.g. fold-arrow injection, icon rendering) finishes any deferred layout/paint work on the returned DOM. If so, later growth in the DOM subtree wouldn't trigger CM6 to re-measure that widget's height, causing subsequent content to overlap the space CM6 already allocated for it.
I want to stress I haven't confirmed this against your actual implementation — it's an inference from black-box behavior (works in Reading View, breaks in Live Preview, reproducible in complete isolation with only JS Engine enabled) rather than something I've traced through JS Engine's source.
What I've ruled out
• Confirmed not caused by any other plugin, including my own—reproduced with JS Engine as the sole enabled community plugin, after a full Obsidian reload.
• The markdown being rendered is correctly formed (confirmed via the blank-line test above).
Happy to provide more detail, test a patch, or run further diagnostics if useful.