Safari on iOS does not have caret jump issue
OS: iOS 16+ · Device: Mobile (iPhone/iPad) Any · Browser: Safari 16+ · Keyboard: English (QWERTY)
Open case →Scenario
On Chrome Mobile for Android, typing certain punctuation characters (commas, colons, semicolons, quotes, etc.) in the middle of a word causes the cursor to jump to the end of the word instead of staying at the insertion point.
On Chrome Mobile for Android, typing certain punctuation characters in the middle of a word causes the cursor to unexpectedly jump to the end of the word instead of staying at the insertion point.
This issue occurs when:
, : ; ! ? " ' & +() {} [] \ | = and similar punctuation
Chrome Mobile’s caret positioning algorithm appears to have a bug when:
Use setTimeout before continuing typing:
editor.addEventListener('input', (e) => {
const selection = window.getSelection();
const range = selection.getRangeAt(0);
// Store insertion position
const insertionPoint = {
node: range.startContainer,
offset: range.startOffset
};
setTimeout(() => {
// Try to restore position
const newRange = document.createRange();
newRange.setStart(insertionPoint.node, insertionPoint.offset);
newRange.collapse(true);
selection.removeAllRanges();
selection.addRange(newRange);
}, 0);
});
Use beforeinput event to detect jump:
let lastCaretPosition = null;
editor.addEventListener('beforeinput', (e) => {
const selection = window.getSelection();
if (selection.rangeCount > 0) {
lastCaretPosition = {
node: selection.getRangeAt(0).startContainer,
offset: selection.getRangeAt(0).startOffset
};
}
});
editor.addEventListener('input', (e) => {
const selection = window.getSelection();
if (selection.rangeCount > 0 && lastCaretPosition) {
const currentOffset = selection.getRangeAt(0).startOffset;
const distance = Math.abs(currentOffset - lastCaretPosition.offset);
// If cursor jumped significantly
if (distance > 2) {
console.warn('Cursor jump detected');
// Restore position
const range = document.createRange();
range.setStart(lastCaretPosition.node, lastCaretPosition.offset);
range.collapse(true);
selection.removeAllRanges();
selection.addRange(range);
}
}
});
User education: Add UI hint that these characters may cause issues on mobile Chrome
Use desktop browser: Recommend users use desktop browsers for editing when possible
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-0269-caret-jump-chrome-mobile-ios-en | iOS 16+ | Mobile (iPhone/iPad) Any | Safari 16+ | English (QWERTY) | confirmed |
| ce-0270-caret-jump-chrome-mobile-firefox-en | Windows 10/11 | Desktop Any | Firefox 120+ | English (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 | Windows | iOS |
|---|---|---|
| Firefox | — | |
| Safari | — |
Open a case to see the detailed description and its dedicated playground.
OS: iOS 16+ · Device: Mobile (iPhone/iPad) Any · Browser: Safari 16+ · Keyboard: English (QWERTY)
Open case →OS: Windows 10/11 · Device: Desktop Any · Browser: Firefox 120+ · Keyboard: English (QWERTY)
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.
When deleting the last character before a non-editable "pill" or tag element (contenteditable="false") in a contenteditable div in Chrome, the caret (cursor) jumps to the end of the entire contenteditable div instead of staying adjacent to the remaining content.
When the browser is zoomed (or content is scaled via CSS transforms), caret position and text selection in contenteditable elements can become inaccurate. Clicking at a certain position places the caret elsewhere, and selection highlights may not match the visual selection.
When contenteditable='false' elements are placed inside a contenteditable container, the cursor may disappear or become invisible in certain browsers, making it difficult for users to determine the text insertion point.
When a contenteditable element or its parent has the CSS contain property, selection behavior may be affected. Selection may not extend beyond the contained element, and caret movement may be restricted.
Have questions, suggestions, or want to share your experience? Join the discussion below.