Caret becomes invisible in dark mode
OS: Any Any · Device: Desktop or Laptop Any · Browser: Chrome Latest · Keyboard: US
Open case →Scenario
When browser dark mode is enabled, contenteditable elements may experience invisible or poorly visible caret, inline style injection conflicts, background color issues, and form control styling problems. These issues are caused by missing color-scheme declarations and conflicts between browser-injected styles and custom CSS.
When browser dark mode is enabled, contenteditable elements may experience invisible or poorly visible caret, inline style injection conflicts, background color issues, and form control styling problems.
currentColor or text color, making it invisible against dark backgroundscolor-scheme declaration causes problemsDeclare support for both light and dark:
:root {
color-scheme: light dark;
}
Ensure caret is visible:
[contenteditable="true"] {
caret-color: var(--caret-color, white);
}
@media (prefers-color-scheme: dark) {
[contenteditable="true"] {
caret-color: #ffffff;
}
}
Avoid position: relative on inline spans:
[contenteditable="true"] span {
position: static;
/* or */
display: inline-block;
z-index: 0;
}
Sanitize pasted content:
function sanitizeContent(html) {
const div = document.createElement('div');
div.innerHTML = html;
// Remove inline styles
div.querySelectorAll('[style]').forEach(el => {
el.removeAttribute('style');
});
return div.innerHTML;
}
Define dark mode colors:
@media (prefers-color-scheme: dark) {
[contenteditable="true"] {
background-color: #1a1a1a;
color: #ffffff;
}
[contenteditable="true"]::placeholder {
color: #888888;
}
[contenteditable="true"] a {
color: #4a9eff;
}
[contenteditable="true"] a:visited {
color: #9d4edd;
}
}
Simulate browser flags:
/* Fallback for forced dark mode */
@media (prefers-color-scheme: dark) {
[contenteditable="true"] {
filter: none; /* Prevent color inversion */
}
}
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-0564-browser-dark-mode-caret-invisible | Any Any | Desktop or Laptop Any | Chrome Latest | US | draft |
Open a case to see the detailed description and its dedicated playground.
OS: Any Any · Device: Desktop or Laptop Any · Browser: Chrome Latest · Keyboard: US
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.
Changing background color (highlighting) in contenteditable elements behaves inconsistently across browsers. Background colors may be applied as inline styles, may not persist when typing, or may interfere with text selection. The behavior differs from text color changes.
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.
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.
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.
Have questions, suggestions, or want to share your experience? Join the discussion below.