browser-compat-data icon indicating copy to clipboard operation
browser-compat-data copied to clipboard

html.global_attributes.contenteditable - Firefox/Safari don't allow cursor to move after `<canvas>` at end of a `<p>` inside `contenteditable`

Open IgnacioHR opened this issue 4 years ago • 4 comments

What information was incorrect, unhelpful, or incomplete?

The problem detected applies specifically to firefox, chrome and MS Edge based on Chromium. Safari works just as expected!

The bug is documented here in the hope that Chrome, Firefox and Microsoft developers can incorporate a fix soon without having to open multiple parallel conversations. The bug has been reported here because it can be easily tested in the referenced page using the information provided below.

It should be a very simple bug fix!

Problem description

When a node has contenteditable="true", and the content node contains an <img> node, the user can move the cursor position after that node and press backspace to delete it. But if the node is a <canvas> then the referenced UAs does not allows the cursor to move after that node.

The W3C specification here https://www.w3.org/TR/2008/WD-html5-20080610/editing.html sais that

How the caret and selection are represented depends entirely on the UA.

What did you expect to see?

<canvas></canvas> should be considered as an <img> node and the user should be able to move the caret position after the canvas node and press backspace to delete it. As it is with an <img> node.

Did you test this? If so, how?

For testing purposes follow these steps:

  1. Head to the https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/contenteditable page
  2. modify the content of the <blockquote> node in the HTML tab and paste this content:
<p>Edit this content to add your own quote
  <img src="foo">
</p>
  1. click in the editable part of the "output" tab and press right cursor until the end of the line. The cursor moves smoothly character after character and allows it to be placed after the <img node, represented as a broken image (because of the lack of proper value in the src attribute)

  2. Now, try to repeat the same process with this code in the "html" tab

<p>Edit this content to add your own quote
  <canvas height="50" width="50"></canvas>
</p>
  1. For convenience, add this code to the CSS tab so you can see a blue rectangle around the canvas.
canvas {
  border: 1px solid blue;
}

Now, try to repeat step 3. The cursor cannot be moved to the right of the blue rectangle.

MDN page report details
  • Query: html.global_attributes.contenteditable
  • MDN URL: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/contenteditable
  • Report started: 2021-07-13T09:53:39.450Z

IgnacioHR avatar Jul 13 '21 18:07 IgnacioHR

@IgnacioHR I just checked and Firefox seems to have the same behavior as Safari now, i.e. backspace after the canvas deletes it. However, Chrome does not seem to have this behavior.

Can you confirm these findings? If so, I would encourage you to report the outstanding issue in the Chromium issue tracker: https://issues.chromium.org/issues/wizard

caugner avatar Jan 10 '25 17:01 caugner

Thank you @caugner for jumping in. As suggested, I've opened an issue here: https://issues.chromium.org/issues/389067061 BR/

IgnacioHR avatar Jan 10 '25 18:01 IgnacioHR

@caugner Please checkout the last comment on the thread https://issues.chromium.org/issues/389067061 Firefox fails if there is no space between the closing tag in "canvas" and the closing tag in "p". Please use exactly this text for testing:

<blockquote contenteditable="true">
  <p>Edit this content to add your own quote
  <canvas height="50" width="50"></canvas></p>
</blockquote>

<cite contenteditable="true">-- Write your own name here</cite>

IgnacioHR avatar Jan 31 '25 19:01 IgnacioHR

To summarize: It makes a difference here whether the element is A) somewhere inside the contenteditable element, or B) at the end of a <p> inside of it, and whether the element is 1) an <img>, or 2) a <canvas>.

The bottom line is that developers may expect that users can:

  • move the cursor behind the element (with arrow keys, or by clicking), and
  • delete the element (with backspace).

In case B2, these expectations are only met in Safari 18.5, but not in Chrome 137 and Firefox 139 (see this Playground).

Test results

✅ Cases A: Element somewhere inside the contenteditable element

✅ Case A1: <img>

<div contenteditable="true">
  <p>Before <img src="/example.png" height="50" width="50" /> After</p>
</div>
  • Can move the cursor behind the element: ✅ Chrome 137 ✅ Firefox 139 ✅ Safari 18.5
  • Can delete the element: ✅ Chrome 137 ✅ Firefox 139 ✅ Safari 18.5

⚠ Note: In Safari, the cursor has the height of the image.

✅ Case A2: <canvas>

<div contenteditable="true">
  <p>Before <canvas style="border:1px solid" height="50" width="50"></canvas> After</p>
</div>
  • Can move the cursor behind the element: ✅ Chrome 137 ✅ Firefox 139 ✅ Safari 18.5
  • Can delete the element: ✅ Chrome 137 ✅ Firefox 139 ✅ Safari 18.5

⚠ Note: In Safari, the cursor has the height of the canvas.

⚠ Cases B: Element at the end of a <p> inside that

✅ Case B1: <img>

<div contenteditable="true">
  <p>Before <img src="/example.png" height="50" width="50" /></p>
</div>
  • Can move the cursor behind the element: ✅ Chrome 137 ✅ Firefox 139 ✅ Safari 18.5
  • Can delete the element: ✅ Chrome 137 ✅ Firefox 139 ✅ Safari 18.5

❌ Case B2: <canvas>

<div contenteditable="true">
  <p>Before <canvas style="border:1px solid" height="50" width="50"></canvas></p>
</div>
  • Can move the cursor behind the element: ❌ Chrome 137 ❌ Firefox 139 ✅ Safari 18.5
  • Can delete the canvas with backspace: (❌ Chrome 137 ❌ Firefox 139) ✅ Safari 18.5

Interop notes

  • In Chrome, the cursor generally takes the height of the text, except immediately after the element, where it takes the height of the element.
  • In Firefox, the cursor always takes the height of the text.
  • In Safari, the cursor always takes the height of the element.

Long story, short: While this bug doesn't justify partial_implementation: true, we should still add notes for Chrome and Firefox mentioning this behavior, and referencing the Chrome bug and this Firefox bug (which contains this test case).

@IgnacioHR Would you like to open a PR with these changes? 🙏

caugner avatar Jun 13 '25 14:06 caugner