May 24, 2026 · Developer Guide

Styling PDFs with Markdown: Layouts and CSS for E-Signatures (2026)

How to use markdown and custom CSS classes to generate beautiful, professional PDFs via API. Managing page breaks, margins, and headers.

Michael Beckett
Michael Beckett

Founder, Signbee

TL;DR

Generating professional PDFs from Markdown requires a mix of markup structure, custom CSS, and API options. By injecting custom CSS into the Signbee /v1/generate API, you can control document styling, handle page-break rules (like page-break-inside: avoid), and configure margins, headers, and footers. Read on to see payload examples, print-specific CSS patterns, and a full integration script.

Why Markdown alone isn't enough for PDFs

Markdown is the perfect format for writing digital agreements, NDAs, and proposals. It is human-readable, version-control friendly, and lightweight. However, markdown was built for the continuous scroll of web browsers. It has no concept of page dimensions, margin limits, headers, footers, or page-break boundaries.

When you convert raw markdown to a PDF using a typical API, you often end up with awkward results: headings stranded at the bottom of a page, text overlapping with headers, or a signature block split across a page crease. To turn markdown into a client-ready contract, you need to combine the simplicity of markdown with custom CSS layout rules and precise API controls.

The Signbee generate API payload

The Signbee /v1/generate endpoint allows you to send markdown, inject custom CSS, and set page layout options in a single API call. This separation of concerns lets your application logic focus on generating content while keeping style and document rules clean.

Here is what a typical payload looks like when configuring page sizes, custom margins, and headers/footers with dynamic page numbering:

Signbee /v1/generate API Request Payload
{
  "markdown": "# Service Agreement\n\nThis agreement is made between...",
  "css": "body { font-family: 'Helvetica', sans-serif; color: #111; }\nh1 { font-size: 24pt; }\n.signature-block { page-break-inside: avoid; }",
  "options": {
    "format": "Letter",
    "margin": {
      "top": "20mm",
      "bottom": "20mm",
      "left": "15mm",
      "right": "15mm"
    },
    "displayHeaderFooter": true,
    "headerTemplate": "<div style='font-size: 8px; color: #888; width: 100%; text-align: right; padding-right: 15mm;'>CONFIDENTIAL</div>",
    "footerTemplate": "<div style='font-size: 8px; color: #888; width: 100%; text-align: center;'>Page <span class='pageNumber'></span> of <span class='totalPages'></span></div>"
  }
}

Mastering CSS page breaks in PDFs

Controlling how elements split across pages is critical for legal agreements. You don't want your sign-off details floating alone on page five, nor do you want a table row cut in half. The PDF generation engine supports standard CSS paged media rules:

1. Forced Page Breaks (page-break-before: always / break-before: page): Use this to begin a new major section on a clean page. You can insert an HTML element directly into your markdown to trigger this:

Markdown snippet for forcing a page break
<div class="page-break"></div>

2. Avoiding Inside Breaks (page-break-inside: avoid / break-inside: avoid): Apply this to groups of elements that must stay together, such as signature fields, callout boxes, or small tables.

3. Preventing Headings Orphans (page-break-after: avoid / break-after: avoid): Prevent headings from sitting alone at the bottom of a page by ensuring they always stay attached to the paragraph that follows.

Styling tables, lists, and images

Because markdown compiles into standard HTML tags, you can target them directly using your custom CSS block. Use this table as a reference for print-specific rules:

ElementCSS PropertyRecommended Value
Table Rows (tr)page-break-insideavoid
Table Header (thead)displaytable-header-group
Tables (table)border-collapsecollapse
Signature Box (.sig)page-break-insideavoid
Images (img)max-width, height100%, auto

A complete generation example (Node.js)

Here is a complete integration script. It defines a document with a forced page break using an inline HTML spacer, customizes CSS fonts and margins, makes a POST request to Signbee, and saves the generated PDF buffer directly to the local filesystem.

Node.js — Generate styled PDF via Signbee API
import fs from 'fs/promises';

async function generateStyledPdf() {
  const payload = {
    markdown: `# Master Services Agreement
    
This Agreement is entered into as of May 24, 2026.

## 1. Services and Deliverables
The Consultant will provide styling engine services as detailed in Exhibit A.

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

## 2. Payment Terms
Invoices are payable within 30 days of receipt.

<div class="signature-block">
  <h3>Signatures</h3>
  <table style="width: 100%; border: none;">
    <tr>
      <td style="width: 50%; border: none; padding: 20px 0;">
        ___________________________<br/>
        <strong>Client Signature</strong>
      </td>
      <td style="width: 50%; border: none; padding: 20px 0;">
        ___________________________<br/>
        <strong>Consultant Signature</strong>
      </td>
    </tr>
  </table>
</div>`,
    css: `
      body {
        font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
        color: #333;
        font-size: 11pt;
        line-height: 1.6;
      }
      h1 { font-size: 22pt; margin-bottom: 20px; color: #111; }
      h2 { font-size: 16pt; margin-top: 30px; color: #222; }
      h3 { font-size: 13pt; margin-top: 20px; color: #333; }
      .page-break { page-break-before: always; }
      .signature-block { page-break-inside: avoid; margin-top: 50px; }
    `,
    options: {
      format: "A4",
      margin: {
        top: "25mm",
        bottom: "25mm",
        left: "20mm",
        right: "20mm"
      },
      displayHeaderFooter: true,
      headerTemplate: `<div style="font-size: 9px; color: #888; width: 100%; text-align: right; padding-right: 20mm; font-family: sans-serif;">Confidential - MSA</div>`,
      footerTemplate: `<div style="font-size: 9px; color: #888; width: 100%; text-align: center; font-family: sans-serif;">Page <span class="pageNumber"></span> of <span class="totalPages"></span></div>`
    }
  };

  const response = await fetch("https://signb.ee/api/v1/generate", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "Authorization": "Bearer YOUR_API_KEY"
    },
    body: JSON.stringify(payload)
  });

  if (!response.ok) {
    const errorText = await response.text();
    throw new Error(`Failed to generate PDF: ${response.status} ${errorText}`);
  }

  // API returns the raw PDF stream
  const arrayBuffer = await response.arrayBuffer();
  await fs.writeFile("agreement.pdf", Buffer.from(arrayBuffer));
  console.log("agreement.pdf generated successfully!");
}

generateStyledPdf().catch(console.error);

Common PDF rendering and styling mistakes

When moving from continuous HTML screens to a physical paper size like A4 or Letter, developers frequently encounter rendering issues. Here are the most common mistakes and how to fix them:

MistakeConsequence
Using Flexbox / Grid wrappingColumns clip or break poorly across pages
Relative font sizes (rem / em)Font scaling depends on viewport size, leading to unpredictable sizing
Ignoring background color rulesTable headers or callouts have missing background fills in PDF
Orphaned HeadingsH2/H3 titles show at bottom of page; text starts on next page
No margin space in footer/headerHeaders/footers overlap document text

Frequently Asked Questions

Can I use standard CSS rules like page-break-before in markdown to PDF conversion?

Yes. When converting markdown to PDF using Signbee's API, you can embed standard CSS style tags or inline styles. To force a page break, use rules like page-break-before: always or break-before: page inside HTML tags embedded in your markdown, such as <div class="page-break"></div> or via custom CSS class definitions.

How do I manage margins, headers, and footers when generating PDFs?

Margins, headers, and footers are controlled via the Signbee /v1/generate API payload options. You can specify top, bottom, left, and right margins in inches, millimeters, or pixels. Custom headers and footers can contain HTML with special classes like date, title, url, pageNumber, and totalPages to dynamically print page info.

How do I style markdown tables and lists for PDF outputs?

Since markdown tables and lists compile to standard HTML tags (<table>, <ul>, <ol>), you can style them by passing a custom CSS stylesheet in the API payload. You should set border-collapse: collapse and define borders, padding, and alternating row backgrounds for tables to ensure they render beautifully and remain readable on a printed page.

Create beautifully styled agreements instantly — 5 free docs/month, 100 req/min.

Last updated: May 29, 2026 · Michael Beckett is the founder of Signbee and B2bee Ltd.

Related resources