Skip to content

fix(view): don't collapse paragraphs in a block view field - #673

Open
nelsonlove wants to merge 1 commit into
mProjectsCode:masterfrom
nelsonlove:fix/view-block-paragraphs
Open

fix(view): don't collapse paragraphs in a block view field#673
nelsonlove wants to merge 1 commit into
mProjectsCode:masterfrom
nelsonlove:fix/view-block-paragraphs

Conversation

@nelsonlove

Copy link
Copy Markdown

The problem

A view field rendering multi-paragraph markdown loses its paragraph breaks when it's a block field:

```meta-bind
VIEW[{overview}][text(renderMarkdown)]
```

with

overview: |-
  First paragraph.

  Second paragraph.

renders as one run of text. MarkdownRenderer.render produces two <p> elements correctly — the CSS then flattens them.

Cause

ViewFieldMountable already tags its wrapper from renderChildType:

this.renderChildType === RenderChildType.BLOCK
    ? addClass(el, 'mb-view-block')
    : addClass(el, 'mb-view-inline');

but styles.css never referenced either class. The inline rules applied unconditionally:

div.mb-view-wrapper.mb-view-markdown > p { margin: 0; display: inline-block; }
div.mb-view-wrapper { display: inline; }

Two zero-margin inline-block paragraphs inside an inline wrapper sit side by side, so the break disappears.

Collapsing is correct for an inline view — it lives inside a sentence and must not introduce block flow. It's wrong for a block view, which has a line of its own.

The change

CSS only. Scoped with :not(.mb-view-block), so:

  • inline views are byte-identical — same selectors match, same declarations;
  • block views inherit Obsidian's own <p> styling rather than being counter-styled, so they pick up the theme's paragraph spacing automatically;
  • a wrapper carrying neither class (if any path exists) still gets the inline treatment, so there's no regression surface.

This mirrors the .mb-input-inline / .mb-input-block pair that already exists for input fields — the same distinction, just never wired up for views.

Verification

bun run build, format:check, lint and typecheck all pass. Confirmed the compiled dist/styles.css carries the scoped selectors, and reproduced the original behaviour against 1.5.1 in a live vault.

nelsonlove added a commit to nelsonlove/obsidian-meta-bind-plugin that referenced this pull request Aug 14, 2026
A BRAT build of upstream 1.5.1 plus the block-view paragraph fix
(mProjectsCode#673) and nothing else.

Cut from the 1.5.1 tag rather than master deliberately: master carries two
unreleased upstream commits — a new optionSource feature (~840 lines) and a
speculative "maybe fix mProjectsCode#667" — and a local install should not inherit those
just to get a CSS fix.

Versioned `-nl.1` so it sorts above 1.5.1 and below 1.5.2: upstream supersedes
this build on their next release. Retire it once mProjectsCode#673 lands.
A view field already tags itself `mb-view-inline` or `mb-view-block` from
`renderChildType`, but styles.css never referenced either class: the inline
rules applied unconditionally. So a block view rendering multi-paragraph
markdown had its <p> elements forced to `display: inline-block` with zero
margin inside an `inline` wrapper, and two paragraphs ran together on one line.

Collapsing is right for an inline view — it sits inside a sentence and must not
introduce block flow. It is wrong for a block view, which has a line of its own,
and there it silently destroys the author's paragraph breaks.

Note which element carries which class: ViewFieldMountable puts
mb-view-block / mb-view-inline on `targetEl`, and mb-view-wrapper on the child
div it creates inside it, which is also the element TextVF marks
mb-view-markdown. The mode therefore has to be matched on the parent — a
`.mb-view-wrapper.mb-view-block` selector matches nothing.

Scoped `:not(.mb-view-block) > …` so the inline case is unchanged, a block view
inherits Obsidian's own <p> styling rather than being counter-styled, and a
wrapper with no mode class (JsViewFieldMountable) keeps what it had.

Reproduce: a note property holding two paragraphs, rendered with
`VIEW[{prop}][text(renderMarkdown)]` in a ```meta-bind block — the blank line
between them disappears.
@nelsonlove
nelsonlove force-pushed the fix/view-block-paragraphs branch from 98f6420 to 479b79f Compare August 14, 2026 07:48
nelsonlove added a commit to nelsonlove/obsidian-meta-bind-plugin that referenced this pull request Aug 14, 2026
Corrects nl.1, which shipped selectors that matched nothing: mb-view-block sits
on targetEl, the parent of the .mb-view-wrapper element, so the mode has to be
matched on the parent. nl.1 was a no-op.

Upstream 1.5.1 plus mProjectsCode#673.
Written as :not(.mb-view-block) > … so a block view inherits Obsidian's own
<p> styling untouched, and every other case — including a wrapper with no
mode class, e.g. JsViewFieldMountable — keeps exactly what it had. */
:not(.mb-view-block) > div.mb-view-wrapper.mb-view-markdown > p {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

I don't really think the long comment is necessary. One sentance or no comment at all should suffice. Also I wonder, why you did not use .mb-view-inline > div.mb-view-wrapper.mb-view-markdown > p instead of :not(.mb-view-block) > .... Same applies on line 76.

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