The native browser cursor in a <textarea> is always the height of the line-height CSS property, not the font-size. This creates a visual mismatch when line-height is larger than font-size (e.g., line-height: 1.75 makes the cursor ~75% taller than the text).
- Font size: 16px (var(--editor-font-size))
- Line height: 1.75 = 28px (var(--editor-line-height))
- Cursor height: 28px (cannot be changed)
- Desired cursor height: ~16px (font-size)
CSS provides no property to control cursor height in a textarea. The browser automatically sets cursor height equal to line-height. This is intentional browser behavior and cannot be overridden.
- Only controls cursor color, not height
- Cannot affect cursor dimensions
- No
caret-height,cursor-height, or similar exists line-heightaffects both text spacing AND cursor height
- Setting
line-height: 1makes cursor = font-size - Problem: Reduces text readability, lines too cramped
- Not recommended for a document editor
- Create a
<div>positioned where cursor should be - Style it to be exactly
font-sizeheight - Hide native cursor with
caret-color: transparent - Advantages:
- Exact control over cursor height
- Can match font-size perfectly
- Can customize appearance (color, width, animation)
- Disadvantages:
- Requires JavaScript to calculate position
- Must update on every cursor movement
- Can feel "janky" if not implemented carefully
We're using the native browser cursor with line-height: 1.75, which means:
- ✅ Zero JavaScript overhead
- ✅ Perfect cursor positioning (browser handles it)
- ✅ Native accessibility (screen readers, etc.)
- ❌ Cursor is 28px tall instead of 16px
- ❌ Visual mismatch between cursor and text height
Status: Implemented
- Easiest solution
- Zero performance cost
- Standard browser behavior
- Users are familiar with this from other web apps
Status: Not implemented (was removed earlier due to jank)
- Would require:
- Calculate cursor position from
selectionStart - Create overlay div at that position
- Set height to
font-size(16px) - Update on keypress, mouse click, arrow keys
- Implement blinking animation
- Hide when textarea loses focus
- Calculate cursor position from
Implementation considerations:
- Use
requestAnimationFramefor smooth updates - Debounce rapid movements
- Cache measurements to avoid layout thrashing
- Use CSS
transformfor positioning (GPU-accelerated)
Status: Not recommended
- Would make lines too cramped
- Reduces readability
- Not suitable for a document editor
Created comprehensive test suite in /e2e/wysiwyg-cursor-height.spec.ts:
- ✅ Verifies cursor is visible
- ✅ Confirms font-size vs line-height measurements
- ✅ Takes screenshots for visual regression testing
- ❌ Cannot actually measure cursor height (browser limitation)
The cursor height issue is a browser limitation, not a bug.
To fix it properly, we need to implement a custom cursor overlay (Option 2). This was previously attempted but removed due to performance concerns. If cursor height is a priority, we should re-implement the custom cursor with better performance optimization (see implementation considerations above).
Otherwise, we accept the native browser behavior where cursor = line-height.