Phenomenon
In Internet Explorer 11, when a line of text is selected in a contenteditable div and the user types, the <br> tag at the end of the line can be unexpectedly deleted, causing lines to merge together.
Reproduction Steps
- Open Internet Explorer 11 browser on Windows.
- Create a
contenteditablediv with multiple lines separated by<br>tags. - Select an entire line of text (e.g., “Line 2”).
- Type new text to replace the selected line.
- Observe the result.
Observed Behavior
- BR Tag Deletion: The
<br>tag at the end of the selected line is deleted. - Line Merging: Lines merge together, breaking the document structure.
- Formatting Loss: The line break is lost, causing formatting issues.
- IE11-Specific: This issue is specific to Internet Explorer 11.
Expected Behavior
- The
<br>tag should be preserved when typing after a selected line. - Lines should remain separate after typing.
- Document structure should not be corrupted.
Impact
- Line Break Loss: BR tags are deleted unexpectedly.
- Line Merging: Lines merge together, breaking document structure.
- Formatting Issues: Document formatting is corrupted.
- Content Integrity: Document content structure is damaged.
Browser Comparison
- Internet Explorer 11: This issue occurs.
- Chrome: Not affected.
- Firefox: Not affected.
- Safari: Not affected.
- Edge: Not affected (Edge uses Chromium).
Notes and Possible Workarounds
Preserve BR Tags During Typing
const editor = document.querySelector('[contenteditable]');
editor.addEventListener('beforeinput', (e) => {
if (e.inputType === 'insertText' || e.inputType === 'insertCompositionText') {
const selection = window.getSelection();
if (selection.rangeCount > 0) {
const range = selection.getRangeAt(0);
// Check if selection includes a BR tag
const container = range.commonAncestorContainer;
const walker = document.createTreeWalker(
container,
NodeFilter.SHOW_ELEMENT,
{
acceptNode: (node) => {
if (node.tagName === 'BR' && range.intersectsNode(node)) {
return NodeFilter.FILTER_ACCEPT;
}
return NodeFilter.FILTER_REJECT;
}
},
false
);
const brNodes = [];
let node;
while (node = walker.nextNode()) {
brNodes.push(node);
}
// Store BR nodes to restore later
if (brNodes.length > 0) {
e.preventDefault();
// Delete selected content
range.deleteContents();
// Insert new text
const textNode = document.createTextNode(e.data || '');
range.insertNode(textNode);
// Restore BR tags after the inserted text
brNodes.forEach(br => {
const newBr = document.createElement('br');
textNode.parentNode.insertBefore(newBr, textNode.nextSibling);
});
// Update selection
range.setStartAfter(textNode);
range.collapse(true);
selection.removeAllRanges();
selection.addRange(range);
}
}
}
});
Normalize After Input
editor.addEventListener('input', (e) => {
// Normalize BR tags after input
const lines = editor.innerHTML.split('<br>');
const normalized = lines
.map(line => line.trim())
.filter(line => line.length > 0)
.join('<br>');
if (normalized !== editor.innerHTML) {
// Restore BR tags if they were lost
editor.innerHTML = normalized;
}
});
References
- Microsoft Support: contenteditable div loses br tag
- Internet Explorer 11 specific bug with BR tag handling