HTML & CSS Basics
Design PDF templates with HTML and CSS
DoCreate uses a headless Chromium browser to render your HTML and CSS into pixel-perfect PDFs. This means you can use the same web technologies you already know to design documents -- no special markup language required.
Writing Template HTML
The html field contains the main body content of your PDF. Write it the same way you would write a web page:
<div class="invoice">
<div class="invoice-header">
<h1>Invoice</h1>
<p class="invoice-number">#INV-2026-001</p>
</div>
<div class="client-details">
<p><strong>Bill to:</strong></p>
<p>Acme Corp</p>
<p>123 Main Street</p>
<p>Berlin, 10115</p>
</div>
<table class="line-items">
<thead>
<tr>
<th>Description</th>
<th>Qty</th>
<th>Unit Price</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr>
<td>Web Development</td>
<td>40</td>
<td>120.00 EUR</td>
<td>4,800.00 EUR</td>
</tr>
</tbody>
</table>
<div class="total">
<p>Total: <strong>4,800.00 EUR</strong></p>
</div>
</div>
Adding CSS Styles
Pass your CSS in the css field. Styles are injected into the document before rendering:
body {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 12px;
color: #333333;
line-height: 1.5;
margin: 0;
padding: 40px;
}
.invoice-header {
display: flex;
justify-content: space-between;
align-items: baseline;
border-bottom: 2px solid #1a1a1a;
padding-bottom: 16px;
margin-bottom: 32px;
}
.invoice-header h1 {
font-size: 28px;
margin: 0;
color: #1a1a1a;
}
.invoice-number {
font-size: 14px;
color: #666666;
}
.line-items {
width: 100%;
border-collapse: collapse;
margin: 24px 0;
}
.line-items th {
background-color: #f5f5f5;
text-align: left;
padding: 10px 12px;
font-weight: 600;
border-bottom: 1px solid #dddddd;
}
.line-items td {
padding: 10px 12px;
border-bottom: 1px solid #eeeeee;
}
.total {
text-align: right;
font-size: 16px;
margin-top: 24px;
padding-top: 16px;
border-top: 2px solid #1a1a1a;
}
Supported CSS Features
Since DoCreate renders with Chromium, you have access to modern CSS features:
Layout
- Flexbox --
display: flex,justify-content,align-items,flex-wrap,gap - CSS Grid --
display: grid,grid-template-columns,grid-gap - Box model --
margin,padding,border,box-sizing - Positioning --
relative,absolute,fixed(use with care in print context)
Typography
- Font properties --
font-family,font-size,font-weight,line-height,letter-spacing - Text styling --
text-align,text-transform,text-decoration,color - Web fonts -- Load external fonts via
@importin your CSS (see Best Practices)
Visual Styling
- Colors -- Hex, RGB, HSL, and named colors
- Backgrounds --
background-color,background-image, gradients - Borders --
border,border-radius,box-shadow - Opacity and visibility --
opacity,visibility
Print-Specific CSS
These properties are particularly useful for PDF generation:
/* Control page breaks */
.section {
page-break-inside: avoid;
}
.chapter {
page-break-before: always;
}
/* Set page size and margins */
@page {
size: A4;
margin: 20mm;
}
/* Hide elements not needed in print */
@media print {
.no-print {
display: none;
}
}
Full Example
Here is a complete API request that combines HTML and CSS into a professional invoice:
curl -X POST https://api.docreate.io/api/pdf/external \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"html": "<div class=\"invoice\"><div class=\"header\"><div><h1>INVOICE</h1><p class=\"subtitle\">DoCreate GmbH</p></div><div class=\"meta\"><p><strong>Invoice:</strong> #INV-2026-042</p><p><strong>Date:</strong> 2026-02-17</p><p><strong>Due:</strong> 2026-03-17</p></div></div><div class=\"addresses\"><div><p class=\"label\">From</p><p>DoCreate GmbH</p><p>Musterstrasse 1</p><p>10115 Berlin, DE</p></div><div><p class=\"label\">Bill To</p><p>Acme Corp</p><p>456 Oak Avenue</p><p>80331 Munich, DE</p></div></div><table><thead><tr><th>Description</th><th>Hours</th><th>Rate</th><th>Amount</th></tr></thead><tbody><tr><td>Frontend Development</td><td>32</td><td>95.00 EUR</td><td>3,040.00 EUR</td></tr><tr><td>API Integration</td><td>18</td><td>110.00 EUR</td><td>1,980.00 EUR</td></tr><tr><td>QA & Testing</td><td>12</td><td>85.00 EUR</td><td>1,020.00 EUR</td></tr></tbody></table><div class=\"totals\"><div class=\"totals-row\"><span>Subtotal</span><span>6,040.00 EUR</span></div><div class=\"totals-row\"><span>VAT (19%)</span><span>1,147.60 EUR</span></div><div class=\"totals-row total\"><span>Total</span><span>7,187.60 EUR</span></div></div></div>",
"css": "body { font-family: Helvetica, sans-serif; font-size: 11px; color: #333; padding: 40px; } .header { display: flex; justify-content: space-between; margin-bottom: 40px; } h1 { font-size: 32px; margin: 0; color: #111; } .subtitle { color: #666; margin: 4px 0 0; } .meta { text-align: right; line-height: 1.8; } .addresses { display: flex; gap: 60px; margin-bottom: 32px; } .label { font-weight: 700; text-transform: uppercase; font-size: 10px; letter-spacing: 0.5px; color: #999; margin-bottom: 4px; } table { width: 100%; border-collapse: collapse; margin-bottom: 24px; } th { background: #f8f8f8; text-align: left; padding: 10px; font-weight: 600; border-bottom: 2px solid #ddd; } td { padding: 10px; border-bottom: 1px solid #eee; } th:last-child, td:last-child { text-align: right; } .totals { margin-left: auto; width: 260px; } .totals-row { display: flex; justify-content: space-between; padding: 6px 0; } .totals-row.total { font-weight: 700; font-size: 14px; border-top: 2px solid #111; padding-top: 10px; margin-top: 6px; }"
}'
Limitations
While most CSS is supported, keep these points in mind:
- No JavaScript execution -- Templates are rendered as static HTML/CSS. Interactive elements like
onclickhandlers are ignored. - External images -- Images referenced via URL must be publicly accessible. Use base64-encoded images for guaranteed reliability.
- Viewport -- The rendering viewport matches the PDF page size (e.g., 794px wide for A4). Design accordingly.
- Animations and transitions -- CSS animations are not rendered. The first frame is captured.
Next Steps
- Dynamic Data -- Replace hardcoded values with variables
- Headers & Footers -- Add repeating page headers and footers
- Best Practices -- Optimize templates for production