Canvas hands you pixels, not an editor.
David Bushell’s excellent rainy-day experiment starts where many custom editors start: draw text and a cursor on <canvas>, wire pointer placement and arrow keys, then enjoy the glow. The demo quickly exposes the invoice. Canvas does not hand over text selection, undo and redo, multiline paste, overflow scrolling, or an accessible text surface.
That is the useful part of the story. The visible editor was never the expensive system. The invisible behavior is the product. A convincing cursor is paint; reliable composition, selection, history, focus, and assistive-technology semantics are the chassis.
Move down one layer before building ten.
Bushell’s next experiments recover browser machinery instead of reimplementing it. A contenteditable="plaintext-only" element restores native editing behavior while dropping rich-text formatting on paste. MDN documents that value explicitly, along with keyboard focus behavior and the fact that contenteditable is enumerated—not a Boolean attribute.
For longer text in Bushell’s unoptimized demo, a plain <textarea> performed better. Syntax paint needed another visible layer, but the text control kept responsibility for input. That is a sane trade: decorate the mechanism without replacing it. If files outgrow that architecture, reach for an editor engine or virtualization before reaching for raw pixels.
Choose the lowest custom layer that can express the interaction you actually need. Every layer below it becomes your maintenance shift.
“Native” does not mean visually dead.
Ambient CSS attacks a different species of slop: unrelated shadow-sm and shadow-lg values pretending to share a scene. Its repository describes a shared light vector that drives five shadow and edge layers across surfaces, calibrated against Blender references. Mechanism and paint remain separate: controls own values and ARIA; parts own appearance.
That separation is the move. A textarea can sit inside a cinematic cockpit. A radio group can feel like a transmission. The visual system can have light, material, depth, and motion without lying about what receives focus or edits text. Pimp the shell. Keep the seatbelts.
The garage rule for custom editors.
- Write the missing interaction in one sentence. If “make it look unique” is the answer, do not replace the input engine.
- Inventory what the browser currently owns: selection, history, paste, scrolling, focus, composition, spelling policy, mobile keyboard, and accessibility.
- Prototype with hostile text: emoji grapheme clusters, combining marks, RTL, very long lines, large files, and IME composition.
- Keep a native seam. Prefer textarea or plaintext-only contenteditable beneath custom paint; graduate only when measured limits demand it.
- Test the boring behavior first. A beautiful caret is not a receipt.