import nokap
nokap.webshot("https://example.com", "page.pdf")PDF Generation
Generate PDFs with configurable page size, margins, orientation, and background printing. nokap leverages Chrome’s built-in print-to-PDF functionality through the DevTools Protocol, giving you access to the same rendering engine used for on-screen display. This page walks through all available PDF options including standard paper sizes, custom dimensions, margin control, and header/footer configuration.
Basic PDF Capture
nokap determines the output format from the file extension. Any webshot() or from_html() call with a .pdf output extension generates a PDF instead of a raster screenshot (no separate function or mode switch is required):
Page Size
For full-page PDFs, the page_size parameter controls the paper dimensions. This affects how content is paginated and how much fits on each page:
nokap.webshot("https://example.com", "a4.pdf", page_size="a4")
nokap.webshot("https://example.com", "letter.pdf", page_size="letter")Available page sizes:
| Size | Dimensions (inches) |
|---|---|
letter |
8.5 × 11 |
legal |
8.5 × 14 |
tabloid |
11 × 17 |
ledger |
17 × 11 |
a0 |
33.1 × 46.8 |
a1 |
23.4 × 33.1 |
a2 |
16.5 × 23.4 |
a3 |
11.7 × 16.5 |
a4 |
8.27 × 11.7 |
a5 |
5.83 × 8.27 |
a6 |
4.13 × 5.83 |
Margins
Set page margins in inches. A single value applies to all sides:
# 1-inch margins on all sides
nokap.webshot("https://example.com", "page.pdf", margins=1.0)
# No margins
nokap.webshot("https://example.com", "page.pdf", margins=0)For asymmetric margins, pass a 4-tuple of (top, right, bottom, left):
nokap.webshot(
"https://example.com",
"page.pdf",
margins=(1.0, 0.75, 1.0, 0.75), # top, right, bottom, left
)The default margin is 0.5 inches on all sides.
Orientation
By default, PDFs render in portrait orientation. Use landscape=True to rotate the page, which is useful for wide content like data tables or charts that benefit from extra horizontal space:
nokap.webshot("https://example.com", "wide.pdf", landscape=True)Print Background
Chrome’s print-to-PDF follows the same convention as physical printing: CSS background colors and images are omitted by default to save ink. For web content where backgrounds are part of the design (styled tables, colored headings, etc.), enable them explicitly:
nokap.webshot(
"https://example.com",
"styled.pdf",
print_background=True,
)A Note on Scale
Unlike raster screenshots where zoom controls pixel density, PDFs are a vector format: text and graphics are stored as scalable geometry, not pixels. This means PDFs always render at the highest possible resolution regardless of any scale setting.
The zoom parameter is ignored for PDF output. Use zoom only for raster screenshots (PNG, JPEG, WebP) where it controls output pixel density and sharpness on HiDPI displays.
Element-Bounded PDF
One of nokap’s most powerful features is the ability to produce a PDF that’s sized exactly to a specific element rather than a standard paper size. When you combine a .pdf output with a selector, nokap produces a tightly-bounded PDF with the paper dimensions matched to the element’s bounding box. The text remains fully selectable and searchable (unlike a raster screenshot embedded in a PDF).
This is the feature to reach for when you need to place a table or chart into a presentation (Keynote, PowerPoint, Google Slides) at vector quality, or when you want a compact PDF that contains only the content you care about.
# Capture just the table as a tight-fit PDF
nokap.webshot("report.html", "table.pdf", selector="table", expand=10)Under the hood, the element-bounded PDF works by:
- Measuring the element’s bounding box in CSS pixels
- Setting the PDF paper size to exactly match those dimensions (converted to inches)
- Injecting print-specific CSS to isolate the element and hide surrounding content
- Rendering via Chrome’s
Page.printToPDFwith zero page margins
The result is a single-page PDF where the page boundary coincides with the element boundary (plus any expand padding you specify).
With from_html()
For packages that generate HTML programmatically (like Great Tables, Plotly, or custom report builders) from_html() is the natural entry point. Pass the HTML string and a selector to extract just the relevant element as a vector PDF:
from great_tables import GT, exibble
html = GT(exibble).as_raw_html(make_page=True, all_important=True)
# Tight PDF of just the table (useful for slides)
nokap.from_html(html, "table.pdf", selector="table", expand=5)Expand / Padding
The expand parameter adds even whitespace around the element in the PDF. This is purely a visual affordance and it gives the content some breathing room so it doesn’t feel jammed against the edges when placed into a slide or document:
# No padding: PDF edges touch the table
nokap.from_html(html, "tight.pdf", selector="table")
# 20px breathing room on all sides
nokap.from_html(html, "padded.pdf", selector="table", expand=20)
# Asymmetric padding
nokap.from_html(html, "asym.pdf", selector="table", expand=(10, 20, 10, 20))Backgrounds
Element-bounded PDFs include CSS backgrounds by default. This is intentional: when you’re exporting a styled table or chart, the background colors, borders, and shading are typically essential to the visual design. Full-page PDFs follow Chrome’s printing convention and omit backgrounds unless you explicitly set print_background=True.
Wide Tables
A common challenge with table-to-PDF export is that wide tables get clipped when they exceed the viewport width. nokap handles this automatically: it detects when an element’s natural width is being constrained by the viewport, temporarily widens the viewport to let the content expand, then sizes the PDF paper to fit the full element. No manual vwidth adjustment is needed (even very wide tables with dozens of columns render completely).
import pandas as pd
from great_tables import GT
# A 20-column table that's wider than the default 992px viewport
df = pd.DataFrame({f"col_{i}": [f"val_{i}"] for i in range(20)})
html = GT(df).as_raw_html(make_page=True, all_important=True)
# Automatically expands to fit all columns
nokap.from_html(html, "wide_table.pdf", selector="table", expand=5)Full-Page PDF vs Element-Bounded PDF
To summarize the two PDF modes and when to reach for each:
| Full-Page PDF | Element-Bounded PDF | |
|---|---|---|
| Trigger | .pdf output, no selector |
.pdf output + selector |
| Paper size | Standard (letter, A4, etc.) | Sized to element |
| Content | Entire page | Just the selected element |
| Backgrounds | Off by default | On by default |
| Use case | Print a document | Export a table/chart for slides |
Both modes produce true vector PDFs with selectable text. The choice comes down to whether you want a traditional paginated document or a compact, element-sized artifact for embedding elsewhere.
PDF from HTML Strings
Just as with screenshots, you can generate a full-page PDF directly from an HTML string using from_html(). This is convenient for generating documents from templates or programmatic HTML without writing to a temporary file yourself:
html = """
<html>
<body>
<h1>Invoice #1234</h1>
<table>
<tr><td>Widget</td><td>$10.00</td></tr>
<tr><td>Gadget</td><td>$25.00</td></tr>
<tr><th>Total</th><th>$35.00</th></tr>
</table>
</body>
</html>
"""
nokap.from_html(html, "invoice.pdf", page_size="a4", margins=1.0)Complete Example
Here’s a full-page PDF capture with all common options specified explicitly, showing how the parameters work together:
nokap.webshot(
"report.html",
"report.pdf",
page_size="a4",
margins=(1.0, 0.75, 1.0, 0.75),
landscape=False,
print_background=True,
)And an element-bounded PDF workflow for exporting a styled table to a presentation:
from great_tables import GT, exibble
html = GT(exibble).as_raw_html(make_page=True, all_important=True)
nokap.from_html(html, "table_for_slides.pdf", selector="table", expand=10)Next Steps
This page covered both full-page and element-bounded PDF generation from standard paper sizes and margins to the tightly-fitted, selector-driven PDFs that are ideal for embedding in presentations. Because PDFs are vector format, you get crisp text at any zoom level without worrying about pixel density.
- The CLI: Generate PDFs from the command line
- Integration with Great Tables: Export tables as images or PDFs
All of the PDF options covered here are also available via the command-line interface, making it easy to integrate nokap into scripts and automation pipelines.