ProseMirror Proposal: Range-wrapping decoration

Title: Decoration type for wrapping a range of sibling nodes in a container element

While working on a personal project, I ran into a limitation I think many ProseMirror editors would benefit from solving upstream: there’s no way to wrap a range of sibling block nodes in a decoration-injected container element.

The problem comes up whenever an editor needs section-level formatting — different CSS custom properties (or any styling) applied to different contiguous groups of top-level nodes. Think of a document where one section has column-count: 2 and the next is single-column, or one section has a narrower max-width than another, or different font-size / margin values per section.

For inline text properties, Decoration.node() works fine — you can set a different inline style on each individual node. But for properties that require a containing element (column layout, max-width, margin, and any CSS that needs to apply to a group rather than an individual node), there’s no decoration-based solution. Decoration.node() requires from/to to bracket exactly one node.

What I’d want is something like:

Decoration.wrap(from, to, {style: "column-count: 2; max-width: 29.7cm"})

…where from/to span a range of sibling nodes at the same depth, and a <div> wraps them — transparent to position mapping, like how MarkViewDesc wraps inline content with zero border.

Looking at the internals, MarkViewDesc already solves the same structural problem for inline content: it wraps runs of nodes in a DOM element that contributes no position offset. A block-level equivalent for decorations, modeled on the same pattern, seems like a natural extension.

Use cases I can see:

  • Section-level formatting (different margins, font sizes, or orientations per section)
  • Multi-column layouts where column count varies by section (common in academic papers: single-column abstract, two-column body)
  • Chapter or part separators with different page widths
  • Newsletter/magazine-style mixed layouts

Questions:

  1. Is this something you’d consider for prosemirror-view?
  2. Would you prefer a new Decoration.wrap() type, or extending Decoration.node() to relax the single-node constraint?
  3. Are there position-mapping concerns beyond what MarkViewDesc already handles? The pattern seems directly reusable for block content.

I’d be happy to implement this and submit a PR if the approach makes sense.

Decorations, as they exist, actually never span multiple nodes, even inline ones. Adding support for a feature like this would involve rather large changes to the way the renderer works, which I don’t think I want to undertake—it is already quite complicated. And no, a PR would not make me more inclined towards this, since that would still put the work of reviewing and dealing with subsequent fallout on me.