Nested span generated when dragging text within contenteditable span
OS: Any Any · Device: Desktop Any · Browser: Firefox 90+
Open case →Scenario
Analysis of Firefox's inconsistent handling of native Drag-and-Drop operations within editable containers.
Drag-and-Drop (DnD) within contenteditable is a complex interaction involving the DataTransfer API and internal DOM mutations. While Chromium and WebKit have converged on a “move” behavior that dispatches specific beforeinput types (like deleteByDrag), Firefox often fails to execute the default action. This leaves the text at the source and provides no automated way to teleport it to the destination.
In recent versions (v130+), selecting a text fragment and dragging it within the same editor results in a visual ghost but no actual DOM mutation upon drop.
/* Observer Sequence */
element.addEventListener('dragstart', (e) => {
console.log('1. Drag started'); // Fires
});
element.addEventListener('drop', (e) => {
console.log('2. Drop fired'); // Fires, but default action is skipped by Engine
});
Dragging content into or out of nested <span> elements often causes Firefox to generate redundant wrapper nodes, breaking the logical tree of the editor.
DataTransfer.beforeinput (deleteByDrag/insertFromDrop) natively.Explicitly set and get the plain text/HTML in the data transfer object to ensure cross-platform compatibility.
element.addEventListener('dragstart', (e) => {
const range = window.getSelection().getRangeAt(0);
e.dataTransfer.setData('text/plain', range.toString());
e.dataTransfer.effectAllowed = 'move';
});
element.addEventListener('drop', (e) => {
e.preventDefault();
const data = e.dataTransfer.getData('text/plain');
const targetRange = document.caretRangeFromPoint(e.clientX, e.clientY);
// Explicitly delete source and insert at target
// Warning: Requires custom transaction handling in frameworks like Lexical
moveFragment(sourceRange, targetRange, data);
});
Visual view of how this scenario connects to its concrete cases and environments. Nodes can be dragged and clicked.
Each row is a concrete case for this scenario, with a dedicated document and playground.
| Case | OS | Device | Browser | Keyboard | Status |
|---|---|---|---|---|---|
| ce-0310-firefox-nested-span-drag-en | Any Any | Desktop Any | Firefox 90+ | Any | draft |
| ce-0554-firefox-drag-drop-textarea-en | Any Any | Desktop Any | Firefox 90+ | Any | draft |
| ce-0569 | Linux Ubuntu 24.04 | Desktop Any | Firefox 132.0 | US QWERTY | confirmed |
This matrix shows which browser and OS combinations have documented cases for this scenario. Click on a cell to view the specific case.
| Browser | Any | Linux |
|---|---|---|
| Firefox | ce-0569 132.0 |
This scenario affects multiple languages. Cases are grouped by language/input method below.
OS: Any Any · Device: Desktop Any · Browser: Firefox 90+
Open case →OS: Any Any · Device: Desktop Any · Browser: Firefox 90+
Open case →OS: Linux Ubuntu 24.04 · Device: Desktop Any · Browser: Firefox 132.0
Open case →Other scenarios that share similar tags or category.
When editing content inside an element with `position:relative`, the text caret (cursor) is completely invisible. Text can be typed and appears in the editor, but there's no visual feedback of where the insertion point is located.
After pasting content into a contenteditable region, the caret position does not end up at the expected location, sometimes jumping to the beginning of the pasted content or to an unexpected position.
Analysis of how out-of-order or missing composition events disrupt editor state synchronization.
When a parent element has contenteditable="true" and a child element has contenteditable="false", the inheritance behavior is inconsistent across browsers. Some browsers allow editing in the child, while others correctly prevent it. The behavior may also differ when the child has contenteditable="inherit" or no contenteditable attribute.
When a contenteditable region is inside a table cell (`<td>`), editing the content may cause layout issues in Firefox. The table may resize unexpectedly or the cell may overflow.
Have questions, suggestions, or want to share your experience? Join the discussion below.