Atom block node adjacent to empty paragraph node

I was building a text editor in VueJS using prosemirror as the backbone. It has floating menu options for formatting, inline math node for allowing inplace math node and atomic block node that allows editing math on demand. The block_math node has following schema

    group : 'block',
    content: 'block*',
    attrs: {latex: {default: " (NH_4)Cr_2O_7  \\to  Cr_2O_3 + N_2 + 4H_20 "}},
    atom : true,
    selectable: true,

    parseDOM: [{
      tag: "div.block-math[latex]",
      getAttrs(dom) {
        let latex = dom.getAttribute("latex");
        return {latex};

    toDOM(node) {
      let mathHtml =  blockMathHtml(node.attrs.latex);
      let mathDom = htmlStrToDom(mathHtml);
      return ["div", {class : 'block-math text-caption', latex : node.attrs.latex}, mathDom];

The floating menu I have implemented is node aware. if I select a node of type paragraph and selection is non empty it shows formatting menus [B, I, f(), H1, H2] etc. If the paragraph node has empty text content it show embedding menus that allows inserting figure, block_math, video etc. Everything is working so great except the following issue:

Notice the gape between empty paragraph with light blue dotted border and the floating embedding menu with block_math insert option. To place the menu at the top + 4px of the cursor I am using let start = this.editorView.coordsAtPos(from); however for some reason an extra large space gets added when there is an atomic block_math node near it which doesn’t happen for p+p, ul+p, ol+p etc etc

I have tried lots of way to resolve the issue but nothing seem to help. Any kind of direction has a big thanks in advance.

So you are querying the coordinates of the position directly in front of the paragraph, and it produces coordinates above the paragraph? I don’t know why that is happening. If you can reduce this to a minimal case by seeing which schema structure an CSS is necessary to reproduce it, I can try to debug it.

So you are querying the coordinates of the position directly in front of the paragraph, and it produces coordinates above the paragraph?

I am actually trying to query the position of cursor(which is also an empty selection), the position approach is the same as the tooltip example in official website.

 let {from, to} = this.editorView.state.selection;
 let start = this.editorView.coordsAtPos(from);

The SCSS I am using is this:

.editor-doc-basic .ProseMirror{

    white-space: pre-wrap!important;
      outline: none;

      outline: 1px dashed $indigo-3;

    p, h2, h3
      background: white;
      padding: 4px;


  font-size: 1rem;
  line-height: 1.5;

  /*p, div {
    margin-bottom: 0;


  p, h2, h3{
    margin: 0;

  * +  p, p + h2, p + h3 {
    margin-top: 16px;

  p + ul, p + ol, h2 + ul, h2 + ol, h3 + ul, h3 + ol {
    margin-top : 8px

  ul, ol{
    padding-inline-start: 40px;

  ul, ol {
    li > p {
      margin-bottom: 0;
    li + li{
      margin-top: 8px;


    font-size: 14px; 
    padding-left: 16px * 2;

  * + div.block-math{
    margin-top: 16px;


To produce a minimal working case, I will require a little while. Kindly excuse me if possible for now. But as I am working 3days in a row to resolve this I can deduce following issues with atomic block node:

  • setting selectable:false in schema and tabindex=0 to corresponding dom of custom NodeView doesn’t help much for independent focusing. If an independent edit button placed inside such atomic block node it tends to pass click event down to the editor even if stopPropagation called.
  • If you notice the grey area and white background I have established for visual clarity, selecting an empty paragraph node immediately after atomic block node doesn’t really select it. But the same doesn’t happen if the paragraph is not empty.

@marijn I have separated the editor src implementation into a complete separate project so that you could try it by yourself for debugging.

The file has the required instruction. Try selecting, clicking and creating math nodes you would understand the problem with atomic block element I hope.

I am using quasar framework to scaffolds the whole app that helps quick development by providing a simple structure. Hence could not managed to provide a on-the-fly click and run solution, sorry about that.

That project errors out with a “Missing babel.config.js file…” message when I try to start it.

Also, that’s a lot more code than I’m willing to look into. What I meant was a single small script that uses the prosemirror packages to recreate the effect you’re seeing. That way, if the problem is caused by some of your CSS or code, you can do the work required to figure out which part is causing it.