Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent Chrome from wrapping contents of joined <p> with a <span>

I have observed an undesirable behaviour in Chrome that occurs when one joins two <p>'s by deleting the separation between them. Although the <p> tags are joined properly, Chrome wraps the right-most <p> tag's content with a <span>.

Edit: this happens for all block elements, not just p tags.

Example:

For example, when the separating </p><p> are deleted from the following block:

<div contenteditable="true"><p>p one.</p><p>p two.</p></div> 

It becomes:

<div contenteditable="true"><p>p one.<span style="font-size: 16px; line-height: 1.44;">p two.</span></p> 

Example in a fiddle: Chrome wrapping contents of joined <p> with a <span>.

Question:

Is there an easy way to prevent chrome from doing this? It results in horrible markup that I'd like very much to be rid of.

like image 757
Michael Robinson Avatar asked Feb 22 '13 00:02

Michael Robinson


People also ask

How to stop a span from wrapping?

You can make the contents of HTML <p>, <div>, and <span> elements not to wrap by using some CSS. You need the white-space property. As we know, this property helps us to handle the spaces within the element.

How to prevent p tag from wrapping?

You can add white-space: nowrap to the p tag css and it will stop the wrapping. Save this answer.


2 Answers

There is a way but you need to pro-actively set a few styles. The idea is to tell Chrome that the styles are already taken care of, so it doesn't need to add SPAN to meet the styles requirement. basically, you need to add the chrome added styles to a span class under your contenteditable div ( see example below).

Edited fiddle

For you example:

  • I added an "edit" class to the contenteditable DIV
  • I added an .edit p, span class in the style

This becomes:

.edit {   border: 1px solid gray;   padding: 10px; } .edit p, span {   line-height: 1.44; font-size: 16px; } 

And the DIV:

<div contenteditable="true" class="edit">...</div> 

Note that you normally don't need the font-size: 16px;. I needed to add this one because fiddle defines some font size in contenteditable. On a standalone page I didn't need it.

You need to apply this Chrome 'patch' to any elements where it happens (so if you need UL, OL... then add what is needed following my example logic above)

like image 174
JScoobyCed Avatar answered Sep 22 '22 14:09

JScoobyCed


I know it is not really an answer to solve it, but a hint how it could be fixed (but it is to long to be a comment to Petah question how i would solve it)

in general you would check when such bugs could happen. for the case of the span creation you would listen to all keydown and keypress events and check if the key is the backspace/delete key or for every key that inserts chars if it is a real selection.

if this is the case then you need to check the current selection (either the position of the insert mark, or the real selection) then you know which is the next following text-element or node. then you need to check the in the next following keypress and keyup if there is a span created directly after your insert mark. depending on the browser bug you need some further checking. if there is one create unwrap its content again. additionale Mutation events and helper attributes could be used.

But i need to say that i gave up in doing this myself and switched over to ckeditor 4. most of the it's features i don't need and it is a really big library. but cause of the huge number of such bugs i did not see another solution for me.

EDIT Here an update of the js fiddle that shows the idea with a Mutable event: http://jsfiddle.net/THPmr/6/

But that is not bullet proofed, it is just to show how it could be achived ( only tested in chrome 27.0.1422.0, and probably would not work if more then one text element is contained in the second p )

like image 38
t.niese Avatar answered Sep 21 '22 14:09

t.niese