Markdown to PDF with Custom CSS: Fonts, Margins, and Page Breaks
Custom styling is useful when a plain Markdown export is not enough. A quick PDF may only need headings, lists, and code blocks, but a client report, resume, handbook, or white paper may also need a brand font, page numbers, controlled margins, repeatable page breaks, and tables that print cleanly.
This guide explains how to convert Markdown to PDF with custom CSS. It focuses on the HTML and print-CSS workflow, then shows where VS Code, Pandoc, and the free Markdown to PDF converter fit.
Quick Answer
For a fast export, use the Markdown to PDF converter. It is useful when you want a clean PDF without installing a tool or maintaining a stylesheet.
For full control, use this workflow:
- Write and preview the Markdown.
- Convert the Markdown to HTML.
- Load a print stylesheet.
- Open the HTML in a browser and choose Print > Save as PDF, or use an HTML-based PDF engine.
- Inspect page breaks, links, tables, and code blocks before sharing the file.
The key distinction is simple: an online converter optimizes for speed and consistency; custom CSS optimizes for control and repeatability.
Download a Matching Markdown, HTML, and CSS Example
Start with these original, freely reusable files:
Save the HTML and CSS in the same folder, keeping the names report-print.html and print.css. Open the HTML in your browser and choose Print → Save as PDF. Enable background graphics if you want the shaded table header. The stylesheet requests A4 paper and 20 mm top, 18 mm side, and 22 mm bottom margins; check that your print dialog is not overriding these settings.
The example includes a heading hierarchy, an API parameter table, a request code block, and a review checklist. It uses system fonts and no remote assets, so you can inspect the layout without downloading a font package. These are fictional report contents for trying the workflow.
To start from your own source, use Markdown to HTML, select Full HTML document, and download the result. In the HTML head, replace the generated style block with <link rel="stylesheet" href="print.css">. Keep the CSS file beside the HTML, then print. If you only need standard styling, open the .md file directly in Markdown to PDF.
Which Export Method Supports Your Styling?
| Workflow | Where styling is configured | What to check |
|---|---|---|
| Browser Print | A stylesheet linked from the HTML | Paper size, margins, background graphics, browser headers and footers |
| VS Code Markdown PDF extension | Extension-specific stylesheet setting | Confirm the setting name and path in that extension's documentation |
| Pandoc with an HTML PDF engine | --css=print.css and the selected engine | Install the engine; CSS support varies by engine and version |
| Pandoc with a LaTeX engine | LaTeX template and variables | HTML CSS rules do not apply to the LaTeX output |
| This site's online PDF converter | Title and paper-size controls | Arbitrary CSS, remote fonts, and automatic TOC generation are not supported |
Do not assume an extension and your browser use the same print engine. Keep a small sample document in your repository and recheck it when changing the exporter.
A Practical Print Stylesheet
Start with a small stylesheet instead of overriding every element. The following rules cover the most common PDF requirements:
@page {
size: A4;
margin: 20mm 18mm 22mm;
}
:root {
color-scheme: light;
}
body {
color: #1f2937;
background: #ffffff;
font-family: "Inter", "Segoe UI", Arial, sans-serif;
font-size: 10.5pt;
line-height: 1.55;
}
h1,
h2,
h3 {
color: #111827;
line-height: 1.2;
page-break-after: avoid;
}
h1 {
font-size: 24pt;
margin-bottom: 12pt;
}
h2 {
font-size: 16pt;
margin-top: 20pt;
}
a {
color: inherit;
text-decoration: none;
}
pre,
table,
figure {
page-break-inside: avoid;
}
pre {
overflow-wrap: break-word;
white-space: pre-wrap;
background: #f3f4f6;
padding: 10pt;
border-radius: 4pt;
}
img {
max-width: 100%;
}
The @page rule controls the paper size and printable margins. The heading rules reduce awkward breaks after a section title. The page-break-inside rules help keep small code blocks, tables, and figures together, although browsers may still split very large elements.
Add a Branded Header and Footer
Represent a simple document header in the Markdown-to-HTML template:
<header class="document-header">
<span>Acme Documentation</span>
<span>Engineering Handbook</span>
</header>
Style it separately from the body:
.document-header {
display: flex;
justify-content: space-between;
border-bottom: 1px solid #d1d5db;
color: #6b7280;
font-size: 8.5pt;
margin-bottom: 18pt;
padding-bottom: 6pt;
}
.cover {
min-height: 220mm;
display: flex;
flex-direction: column;
justify-content: center;
page-break-after: always;
}
This approach works well for reports and handbooks. If you need generated page numbers in headers or footers, support varies between browsers and PDF engines. Test the exact engine used in production instead of assuming that a CSS feature will behave identically everywhere.
Control Page Breaks
Use a class when a new major section must start on a new page:
<h2 class="new-page">Release checklist</h2>
.new-page {
break-before: page;
page-break-before: always;
}
.keep-with-next {
break-after: avoid;
page-break-after: avoid;
}
Prefer break-before, break-after, and break-inside in new stylesheets. The older page-break-* names are still useful for browser compatibility. Avoid forcing a page break before every heading because short sections can create mostly empty pages.
Make Markdown Tables Print Well
Markdown tables often look fine in a browser and fail on paper because their text is too wide. Before export:
- Keep comparison tables to a few focused columns.
- Shorten long labels instead of shrinking the entire document.
- Use landscape paper for genuinely wide data.
- Allow long text to wrap inside cells.
- Repeat table headers when the PDF engine supports it.
table {
width: 100%;
border-collapse: collapse;
font-size: 9pt;
}
thead {
display: table-header-group;
}
th,
td {
border: 1px solid #d1d5db;
padding: 5pt 6pt;
text-align: left;
vertical-align: top;
overflow-wrap: anywhere;
}
th {
background: #f3f4f6;
}
tr {
break-inside: avoid;
}
For a quick table cleanup before export, use the Markdown Table Generator or convert source data with the CSV to Markdown Table tool.
Style Code Blocks Without Losing Readability
Code is one of the easiest PDF elements to break. A long line can push the entire document beyond the page width, while an overly small font makes the code unusable.
pre {
font-family: "Cascadia Code", Consolas, monospace;
font-size: 8.5pt;
line-height: 1.4;
white-space: pre-wrap;
overflow-wrap: anywhere;
}
code {
font-family: "Cascadia Code", Consolas, monospace;
}
Wrap only when the output is intended to be read on paper. For API examples or source code where exact line structure matters, use a smaller font, landscape pages, or split the example into shorter blocks instead of wrapping silently.
Use Custom CSS in Common Workflows
Browser Print
Convert the Markdown to HTML, attach the stylesheet, open the result in a Chromium-based browser, and choose Print > Save as PDF. Turn on background graphics if your design uses colored headers or shaded code blocks. Browser print settings can override margins, headers, and footers, so verify the preview.
VS Code
Markdown PDF extensions commonly accept a CSS file or a path configured in the workspace settings. This is convenient when the Markdown source and stylesheet live in the same repository. Keep the stylesheet under version control so teammates and CI exports use the same formatting.
Pandoc with an HTML PDF Engine
Pandoc can use a CSS file when rendering through an HTML-capable engine:
pandoc report.md -o report.pdf --css=print.css --pdf-engine=wkhtmltopdf
Exact flags vary by engine. If the command fails, check that Pandoc and the selected PDF engine are installed and available on your PATH. For academic documents, Pandoc with a LaTeX engine may be a better fit, but CSS rules will not transfer directly to LaTeX output.
Troubleshoot Clipped Tables, Code, and Extra Pages
| Symptom | Likely cause | First adjustment |
|---|---|---|
| Table runs off the page | Long unbroken strings or too many columns | Use overflow-wrap: anywhere, reduce columns, or switch to landscape |
| Code is cut off on the right | A long line with preserved whitespace | Set white-space: pre-wrap on pre and review whether wrapping changes readability |
| A large empty area precedes a table | The entire table is forced to stay together | Allow the table to split; apply break-inside: avoid to rows instead |
| A heading is alone at the bottom | No break constraint after the heading | Add break-after: avoid to headings |
| Colors disappear | Background printing disabled | Enable background graphics in the print dialog |
| Different line wrapping on another machine | The requested font is unavailable | Use a shared installed font or a reliable system-font fallback |
break-inside: avoid is a preference, not a guarantee. A block taller than the printable page must split or overflow. For long reference tables, allow page breaks and repeat the header rather than trying to keep the whole table on one page.
When to Use an Online Converter Instead
Custom CSS is not always the right answer. Use the free Markdown to PDF converter when you need a quick report, README, assignment, or AI response with standard formatting. It avoids local setup and removes the need to maintain an export pipeline.
Use a stylesheet when the same document must be exported repeatedly, the PDF needs brand rules, or page layout is part of the deliverable. For a broader comparison of online, Pandoc, VS Code, and Typora workflows, see How to Convert Markdown to PDF.
PDF QA Checklist
Before distributing a styled Markdown PDF, check:
- The title and first heading are not duplicated.
- No heading is stranded at the bottom of a page.
- Tables fit the selected paper size and repeat headers correctly.
- Code blocks are readable and do not run past the page edge.
- Links have enough contrast and remain usable in the PDF.
- Images are sharp, scaled to the page, and include meaningful alt text in the source.
- Background colors and fonts survive the print settings.
- The document looks acceptable in both portrait and the intended alternate layout.
Custom CSS works best when it stays small and testable. Start with margins, typography, tables, code, and breaks, then add branding only where it improves the document. That produces a more reliable PDF than a large stylesheet full of renderer-specific overrides.