Marginalius
unlistedby wlo2
Renders adaptive marginalia via margin/margin-r callouts.
Marginalius
https://github.com/user-attachments/assets/2e1c1ff8-f7b3-428a-b73a-6a962eb6c38b
An Obsidian plugin for adaptive marginalia — Tufte/Cornell-style side notes that live in the page margins on wide screens and gracefully fall back to compact, embedded note boxes when space is tight.
Write a note once with a simple callout, and Marginalius decides how to present it based on the available width of the editor pane.
Features
- Two adaptive layouts from one syntax:
- Cornell / margin view (wide panes): the note is pulled out of the text column into the side gutter, borderless and muted, like a printed margin note.
- Embedded view (narrow panes): the note becomes a compact, rounded, floated box that sits inline with the text.
- Left and right margins:
[!margin]floats into the left gutter,[!margin-r]into the right. - Responsive width: in the wide view the note width is computed from the actual gutter space, so resizing the pane (or opening a sidebar) shrinks the note to stay flush against the pane edge instead of being clipped. When the gutter gets too small it automatically switches to the embedded view.
- Word-safe wrapping: text in a narrow margin never splits mid-word. Non-breaking spaces in your notes (commonly typed with
Option+Spaceon macOS, or pasted from rich text) are normalized at render time so phrases wrap on real word boundaries — your source file is never modified. - Click-to-edit: clicking a rendered margin note in the editor places the cursor at that note's position in the document.
- Configurable widths and spacing via a settings tab.
- Theme-friendly: uses theme variables (text colors, borders, readable line width) and works in both Reading view and Live Preview.
Usage
Use a callout with the margin (left) or margin-r (right) type:
> [!margin]
> Result: only the mysql-backup pod can assume that role and write to S3;
> other pods cannot. So yes: it's access control and least privilege.
Your main body text goes here. On a wide screen the note above is rendered
in the left margin next to this paragraph.
> [!margin-r]
> This note is pulled into the right-hand margin instead.
- On a wide pane the notes appear in the margins, borderless and muted.
- On a narrow pane the same notes render as compact, rounded boxes floated into the text.
Settings
Settings → Community plugins → Marginalius
| Setting | Description | Default |
|---|---|---|
| Sidenote width | Maximum width of a margin note in the wide (Cornell) view. The note may render narrower if the gutter is smaller than this. | 200px |
| Sidenote margin | Gap between a margin note and the main document text. | 20px |
| Intrusive width | Width of the embedded note box in the narrow (half-embedded) view. | 200px |
These map to the CSS custom properties --marginalius-width, --marginalius-margin, and --marginalius-intrusive-width.
How it works
Marginalius is intentionally small and split into focused modules under src/:
main.ts— plugin lifecycle. Loads settings, injects the dynamic CSS variables from settings, registers the wrap fix, and wires up the click-to-edit handler.settings.ts— settings interface, defaults, and the settings tab.wrap-fix.ts— a markdown post-processor that replaces non-breaking characters (U+00A0,U+202F,U+2007, the word joiner/ZWNBSP, and the non-breaking hyphen) with their breaking equivalents inside margin callouts only, so narrow notes can wrap normally. It runs for both Reading view and Live Preview.styles.css— all presentation:- Strips the default callout chrome (title, icon, border, background) for
margin/margin-r. - Forces word-integrity wrapping (
word-break: normal,overflow-wrap: break-word) across the callout and its descendants, including the CodeMirror internals used in Live Preview. - Defines the narrow / embedded layout as the default.
- Uses a CSS container query on the markdown view (
container-type: inline-size) to switch to the wide / Cornell layout atwidth >= 1000px.
- Strips the default callout chrome (title, icon, border, background) for
Adaptive width math (wide view)
The body is centered at the readable line width (--file-line-width), leaving a gutter on each side. Using container query units, the plugin computes:
gutter = (100cqi - var(--file-line-width)) / 2
fit = max(0, min(configured width, gutter - margin - edge))
fit drives both the note's width and its negative pull-out margin, so the box and its offset always stay in sync. As the pane narrows, fit shrinks; below the breakpoint the note reverts to the embedded layout. Reading view adds a small extra --marginalius-edge of separation because its rendered text sits a little closer to the gutter than the editor's.
Note: the wide view relies on Readable line length being enabled (the default), which is what creates the side gutters.
Development
Requirements: Node.js 18+ and npm.
# install dependencies
npm install
# development build with watch
npm run dev
# production build (type-check + bundle)
npm run build
The build type-checks with tsc and bundles src/main.ts into main.js with esbuild (see esbuild.config.mjs).
Manual install / testing
Copy the release artifacts into your vault's plugin folder, then reload Obsidian and enable the plugin in Settings → Community plugins:
cp main.js manifest.json styles.css "<Vault>/.obsidian/plugins/obsidian-marginalius/"
Required artifacts: main.js, manifest.json, styles.css.
Privacy
Marginalius runs entirely locally. It makes no network requests, collects no telemetry, and never modifies your notes on disk — the non-breaking-space normalization only affects the rendered DOM.
License
MIT
For plugin developers
Search results and similarity scores are powered by semantic analysis of your plugin's README. If your plugin isn't appearing for searches you'd expect, try updating your README to clearly describe your plugin's purpose, features, and use cases.