Originally published on Medium.
Word processors have had a horizontal ruler for forty years. You grab a marker, drag,
and the paragraph's margins move. Every writer knows it without being taught.
Open Froala, TinyMCE, CKEditor 5, or Quill and it isn't there. Not hidden in a menu —
it doesn't exist. The CKEditor 5 feature request
has been open since September 2020.
The editors that do ship a ruler — Syncfusion, ONLYOFFICE, DevExpress — are heavyweight
document processors with their own document models. They can draw a ruler because they
own the concept of a page. HTML doesn't have pages, and that is where most attempts stop.
What a ruler can actually mean in HTML
The trick is to stop asking for a page and ask what the ruler edits. Three CSS
properties, and nothing else:
| Ruler control | CSS |
|---|---|
| Left margin | margin-left |
| Right margin | margin-right |
| First-line indent | text-indent |
That mapping is 1:1 and it is why the output travels. You get plain inline CSS:
<p style="margin-left: 75px; text-indent: 38px">…</p>
Paste that into an email, a CMS, another page — the layout holds, because there is no
private document model to leave behind.
Tab stops are deliberately out of scope. HTML has no tab-stop model. A ruler that
pretends otherwise produces documents that break the moment they leave the editor.
editor-ruler
An editor-agnostic core plus thin per-editor adapters. Apache-2.0.
npm install @devslab/editor-ruler # core, any contenteditable
npm install @devslab/editor-ruler-froala # Froala plugin
npm install @devslab/editor-ruler-tiptap # Tiptap v2/v3 extension
npm install @devslab/editor-ruler-ckeditor5 # CKEditor 5 plugin
The core has zero dependencies and also ships an iife build, so a plain <script> tag
works with no bundler.
What you get on every adapter:
- Left/right margin and first-line indent handles, hanging indent included
- A vertical ruler
- Guide lines with snapping — drag one out of the ruler, Photoshop-style. They are a visual overlay and never appear in the exported HTML
- cm / inch / px, switchable at runtime
- One undo step per drag gesture, not one per pixel
- Handles are ARIA sliders, so the whole thing is keyboard-operable
- UI language follows the browser (ko/en built in)
Whole-table indent and column-width markers are Froala-only for now; on Tiptap and
CKEditor 5 you get everything else.
Three gotchas worth knowing
CSS ignores margins on table cells. Setting margin-left on a <td> does nothing,
silently. The ruler has to notice the selection is inside a table and climb to the
<table> itself — which is also what Word does.
Tiptap's Image extension drops content without telling you. data: URIs need
allowBase64: true, and <img> inside <p> needs inline: true. Nothing throws;
the nodes just vanish on parse.
Froala toolbar buttons ignore synthetic click(). They respond to a
mousedown/mouseup sequence. Worth knowing before you write the automated test.
Since this was published
The library reached 1.0 — the documented API is under semver now. Also added:
- The vertical ruler now works on all three adapters, not just Froala
-
verticalGutterreserves the strip's column up front, so toggling the vertical ruler never reflows your content -
visible: falsestarts the ruler hidden, with commands to bring it up - The landing page serves English to non-Korean browsers
Two of those came from a user reporting real problems — the strip sizing itself to the
wrong element, and the content shifting when the vertical ruler appeared.
Try it
- Live demo (tabs for Froala, Tiptap, CKEditor 5, and the bare core): https://devslab-kr.github.io/editor-ruler/
- GitHub: https://github.com/devslab-kr/editor-ruler
- One-click StackBlitz sandboxes for each adapter are linked from the demo
If the editor you use isn't covered, an adapter only has to do three things: read the
selected blocks, write styles, and hook into undo. Open an issue.
Top comments (0)