How to Convert Markdown to PDF with Custom Styling

Make your markdown PDFs look professional. Browser print, Pandoc, Puppeteer, and CSS techniques for styled output.

· · 6 min read

Last updated: March 1, 2026

pdf styling markdown conversion

The default PDF output from most markdown converters looks like a 1998 web page. No custom fonts, no spacing control, no color. You can do better. There are four practical approaches to styled markdown-to-PDF conversion, each with different tradeoffs between setup effort and output quality.

1. Browser Print-to-PDF

This is the simplest method and what the MDtoLink PDF tool uses under the hood. Convert markdown to HTML, apply a CSS stylesheet, open in a browser, and print to PDF.

The key is the @media print CSS block. This lets you define styles that only apply when printing.

@media print {
body {
font-family: "Inter", sans-serif;
font-size: 11pt;
line-height: 1.5;
color: #1a1a1a;
max-width: 100%;
}
nav, footer, .no-print {
display: none;
}
a {
color: #1a1a1a;
text-decoration: underline;
}
h1 { font-size: 20pt; margin-top: 0; }
h2 { font-size: 15pt; page-break-after: avoid; }
pre {
background: #f5f5f5;
padding: 12px;
font-size: 9pt;
white-space: pre-wrap;
page-break-inside: avoid;
}
@page {
margin: 1in 0.75in;
}
}

To use this with a local markdown file, convert to HTML first (using marked, markdown-it, or any parser), inject your CSS, and open the result in Chrome. Then Cmd+P or Ctrl+P to print.

Pros: Zero dependencies beyond a browser. Full CSS control. Works with any HTML output.

Cons: Manual process unless you script it. Print rendering varies slightly between browsers.

2. Pandoc with LaTeX

Pandoc converts between dozens of document formats. For PDF output, it pipes through a LaTeX engine, which produces typographically polished results.

Terminal window
# Install (macOS)
brew install pandoc basictex
# Convert with a custom template
pandoc resume.md \
-o resume.pdf \
--pdf-engine=xelatex \
-V geometry:margin=1in \
-V fontsize=11pt \
-V mainfont="Inter" \
-V monofont="JetBrains Mono"

For more control, create a LaTeX template and pass it with --template=custom.tex. Pandoc’s template syntax lets you inject variables and conditionals.

Pros: Highest typographic quality. Fine-grained control over page layout. Handles footnotes, citations, and cross-references natively.

Cons: LaTeX installation is heavy (BasicTeX is ~100MB, full TeX Live is 4GB+). Debugging LaTeX errors is painful. The learning curve is steep if you haven’t used LaTeX before.

3. Puppeteer or Playwright

If you need PDF generation in a CI/CD pipeline or as part of an automated workflow, headless browser libraries give you programmatic control.

import puppeteer from "puppeteer";
import { marked } from "marked";
import { readFileSync, writeFileSync } from "node:fs";
const markdown = readFileSync("document.md", "utf-8");
const html = `
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: Inter, sans-serif; font-size: 11pt; line-height: 1.6; padding: 0 40px; }
h1 { font-size: 22pt; border-bottom: 2px solid #333; padding-bottom: 4px; }
code { background: #f0f0f0; padding: 2px 5px; border-radius: 3px; font-size: 9pt; }
pre code { display: block; padding: 12px; }
</style>
</head>
<body>${marked(markdown)}</body>
</html>`;
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setContent(html, { waitUntil: "networkidle0" });
await page.pdf({
path: "document.pdf",
format: "A4",
margin: { top: "1in", bottom: "1in", left: "0.75in", right: "0.75in" },
printBackground: true,
});
await browser.close();

You can run this in a GitHub Action to auto-generate PDFs on every commit.

Pros: Fully programmable. Same rendering as Chrome. Easy to integrate into CI/CD. Batch processing is straightforward.

Cons: Requires Node.js and a Chromium download (~200MB). Slower than Pandoc for single files. More code to maintain.

If you already publish your markdown with MDtoLink, you get styled PDF output for free. Publish the file, open the URL, and print.

Terminal window
# Publish your document
mdtolink document.md
# Open the URL in your browser, then Cmd+P / Ctrl+P

MDtoLink renders your markdown with clean typography, proper code highlighting, and responsive layout. The print stylesheet is already built in, so the PDF output looks good without any CSS work on your part.

Pros: Zero setup. Styling is handled for you. The URL doubles as a shareable link.

Cons: Requires an MDtoLink account. Less customization than rolling your own CSS.

CSS Tips for Print Stylesheets

Regardless of which method you use, these CSS properties matter most for print output.

Page Margins

@page {
margin: 1in 0.75in;
size: letter; /* or A4 */
}

Controlling Page Breaks

h2, h3 {
page-break-after: avoid; /* Don't break right after a heading */
}
pre, blockquote, table {
page-break-inside: avoid; /* Keep code blocks on one page */
}
.section {
page-break-before: always; /* Force a new page */
}

Hiding Screen-Only Elements

@media print {
nav, .sidebar, .toolbar, footer {
display: none;
}
}

Font Sizing

Screen fonts are sized in px or rem. Print fonts should use pt. A good baseline: 11pt body text, 9pt code, 15-20pt headings.

Readers can’t click links on paper. Show the URL after the link text:

@media print {
a[href^="http"]::after {
content: " (" attr(href) ")";
font-size: 8pt;
color: #666;
}
}

Which Method Should You Pick?

One-off documents: Browser print or MDtoLink. Minimal setup, good enough output.

Automated pipelines: Puppeteer or Playwright. Script it once, run it in CI forever.

Academic or typographic work: Pandoc with LaTeX. Nothing else matches its output quality for long-form documents.

Quick sharing with colleagues: MDtoLink. Publish the markdown, send the URL. If they need a PDF, they can print it themselves.

Try the Markdown to PDF tool to convert a file right now, no install required.


David Schemm
David Schemm

Founder, MDtoLink

David builds developer tools and writes about markdown workflows, documentation, and AI-assisted publishing.

Publish your markdown to a shareable URL

One command. Free to start. No credit card.