PDF to HTML with CSS

The CSS a converter writes is a coordinate list. It reproduces the printed page exactly at one width and cannot reflow at any other, because there is no layout underneath it.

Converting a PDF to HTML with CSS gives you a stylesheet full of coordinates, not a layout. That distinction decides everything about what you can do with the output.

The generated stylesheet from a converted PDF, showing numbered classes with top and left offsets.
The generated stylesheet from a converted PDF, showing numbered classes with top and left offsets.

A converter reads the PDF and finds text runs at positions. It has no way to know that two runs form a paragraph, so it writes one positioned element per run and a class holding the position.

Rendered at the original width, it matches the PDF closely. Rendered at any other width, nothing moves, because nothing was ever laid out.

PDF to HTML with CSS: what the generated stylesheet holds

Rule type What it holds Keep it
Page container Fixed width and height per PDF page Only for a visual archive
Positioned text classes position: absolute, top, left No, if you want reflow
Font classes Family, size, colour, numbered Yes, after consolidating
Background images One per page, the page picture Usually no
Word spacing fixes Per run letter spacing No

The pattern looks like this.

.ft07 { font-size: 11px; font-family: Times; color: #000; }
#page1-div { position: relative; width: 892px; height: 1263px; }
.p07 { position: absolute; top: 412px; left: 96px; white-space: nowrap; }

Three things are worth reading out of that. The page is a fixed box in pixels. Every run is absolutely placed. And white-space: nowrap guarantees no line will ever wrap, which is the reflow problem stated directly in CSS.

Producing it

Poppler's pdftohtml is the usual command line route and the flags decide what you get.

pdftohtml -c -s -noframes -zoom 1.5 report.pdf out.html
  • -c produces the complex output with the positioning CSS. Without it you get plain text runs and no layout at all.
  • -s puts every page into one document rather than one file per page.
  • -noframes drops the frameset wrapper older versions emit.
  • -zoom sets the scale, which affects the pixel coordinates and the extracted image resolution.

Flags vary by build, so check pdftohtml -h against the version you have. Converting PDF to HTML covers the other routes and when to use each.

Decide which output you want

There are two honest destinations and they need opposite treatment.

A visual archive. The page should look like the printed original. Keep the positioning, keep the page containers, accept that it will not work on a phone. Minimal work.

A readable page. The text should reflow and be searchable. Delete the positioning entirely and rebuild the structure. Significant work, and the only route that produces something usable on a phone.

Trying to get both out of one file is where people spend a day and finish with neither.

Making it reflow

If you chose the readable page, the cleanup has a fixed shape.

  1. Strip the positioning. Remove every position: absolute, every top, every left, and every white-space: nowrap.
  2. Remove the fixed page boxes. They impose the printed page size on a medium that has no pages.
  3. Merge the runs. Consecutive runs on the same line belong in one paragraph element.
  4. Restore structure. Large font runs are headings. Runs starting with a bullet glyph are list items. Convert them.
  5. Consolidate the font classes. Twenty numbered classes usually collapse to three or four real ones.
body { max-width: 72ch; margin: 2rem auto; line-height: 1.6; }
h2 { font-size: 1.4rem; margin-top: 2.5rem; }
p { margin: 0 0 1rem; }
table { border-collapse: collapse; width: 100%; }

That is the whole stylesheet a converted document usually needs, replacing several hundred generated lines.

The same content before and after cleanup, both shown in a narrow window.
The same content before and after cleanup, both shown in a narrow window.

The font question

Fonts embedded in a PDF are subset for that file and are not usable as web fonts. The converter records the name and the browser substitutes.

That means a document set in a licensed serif will render in whatever serif the reader has. Line lengths shift and the page looks subtly different on every machine.

Choose the substitute yourself. Name a web font you have the right to use, or set a short font stack that behaves predictably. Web fonts covers loading one, and fonts not loading covers the usual failure.

Images and the extracted files

A converter writes the page images and any extracted pictures into a folder beside the HTML. The markup references them by relative path.

Move the HTML file on its own and every picture disappears. This is the same trap as any other multi file export.

Embed them, or keep the folder together. Self-contained HTML covers folding the pictures into the file, and inline CSS covers doing the same with the stylesheet.

Sharing the result

The cleaned page pasted into a document, rendering with its own share link.
The cleaned page pasted into a document, rendering with its own share link.

Once the file is self-contained, it still needs somewhere to live. A converted document sitting in a folder has no address.

Paste the HTML into a NOS document and it renders as written, stylesheet included. Share, then Share link, then Create link gives it an address that does not move when you fix the next conversion error.

That matters here more than usual, because converted documents always have a second round of corrections. Editing the page beats re-running the converter and sending a second file.

Questions people ask

What CSS does a PDF converter generate?

Mostly absolute positioning. Each text run gets a class with a top and left offset in pixels, plus a font size and family. There are usually numbered font classes and a page container with a fixed width and height per PDF page.

Why does the converted page not reflow?

Every element is placed at a fixed coordinate, so narrowing the window moves nothing. Reflow requires elements in normal document flow, which means removing the positioning and giving the content real paragraph and heading elements instead.

Can I keep the fonts from the PDF?

Not directly. Fonts embedded in a PDF are subset for that document and are not web fonts. Converters name the font in CSS and the browser substitutes whatever it has. Pick a close web font deliberately rather than leaving the substitution to chance.

Should the CSS be inline or in a separate file?

A separate stylesheet is easier to edit while you work. Inline it before sharing, so the page travels as one file and cannot arrive unstyled. If you paste the HTML into a document that renders it, a single self-contained file is the cleanest input.

Keep reading