How to Edit HTML Code and Export It as a PDF
Edit HTML and CSS, make print-ready layouts, fix pagination, and export a reliable PDF from your browser or ScreenshotNeo.
Short answer: edit the HTML and CSS source files, add print-specific rules with @media print and @page, inspect the result in browser print preview, then choose Save to PDF. Developer Tools edits are temporary unless you use a configured Workspace or copy the changes back into your source files.
1. Choose the editing workflow
There are three practical ways to change a page before exporting it:
| Workflow | Best for | Does it persist? |
|---|---|---|
| Edit source files | Permanent, repeatable PDFs | Yes, when you save the files |
| Browser Developer Tools | Inspecting layout and trying CSS values | No, unless a Workspace is configured |
| DevTools Workspace | Editing locally while seeing the live page | Yes, changes can map to local files |
Use Developer Tools to discover what needs changing, then persist the final HTML and CSS in your editor. MDN describes live DOM and CSS edits as temporary; a reload normally removes them. Chrome Workspaces provide a way to save supported DevTools changes to your local file system.
2. Edit the HTML and CSS source
Start with a small document and a separate print stylesheet. Keeping print rules separate makes it easier to maintain the screen layout.
<!doctype html>
<html lang='en'>
<head>
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<title>Project report</title>
<link rel='stylesheet' href='styles.css'>
<link rel='stylesheet' href='print.css' media='print'>
</head>
<body>
<header id='header'>Project report</header>
<nav id='nav'>Screen navigation</nav>
<main>
<h1>Project report</h1>
<p>Content that should appear in the PDF goes here.</p>
<section class='avoid-break'>
<h2>Results</h2>
<p>Keep this section together where the page size allows.</p>
</section>
</main>
<footer id='footer'>Screen footer</footer>
<button class='screen-only' type='button' onclick='window.print()'>Print</button>
</body>
</html>
The corresponding screen stylesheet can contain your normal responsive design:
body {
font-family: system-ui, sans-serif;
line-height: 1.5;
max-width: 70rem;
margin: 0 auto;
padding: 2rem;
}
main {
background: white;
}
.screen-only {
position: fixed;
right: 1rem;
bottom: 1rem;
}
3. Add print-only CSS
Use media='print' on a dedicated stylesheet or place the rules inside an @media print block. Use @page for paper size, orientation, and margins.
@page {
size: A4;
margin: 18mm;
}
@media print {
#header,
#footer,
#nav,
.screen-only,
button {
display: none !important;
}
body {
max-width: none;
margin: 0;
padding: 0;
color: #000;
background: #fff;
}
a {
color: #000;
text-decoration: none;
}
.avoid-break {
break-inside: avoid;
}
h1,
h2,
h3 {
break-after: avoid;
}
img,
figure,
table {
max-width: 100%;
}
}
A4 is only an example. Choose the paper size and margins your audience needs. In print preview, also check the browser’s scale, paper size, margins, headers and footers, and background-graphics settings because those controls can change the final PDF.
Hide navigation and controls
Give screen-only elements a class or stable selector and hide them during printing. Prefer a specific selector over broad rules such as hiding every header, because a report may contain a header that belongs in the PDF.
Control page breaks
Use break-before, break-after, and break-inside where a section must start on a new page or should not split. These are requests to the browser; a very large element can still span pages.
@media print {
.page-break-before {
break-before: page;
}
.keep-with-next {
break-after: avoid;
}
.avoid-break {
break-inside: avoid;
}
}
Preserve colors and backgrounds
Print preview often has a control for background graphics. If a colored panel is essential, verify that option is enabled in the browser. For a document that must remain readable without backgrounds, set a clear text color and border in print CSS instead of relying on a background alone.
Handle links, images, and fonts
- Remove link underlines only when the destination is obvious; otherwise keep them or add printed URLs with generated content.
- Use local or reliably loaded fonts and wait for them before printing. A late font swap can change line wrapping and pagination.
- Give images an explicit width or
max-width: 100%so they cannot overflow the page. - Use descriptive
alttext for accessibility, even though it may not be visible in the PDF.
4. Preview and export the PDF
- Save the HTML, screen CSS, and print CSS.
- Open the file directly or serve the directory from a local development server.
- Open the browser print dialog with
Ctrl+Pon Windows/Linux orCmd+Pon macOS. - Select the browser’s Save to PDF destination.
- Set the paper size, orientation, margins, scale, and background-graphics options.
- Review every page for clipping, unexpected blank pages, split headings, missing images, and incorrect colors.
- Save the PDF with a descriptive filename and reopen it in a PDF viewer to verify the exported file.
The browser owns the print dialog and performs the final pagination. A CSS change that looks correct on screen is not finished until it passes print preview.
5. Add a print button without changing the PDF layout
A page can expose a button that calls window.print(). The API opens the browser print dialog; it does not silently write a PDF file.
<button id='print-button' class='screen-only' type='button'>Print or save as PDF</button>
<script>
document.querySelector('#print-button').addEventListener('click', () => {
window.print();
});
window.addEventListener('beforeprint', () => {
document.body.classList.add('is-printing');
});
window.addEventListener('afterprint', () => {
document.body.classList.remove('is-printing');
});
</script>
Use beforeprint and afterprint when a screen-only control needs temporary state changes. Most permanent layout work belongs in print CSS.
6. Use Developer Tools safely
- Open Developer Tools and inspect the element whose spacing, color, or visibility needs changing.
- Edit the DOM or CSS rule in the Elements panel and inspect the result immediately.
- When the layout is correct, copy the change into the real HTML or stylesheet and save it.
- Reload the page and repeat the print-preview check.
Chrome’s Sources panel can edit CSS and JavaScript. Configure a Workspace when you want supported edits to map to local files. Without a Workspace, a reload can erase the experiment. DevTools is therefore ideal for discovery, while source files or a Workspace are required for repeatable exports.
7. Common problems and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| Changes disappear after reload | The edit was made only in the live DOM or Styles pane | Copy it to the source file or configure a DevTools Workspace |
| Navigation appears in the PDF | No print rule hides it, or the selector does not match | Inspect the element and add a targeted display: none !important rule in print CSS |
| Content is cut off at the right edge | Fixed width, wide table, or oversized image | Use fluid widths, max-width: 100%, and a print-specific table layout |
| Headings are separated from their paragraphs | Normal pagination split the block | Apply break-after: avoid to headings and break-inside: avoid to small sections |
| Unexpected blank pages | Forced page breaks, oversized margins, or an element taller than the page | Remove unnecessary breaks, reduce print margins, and inspect the element’s computed height |
| Background colors are missing | Background graphics are disabled in print settings | Enable background graphics or add borders and high-contrast print colors |
| Images are missing | Network image failed, lazy loading did not trigger, or the print happened too early | Confirm the image loaded, use stable URLs, and wait until images and fonts are ready |
| Font changes pagination | A web font loaded after the preview opened | Wait for document.fonts.ready before invoking print |
| JavaScript content is absent | The page was printed before client-side rendering finished | Wait for the data request and render completion, then preview again |
| PDF text is unreadable | Low scale, very small print font, or poor contrast | Set a readable print size, use dark text, and verify at 100% in a PDF viewer |
8. Wait for dynamic pages before printing
For a page that loads data, images, or fonts asynchronously, make readiness explicit. This pattern waits for fonts and all currently known images before opening print preview:
async function waitUntilPrintable() {
if (document.fonts?.ready) {
await document.fonts.ready;
}
const images = [...document.images];
await Promise.all(images.map((image) => {
if (image.complete) return Promise.resolve();
return new Promise((resolve) => {
image.addEventListener('load', resolve, { once: true });
image.addEventListener('error', resolve, { once: true });
});
}));
}
document.querySelector('#print-button').addEventListener('click', async () => {
await waitUntilPrintable();
window.print();
});
This does not fix a failed request; it only prevents a print action from racing a still-loading resource. Your application should still show an error or placeholder for data that cannot be loaded.
9. Repeatable exports and automation choices
Manual browser printing is suitable for occasional reports and documents that need visual inspection. For recurring exports, keep the HTML and print CSS in version control, use a stable data snapshot, and review representative pages after template changes. Record the browser print settings used by your team so two people do not export different page sizes or margins.
When a server or CI job must create PDFs, use a controlled browser environment or a screenshot/PDF service. Account for authentication, cookies, custom headers, JavaScript readiness, fonts, lazy images, and print-specific styles. Cache stable assets and avoid unnecessary third-party requests to reduce variability.
10. Performance, reliability, and cost considerations
- Performance: large images, web fonts, client-side rendering, and third-party scripts dominate load time. Resize images for the target paper size and remove resources that are irrelevant to the PDF.
- Reliability: wait for the actual content state rather than sleeping for an arbitrary number of milliseconds. Test slow networks and missing assets, and make sure a failed image cannot push content outside the page.
- Repeatability: pin the HTML/CSS version, use deterministic data, and keep print settings documented. A small font or margin change can move every later page break.
- Cost: local browser printing has no API charge, but it consumes developer time and is difficult to run consistently at scale. A hosted API adds request cost while removing browser setup and maintenance.
11. Or skip the browser setup
ScreenshotNeo provides a website screenshot API and MCP server. One GET request can return a PNG, JPEG, WebP, or PDF, with options for full-page capture, PDF paper size, margins, landscape mode, and page ranges. See the ScreenshotNeo API documentation for the current request options.
cURL:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python:
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("shot.webp", "wb").write(r.content)
Node.js:
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(`Screenshot failed: ${res.status}`);
const body = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then((fs) => fs.writeFile('shot.webp', body));
For a PDF request, select the PDF output and its paper, margin, orientation, and page-range options in the request as documented. ScreenshotNeo can also wait for a selector, delay, or network idle; load lazy images; run custom JavaScript; click an element; hide selectors; set cookies, headers, user agent, timezone, and geolocation; block ads, trackers, requests, or resource types; and capture a single element instead of the full page.
- Cookie and consent banners, newsletter popups, and chat widgets are removed before the shot; each cleanup step can be turned off.
- Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed. The response identifies the result with
X-Page-VerdictandX-Billedheaders. - An MCP server lets Claude, Cursor, and other MCP clients use
take_screenshot,get_page_info, andcapture_pdf. - The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots, and every feature is available on every plan.
Create a free ScreenshotNeo account and start with the 1,000 included screenshots.
12. Checklist before sharing the PDF
- Source HTML and CSS changes are saved.
- Screen-only navigation and controls are hidden.
- Paper size, margins, orientation, and scale are correct.
- Images and fonts have loaded.
- Headings, tables, and figures break in sensible places.
- No content is clipped horizontally or vertically.
- Colors and backgrounds remain readable when printed.
- The saved PDF opens correctly in a separate viewer.
FAQ
Can I save a PDF directly from Developer Tools?
Developer Tools changes the page; the browser print dialog creates the PDF. Persist important changes in source files or a Workspace first.
Does window.print() choose a filename?
No. It opens the browser’s print dialog. The user or automation environment chooses the destination and filename.
Should print CSS replace my screen CSS?
No. Keep screen and print concerns separate, then override only what changes for paper.
Why does my PDF have different page breaks on another computer?
Fonts, browser versions, print settings, paper size, scale, and loaded content can differ. Control those inputs or use a managed capture environment.
Can I export only one element?
With a browser, temporarily isolate the element or create a print-specific wrapper. ScreenshotNeo supports element capture by CSS selector when you need an API workflow.


