ScreenshotNeo

BlogHow-to

How to Preview HTML Code as a PDF

Preview HTML as a PDF with browser print tools, Puppeteer, Acrobat, or ScreenshotNeo—and fix layout, CSS, font, and pagination problems.

By the ScreenshotNeo team1 October 20267 min read

To preview HTML as a PDF, open the page in a browser, use its print preview, and choose a PDF destination or Save as PDF. For repeatable previews, use Puppeteer and call page.pdf(). Remember that PDF generation usually uses print CSS, so the result can differ from the screen version.

Quick decision guide

Situation Best starting point
One-time visual check Browser print preview
Repeatable or automated output Puppeteer
More conversion controls for a URL or local file Acrobat desktop
HTML-to-PDF service workflow Adobe PDF Services API
Need a clean screenshot or PDF from a live URL without browser setup ScreenshotNeo

Preview HTML as a PDF in a browser

  1. Open the HTML page in your browser. For a local file, open the file directly. If it depends on local assets, JavaScript, routing, or server data, run it in the environment where it is intended to work.
  2. Open the browser’s print dialog and inspect the print preview. The exact menu name and keyboard shortcut depend on the browser and operating system.
  3. Select a PDF destination or Save as PDF option when your browser provides one.
  4. Check paper size, portrait or landscape orientation, margins, scale, page breaks, backgrounds, links, and whether wide content is clipped.
  5. Change the print stylesheet or print settings, then preview again.

A minimal print stylesheet

<style>
  @media print {
    body { color: #111; background: #fff; }
    .screen-only, nav, .chat-widget { display: none !important; }
    .page-break { break-before: page; }
    h1, h2, h3 { break-after: avoid; }
    table, figure, img { break-inside: avoid; }
    a { color: inherit; text-decoration: none; }
  }

  @page {
    size: A4;
    margin: 18mm;
  }
</style>

Use break-before, break-after, and break-inside for modern pagination rules. Keep older page-break-before, page-break-after, and page-break-inside declarations when you need compatibility with older rendering engines.

Preview screen CSS instead of print CSS with Puppeteer

Puppeteer’s page.pdf() generates a PDF with the print CSS media type by default. If the PDF should resemble the screen, call page.emulateMediaType('screen') first. Puppeteer also documents that PDF colors may be adjusted for printing; use -webkit-print-color-adjust: exact when exact colors are required.

Complete runnable example

npm install puppeteer
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: true });
  try {
    const page = await browser.newPage();
    await page.setViewport({ width: 1440, height: 900, deviceScaleFactor: 1 });

    // Use a URL, local development server, or file URL.
    await page.goto('http://localhost:3000/example.html', {
      waitUntil: 'networkidle0',
      timeout: 60000
    });

    // Choose this when the PDF should match screen styles.
    await page.emulateMediaType('screen');

    // Wait for application-rendered content and fonts.
    await page.waitForSelector('#report');
    await page.evaluate(async () => {
      if (document.fonts) await document.fonts.ready;
      const images = Array.from(document.images);
      await Promise.all(images.map(img => {
        if (img.complete) return Promise.resolve();
        return new Promise(resolve => {
          img.addEventListener('load', resolve, { once: true });
          img.addEventListener('error', resolve, { once: true });
        });
      }));
    });

    await page.pdf({
      path: 'preview.pdf',
      format: 'A4',
      printBackground: true,
      preferCSSPageSize: true,
      margin: { top: '18mm', right: '18mm', bottom: '18mm', left: '18mm' }
    });
  } finally {
    await browser.close();
  }
})();

See the Puppeteer Page.pdf() API documentation for the current option names and behavior.

Useful Puppeteer options

Option Use
path Output file path.
format Standard paper size such as A4 or Letter.
width, height Custom paper dimensions.
landscape Switch to landscape orientation.
margin Set top, right, bottom, and left margins.
printBackground Include CSS background graphics.
preferCSSPageSize Use the document’s @page size when defined.
pageRanges Export selected pages, such as 1-3.
displayHeaderFooter Enable generated PDF headers and footers.
scale Adjust PDF rendering scale within the supported range.

Make the HTML deterministic before capture

  • Wait for the application state, not just the initial page load.
  • Wait for fonts with document.fonts.ready.
  • Wait for images, charts, and other asynchronous assets.
  • Use a fixed viewport, timezone, locale, and test data when visual consistency matters.
  • Disable animations and transitions in print CSS.
  • Make sure the capture process can reach private APIs, fonts, and images.
  • Use absolute or correctly resolved asset URLs when converting a local file.
@media print {
  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
    caret-color: transparent !important;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
}

Why the PDF looks different from the page

Print output can use different CSS, color handling, paper dimensions, font metrics, and pagination rules than the screen. A wide layout may wrap or clip, fixed-position elements may repeat unexpectedly, and backgrounds may be omitted unless the print workflow or PDF generator includes them.

Screen media versus print media

Use @media screen for interactive layout and @media print for paper output. With Puppeteer, call page.emulateMediaType('screen') before page.pdf() when the screen rendering is the intended reference. Otherwise, design and review a dedicated print layout.

Pagination controls

.keep-together {
  break-inside: avoid;
  page-break-inside: avoid;
}

.start-new-page {
  break-before: page;
  page-break-before: always;
}

.no-break-after {
  break-after: avoid;
  page-break-after: avoid;
}

Acrobat and PDF conversion services

Acrobat desktop can convert a URL or local HTML file and provides controls for page layout, encoding, fonts, colors, backgrounds, images, links, scrollable blocks, page size, orientation, margins, and scaling wide content to fit. These controls are useful when a browser preview loses backgrounds, clips wide content, or handles scrollable regions differently. See Adobe’s documentation for converting web pages to PDFs in Acrobat and customizing web-page conversion settings.

For a developer-facing service workflow, Adobe documents an HTML-to-PDF option in PDF Services API for static or dynamic HTML, ZIP input, and URLs. Choose a service when conversion belongs in an application or build pipeline rather than a local preview.

Or skip the browser setup

ScreenshotNeo can return a PDF from one GET request to a live URL. Its capture options include PDF paper size, margins, landscape mode, and page ranges, along with waiting for a selector, delay, or network idle.

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://stripe.com \
  -o preview.pdf
import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
r.raise_for_status()
open("preview.pdf", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const buffer = Buffer.from(await res.arrayBuffer());
require('fs').writeFileSync('preview.pdf', buffer);

Read the ScreenshotNeo API documentation for the full parameter set. Cookie banners, newsletter popups, and chat widgets are removed before the capture. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers identify the page verdict and billing status. An MCP server lets Claude, Cursor, and other MCP clients use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

Troubleshooting

Symptom Likely cause Fix
Content is missing JavaScript had not finished rendering. Wait for a specific selector, application state, or network idle; increase the timeout.
Fonts fall back Web fonts were blocked, unavailable, or not loaded. Check font URLs and permissions, then wait for document.fonts.ready.
Images are blank Lazy loading or image requests completed after capture. Scroll or trigger lazy loading, wait for image completion, and inspect failed requests.
Colors or backgrounds disappear Print settings omit background graphics or print CSS changes colors. Enable background graphics, set printBackground: true, and use print-color-adjust: exact where appropriate.
Screen and PDF layouts differ Puppeteer uses print media by default. Emulate screen media or create intentional print CSS.
Wide content is clipped Content exceeds the paper width. Use responsive print rules, landscape orientation, smaller margins, or a fit-to-page setting.
Unexpected page breaks Large blocks, tables, or CSS break rules do not fit. Apply break-inside: avoid selectively and remove excessive fixed heights.
Local assets fail The file depends on a server, relative paths, or blocked local access. Run the app locally and capture its HTTP URL, or correct asset paths and browser permissions.
Private pages return an error Authentication or required headers are missing. Supply the session or authorization context in your automation or capture service.
Capture times out A request, script, or third-party widget never settles. Block unnecessary resources, wait for a reliable selector instead of every request, and set a bounded timeout.

Performance, reliability, and cost notes

  • Browser automation has startup and rendering cost, so reuse a browser process for batches and avoid waiting for resources the document does not need.
  • Network-idle waits can be unreliable on pages with analytics, websockets, or polling. A page-specific ready selector is often more deterministic.
  • Fix the viewport, media type, fonts, locale, and data if generated PDFs are compared in CI.
  • Cache stable assets and block ads, trackers, and unnecessary resource types when they cannot affect the PDF.
  • For a manual preview, the browser print dialog has no dedicated purchase requirement for the basic workflow. Automated services and desktop software have their own pricing and account terms; check the current provider documentation.
  • With ScreenshotNeo, cache hits and failed or unusable captures are not billed; inspect the X-Page-Verdict and X-Billed response headers when accounting for usage.

Preview checklist

  • Correct paper size and orientation
  • Readable margins and scale
  • No clipped horizontal content
  • Expected print or screen media CSS
  • Fonts loaded
  • Images and charts visible
  • Backgrounds included when required
  • Headings and tables break sensibly
  • Links and page ranges behave as intended
  • Dynamic content is complete before capture

FAQ

Can I preview HTML without saving a PDF?

Yes. The browser’s print preview lets you inspect pagination and layout before saving. You can also run Puppeteer and write the PDF only when the preview passes your checks.

Should I use print CSS or screen CSS?

Use print CSS for documents designed for paper or standard PDF output. Emulate screen media when the PDF is intended to reproduce the on-screen layout.

Why does a local HTML file work in a browser but fail in automation?

Local files often rely on relative paths, server routes, modules, or permissions that differ under automation. Serve the project over HTTP and capture that URL.

How do I preview only selected PDF pages?

In Puppeteer, use the pageRanges PDF option. In a browser or desktop converter, use the page-range control provided by the print or conversion dialog.

Can a screenshot API create a PDF preview?

Yes. A service such as ScreenshotNeo can capture a live URL as a PDF and handle waiting, page settings, and unwanted overlays without requiring you to maintain browser automation.