Engineering Journal
Pdf Processor
Pdf Processor

Hot Take: You Don't Need a Canvas to Build a Document CAD Editor

2026-05-21

TLDR: The entire industry reaches for a canvas layer the moment they need to let users rearrange content. It's almost always the wrong choice for documents.


The reflex

Someone wants to let users drag blocks of content around. The reflex is immediate: add a canvas overlay, track absolute coordinates, write a hit-test loop, manage a coordinate system, decide what "snapping" means in absolute space.

Fabric.js. Konva. A raw <canvas>. An absolutely positioned div layer on top of everything. Hundreds of lines of coordinate math.

This works fine for a drawing tool. It's wrong for a document editor.


What a document already is

A browser rendering engine is a layout engine. It calculates every element's position, size, and relationship to every other element. For free. Every time the DOM changes.

A CSS Grid zone is a container with spatial relationships built in. You rearrange its children and the browser reflows. You don't compute anything. You call insertBefore.

getBoundingClientRect() gives you every element's position in viewport space at any time. dragover gives you cursor position. The math for "which half of the element did the cursor land in" is four lines.

The browser is already doing the CAD work. You just have to not fight it.


What absolute positioning costs you

The moment you lift elements into position: absolute, they fall out of document flow. They no longer affect other elements. They don't respond to container resizes. They don't export to Markdown as paragraphs — they export as positioned artifacts or not at all.

For a document, this is catastrophic. The whole point of the tool is that you export what you see. An absolutely-positioned paragraph that looks right on screen is meaningless in a Markdown file.

The "CAD" in this system means: layout editing with the document as the source of truth. Not a separate spatial model. The DOM is the model.


The part the industry gets wrong about drag-and-drop

Most drag-and-drop tutorial code does this:

el.style.position = 'absolute';
el.style.left = e.clientX + 'px';
el.style.top = e.clientY + 'px';

That's drag-to-position. It's different from drag-to-reorder.

Drag-to-reorder is: the user expresses intent about order or adjacency. The layout system figures out the position. You never track coordinates for the dragged element. You only track where in the DOM it should land relative to its siblings.

The drop indicator is a 2px line between siblings. The drag handler is insertBefore. The browser handles the rest.


The right tool for the right model

Canvas layers are correct for:

Flow-based drag-and-drop is correct for: We're building a document editor. The content is structured HTML. The export formats are Markdown, XML, DOC. Position:absolute has no representation in any of those formats.

The browser's flow model is the only model that can produce correct output in all three.


One concrete rule

If your drag-and-drop produces output that someone will read or process downstream, don't use position: absolute for content elements. Use DOM order. Use insertBefore. Use the browser.

Reserve absolute positioning for UI chrome: handles, indicators, tooltips, dividers. Not content.

That's the line that separates a CAD editor that works from one that looks good but exports garbage.

Read this post in the full Engineering Journal →