Comparison

Obsidian to PDF: Export, Custom CSS and the Alternatives

Published July 30, 2026

Obsidian is a very good place to write and an adequate place to export from. Its built-in PDF export handles a straightforward note well and runs into predictable limits as soon as you want control over layout — which, for anything you send to someone else, you usually do.

This guide covers what the built-in export actually does, how far custom CSS gets you, the plugin landscape, and when the honest answer is to export the Markdown and convert it elsewhere.

The built-in export

Ctrl/Cmd+PExport to PDF, or right-click a note in the file explorer. Obsidian is an Electron application, so this is Chromium’s print pipeline rendering the note’s preview mode.

The dialog gives you:

  • Page size (A4, Letter, Legal, Tabloid, and a few others)
  • Margin presets (none, small, default, large)
  • Landscape toggle
  • A downscale percentage
  • “Include filename as title”
  • “Open after export”

That is the full extent of the controls. Notably absent: page numbers, headers or footers, custom margins in real units, a table of contents, and any control over page breaks.

What it does well

It renders your active theme and CSS snippets, so a note with callouts, Dataview tables (already rendered), Mermaid diagrams and LaTeX math exports looking essentially as it does on screen. Internal links become clickable PDF links when the target is in the same export. Vector graphics stay vector.

For a note you want to hand someone as-is, it is fine and takes two clicks.

Where it falls short

No page numbers, headers or footers. Because Chromium does not implement @page margin boxes — the underlying reason, explained in the headers and footers guide. No amount of CSS will add them in Obsidian’s export. This is the single most-requested missing feature and it is not fixable from your side.

Margins are presets, not measurements. “Default” is roughly 1 inch. If your requirement is 25mm, you cannot express it in the dialog — though CSS can override it, see below.

No control over page breaks from the dialog. CSS can supply this.

One note at a time. No batch export, no folder export, no combining several notes into one document. This is where plugins come in.

The downscale slider is a blunt instrument. It shrinks everything, including text, to fit more per page. Reducing your CSS font size gives a better result.

Custom CSS for print

This is the highest-value thing you can do, and it is under-documented: Obsidian’s PDF export respects @media print rules in CSS snippets. You get real print CSS control despite the minimal dialog.

Enable snippets in Settings → Appearance → CSS snippets, then create a file in YourVault/.obsidian/snippets/print.css. Click the reload icon in that settings pane after editing, and toggle the snippet on.

@media print {
  /* Real margin control, overriding the dialog presets. */
  @page {
    size: A4;
    margin: 22mm 20mm;
  }

  /* Obsidian's preview container. */
  .markdown-preview-view {
    font-family: "Source Serif 4", Georgia, serif;
    font-size: 11pt;
    line-height: 1.55;
    color: #111;
    padding: 0 !important;
  }

  /* Headings: keep with following content. */
  .markdown-preview-view h1,
  .markdown-preview-view h2,
  .markdown-preview-view h3,
  .markdown-preview-view h4 {
    break-after: avoid;
    page-break-after: avoid;
    break-inside: avoid;
    color: #000;
  }

  .markdown-preview-view h1 { font-size: 21pt; }
  .markdown-preview-view h2 { font-size: 16pt; }
  .markdown-preview-view h3 { font-size: 13pt; }

  /* Keep blocks intact. */
  .markdown-preview-view pre,
  .markdown-preview-view table,
  .markdown-preview-view blockquote,
  .markdown-preview-view .callout {
    break-inside: avoid;
    page-break-inside: avoid;
  }

  /* Code that wraps rather than clipping. */
  .markdown-preview-view pre {
    white-space: pre-wrap;
    word-wrap: break-word;
    font-size: 9pt;
    background: #f7f7f9 !important;
    border: 0.75pt solid #e4e4e7;
    print-color-adjust: exact;
    -webkit-print-color-adjust: exact;
  }

  /* Repeat table headers across pages. */
  .markdown-preview-view thead {
    display: table-header-group;
  }

  .markdown-preview-view table {
    width: 100%;
    border-collapse: collapse;
    font-size: 9.5pt;
  }

  .markdown-preview-view th,
  .markdown-preview-view td {
    border: 0.5pt solid #ccc;
    padding: 4pt 6pt;
  }

  /* Manual page breaks, triggered from a note. */
  .page-break {
    break-after: page;
    page-break-after: always;
    height: 0;
  }

  /* Hide UI that has no business in a document. */
  .markdown-preview-view .frontmatter,
  .markdown-preview-view .frontmatter-container,
  .markdown-preview-view .metadata-container,
  .markdown-preview-view .collapse-indicator,
  .markdown-preview-view .heading-collapse-indicator,
  .markdown-embed-title,
  .internal-link .external-link-icon {
    display: none !important;
  }

  /* Orphans and widows. */
  .markdown-preview-view p,
  .markdown-preview-view li {
    orphans: 3;
    widows: 3;
  }
}

Several things worth flagging in that snippet.

.markdown-preview-view is the selector you need. Styling body does very little because Obsidian’s content lives nested inside its own container. Most CSS that “does not work” in Obsidian export is targeting the wrong element.

!important is often necessary. Obsidian’s theme CSS is specific and loaded after snippets. Fighting it with specificity is possible but tedious; !important on the properties you need is pragmatic.

Hiding the metadata container matters if your notes have YAML frontmatter. By default Obsidian renders the properties block in preview, and it exports — a table of tags and dates at the top of your document. .metadata-container is the modern selector; .frontmatter covers older versions.

Page breaks need a hook in the note. With the .page-break rule above, insert this in your Markdown wherever you want a break:

<div class="page-break"></div>

That single addition covers the most-missed capability of the built-in export.

You can include content that appears in the PDF but not on screen, which is how you fake a title block:

.markdown-preview-view .print-only { display: none; }

@media print {
  .markdown-preview-view .print-only { display: block; }
  .markdown-preview-view .screen-only { display: none; }
}
<div class="print-only">
  <p style="text-align:center; font-size:9pt; color:#666;">
    Acme Corporation — Internal — Exported March 2026
  </p>
</div>

It appears once at the top of the document, not on every page — margin boxes remain unavailable — but for a classification line or a footer on a short document it is often enough.

Obsidian’s most distinctive features are also the ones that translate least cleanly.

[[Another Note]] renders as a link. On export:

  • If the target note is not part of the export, the link becomes dead text. Obsidian has no external URL to point at.
  • If you export a note whose value lies in its outbound links — a hub or map-of-content note — the PDF loses most of its meaning.

There is no clean fix. Options: convert important wikilinks to real content before exporting, use a plugin that inlines linked notes, or accept that hub notes do not export usefully.

Embeds

![[Another Note]] embeds the target’s content inline, and this does export — the embedded content appears in the PDF. That makes embeds the mechanism for assembling a multi-note document:

# Complete Project Handbook

![[01 - Introduction]]

<div class="page-break"></div>

![[02 - Architecture]]

<div class="page-break"></div>

![[03 - Deployment Runbook]]

Export that single note and you get a combined document. This is the most useful trick in this guide and it needs no plugins.

Two caveats. Embedded notes render inside a .markdown-embed wrapper that Obsidian styles with a border and a title — usually not what you want in a document:

@media print {
  .markdown-embed {
    border: none !important;
    padding: 0 !important;
    margin: 0 !important;
    background: none !important;
  }
  .markdown-embed-title { display: none !important; }
  .markdown-embed-link  { display: none !important; }
}

And embedded headings keep their original levels, so an embedded note starting at h1 produces multiple h1s in your combined document. Either write the source notes with h2 as their top level, or demote them in CSS (which changes appearance but not document structure).

Block references

![[Note#^blockid]] embeds a specific block. It exports like any embed. [[Note#^blockid]] as a plain link does not.

Attachments and images

Images stored in the vault export correctly — Obsidian resolves the local path. Two things break:

Images referenced by remote URL are subject to the loading-race problem described in the images guide. Usually fine in Obsidian since export is user-triggered after render, but slow-loading remote images can be missed.

PDF embeds (![[document.pdf]]) do not export. Obsidian renders these with an embedded viewer, which has no print representation. You get a blank space.

Plugin-rendered content

This is the significant one for heavy plugin users:

ContentExports?
Mermaid diagramsYes — rendered SVG
LaTeX mathYes — rendered by MathJax
CalloutsYes, with theme styling
Dataview queriesYes — the rendered result exports, not the query
Excalidraw drawingsYes if embedded as an image; the .excalidraw file itself does not
Kanban boardsPoorly — the board UI is not a document
Canvas filesNo — Canvas is not Markdown and has no print view
Tasks plugin queriesYes — rendered result
Charts pluginUsually yes if it renders to SVG; canvas-based charts may be blank

The general rule: anything that renders to HTML or SVG in preview mode exports. Anything that renders to an interactive widget or a <canvas> element may not. Test before relying on it.

Plugin options

The built-in export’s limits are what the plugin ecosystem addresses.

Better Export PDF is the most direct upgrade. It adds page numbers, headers and footers, a table of contents, custom margins in real units, and batch export of multiple notes. It works by running its own rendering pass rather than relying on Chromium’s print pipeline, which is how it manages headers and footers. If the built-in export is nearly enough and you need page numbers, this is the shortest path.

Pandoc Plugin hands off to a local Pandoc installation, giving you the full Pandoc feature set — citations via --citeproc, DOCX and EPUB output, LaTeX templates — from inside Obsidian. It requires Pandoc installed separately. This is the right choice for academic work in a vault; see the academic writing guide for the citation workflow.

Longform is for book-length projects. It manages scene and chapter ordering across many notes and compiles them into a single manuscript, with a compile step that can output Markdown for further processing. It solves organisation rather than export.

Enhancing Export offers similar territory to Better Export PDF with different defaults.

Webpage HTML Export exports to standalone HTML rather than PDF, which is useful as an intermediate step — export clean HTML, then convert it with a tool that gives you full print CSS control.

A caution that applies to all of them: export plugins are a category with high churn. Plugins are abandoned, break on Obsidian API changes, and get replaced. Check the last release date before building a workflow on one.

Exporting outside Obsidian

Your notes are plain Markdown files on disk. Nothing stops you converting them with any other tool, and for documents where layout matters this is often the better route.

Where the vault lives

The .md files are in your vault directory in their original folder structure. Attachments are wherever your attachment settings put them — commonly an attachments/ or assets/ folder.

Obsidian’s [[wikilink]] syntax is not standard Markdown, and other tools will not understand it. Two solutions:

Change the setting. Settings → Files & Links → Use [[Wikilinks]] — turn it off, and Obsidian writes standard [text](path) links going forward. Existing links are unaffected.

Convert on the way out. For Pandoc, a Lua filter or a preprocessing pass:

# Convert [[Note Name]] to [Note Name](Note Name.md)
perl -pe 's/\[\[([^\]|]+)\]\]/[$1]($1.md)/g' note.md > note.converted.md

# Handle the aliased form [[Note Name|display text]]
perl -pe 's/\[\[([^\]|]+)\|([^\]]+)\]\]/[$2]($1.md)/g' note.md > note.converted.md

Run the aliased form first, since the simpler pattern would otherwise match it wrongly.

Frontmatter

Obsidian notes usually carry YAML frontmatter. Pandoc reads it as metadata, which is often useful — a title: field becomes the document title. Other tools may render it as literal text at the top of the document. Strip it if needed:

sed '1{/^---$/!q;};1,/^---$/d' note.md > note.stripped.md

That deletes everything up to and including the second ---, but only if the file starts with ---.

Pandoc from a vault

cd ~/Documents/MyVault

pandoc "Projects/Migration Plan.md" \
  --resource-path=.:attachments \
  --pdf-engine=xelatex \
  -V geometry:margin=25mm \
  -o migration-plan.pdf

--resource-path is what makes attachment images resolve — without it, relative image paths fail because Pandoc looks relative to the Markdown file rather than the vault root.

A browser-based converter

For a single note where you want visual control over the layout, copying the Markdown into a browser converter with a paginated preview is often faster than configuring anything. You get real-time feedback on where page breaks land, which Obsidian’s export does not offer at all — you export, look at the PDF, adjust, export again.

Which route to pick

NeedRoute
Quick share of a single noteBuilt-in export
Page numbers, headers, footersBetter Export PDF plugin
Combine several notesEmbeds (![[Note]]) in a parent note
Citations and bibliographyPandoc plugin, or Pandoc directly
Book-length manuscriptLongform plugin, then Pandoc
Precise layout controlExport the Markdown, convert elsewhere
Batch conversion of a folderPandoc in a shell loop, or Better Export PDF
Resume or client-facing documentConvert elsewhere with your own CSS

The pattern worth noticing: Obsidian is for writing; export precision usually happens elsewhere. That is not a criticism of Obsidian — it is a note-taking application with export as a secondary feature, and the plugin ecosystem plus plain-text storage means you are never locked in.

Try it yourself

For notes where the layout matters — anything client-facing — the editor here gives you a paginated live preview, so you see where breaks fall as you edit rather than after exporting. Paste a note in, or open the Obsidian to PDF page for the tool with an example loaded.

Related: exporting notes from other apps if you use more than one, print CSS for the layout details, and the Pandoc comparison.

About this guide

Written and maintained by the developer of MarkdownToFile — the browser-based converter this site runs on. Techniques described here are tested against the engines named in the text (Chromium's print pipeline, Paged.js, WeasyPrint), and engine limitations are stated rather than glossed over. Corrections are welcome via the contact page; more about the project on the about page.

Try it yourself — free, no signup

Convert your Markdown to a polished PDF right in your browser.

Open the editor