skip to Main Content

So, if we select and copy two paragraphs sitting next to each other, and then paste it in the text editor, there will be a blank line between them. If we do the same but with any other block elements, e.g. headers, there’s no blank line. Why is it happening and how can I achieve this behaviour on other block elements?

Code (paragraphs):

<p>first paragraph</p>
<p>second paragraph</p>

Result (paragraphs):

> first paragraph
> 
> second paragraph

Code (other elements):

<h3>first paragraph</h3>
<h3>second paragraph</h3>

Result (other elements):

> first paragraph
> second paragraph

Notice, there’s no blank line between the lines in the second result.

textarea {
  width: 30em;
  height: 10em;
}
<h3>Select and copy these four lines of text</h3>
<div>Paste into the textarea below</div>
<p>There is a blank line after the P element</p>
<h4>What causes this?</h4>
<textarea></textarea>

2

Answers


  1. Use this css.

    p { margin: 0; }

    Login or Signup to reply.
  2. There is nothing in the Standart that specifies how the HMTl should be converted to Plain text, so this depends entirely on the application you copy from and/or the on one you past in.

    A clipboard can hold multiple reperesentations of othe data you copied.

    On past the application checks the clipboard for the best matching representation for the target (or on the desired behaviour the user chooses for insert), and converts the data if necessary (with its own rules)

    In JavaScript you can overwrite what is stored in the clipboard upon copy:

    function copyListener(event) {
      event.clipboardData.setData("text/html", "here we have <strong>html</strong>");
      event.clipboardData.setData("text/plain", 'this is just plain text');
      event.preventDefault();
    
    };
    
    document.addEventListener("copy", copyListener, false);
    .editor {
      width: 30em;
      height: 10em;
      border: 1px solid rgb(200, 200, 200)
    }
    <p>copy me</p>
    <p>
      Past as Plain:
    </p>
    <textarea class="editor"></textarea>
    <p>
      Past as HTML:
    </p>
    <div contenteditable class="editor">
    </div>

    So as you can see here, something complelty different to "copy me" is saved in the clipboard, and depending on whether you past it to <textarea> or contenteditable you get the corresponding data.

    This is also the case (for many application and OSs) if you past it into a different application. If you past it "normally" it a RTE it would use the HTML version, or if you choose "Past as plain text" or "Past and Match style" which would use "text/plain". If no "text/plain" is present it is up to the application that performs the past to decide how to format it.

    So if you want to have something consistent for the plain text you could use the html as is and then just overwrite the text/plain with your own converted text.

    function copyListener(event) {
      const range = window.getSelection().getRangeAt(0);
      const rangeContents = range.cloneContents();
      const wrapper =  document.createElement('div')
      wrapper.appendChild(rangeContents);
    
      // store the actual HTML for rich text editors
      event.clipboardData.setData("text/html", wrapper.innerHTML);
    
      // store some custome plain text
      event.clipboardData.setData("text/plain", 'my custom plain text');
      
      event.preventDefault();
    };
    
    
    document.addEventListener("copy", copyListener, false);
    .editor {
      width: 30em;
      height: 10em;
      border: 1px solid rgb(200, 200, 200)
    }
    <h3>Select and copy these four lines of text</h3>
    <div>Paste into the textarea below</div>
    <p>There is a blank line after the P element</p>
    <h4>What causes this?</h4>
    
    
    <p>
      Past as Plain:
    </p>
    <textarea class="editor"></textarea>
    <p>
      Past as HTML:
    </p>
    <div contenteditable class="editor">
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search