Engineering Journal
Pdf Processor
Pdf Processor

Numbered font classes are better than Tailwind utilities for extracted PDF text

2026-07-17

TLDR: A PDF extraction pipeline that replaces its numbered font classes with Tailwind utility classes would produce larger HTML, lose font precision, and gain nothing. The .fN system maps each unique (font family, size, bold, italic) combination to a 4-byte class name. A single page might define 12 font classes used 400 times. With Tailwind, each use would require text-[12pt] font-['Times_New_Roman'] -- 40+ bytes per element. The numbered class is more efficient. The fix is to add a stable semantic class name like .pdf-paragraph alongside the numbered class, not to eliminate the numbered class.

What the industry does

CSS utility frameworks like Tailwind encourage you to express every style as a class on the element. A paragraph with 12pt Times New Roman left-aligned becomes <p class="text-[12pt] font-['Times_New_Roman'] text-left">. This is explicit, self-documenting, and easy to override.

For hand-written HTML, this approach is excellent. The classes are readable. The JIT compiler generates exactly the CSS you use. No unused styles ship to the browser.

Why it fails for PDF extraction

PDF documents use continuous font sizes, not a 7-step type scale. A typical government budget document might have body text at 10pt, footnotes at 8pt, headings at 14pt and 16pt, table headers at 9pt, captions at 9.5pt, and page numbers at 7pt. That is seven distinct sizes on one page, and none of them match Tailwind's text-sm (14px = 10.5pt) or text-base (16px = 12pt).

You can use Tailwind's arbitrary value syntax: text-[10pt], text-[8pt], text-[14pt], etc. But now you have exploded your class list, and every element carries a 15-30 byte class string instead of 4 bytes.

The math works against utility classes at scale:

Total difference: 23 bytes per element x 15,000 elements = 345 KB. The numbered class system is literally lighter.

The better approach

Keep the numbered font classes. They exist because the PDF specified exact font metrics, and discarding that precision is a fidelity loss. Add ONE stable semantic class alongside them.

The pdf-paragraph class is that hook:

.pdf-doc .pdf-paragraph { margin: 0.5em 0; }

Tailwind users override it once in their config. Bootstrap users write a one-line override. Custom CSS users ignore it. The numbered classes stay for font precision. The semantic class provides the stable targeting that framework users need.

The output goes from this (utility approach, verbose): <p class="text-[12pt] font-['Times_New_Roman'] text-left">text</p> to this (hybrid approach, compact): <p class="f0 ta-l pdf-paragraph">text</p>. Same styling, less HTML, same hookability.

What you give up

You give up the self-documenting nature of utility classes. A developer reading <p class="f0"> cannot tell what font that is without looking up the CSS rule. This is a real readability cost. Mitigate it with good documentation in the CSS and by keeping the .fN numbering stable across re-extractions of the same document.

When the common pattern is right

If your extracted text uses a fixed set of 3-4 font sizes (common for simple invoices, receipts, or standardized forms), Tailwind's type scale covers them. Use utility classes directly. Skip the numbered class system. The hybrid approach pays off only when font diversity is high, which is exactly the case for most long-form PDF documents (government reports, academic papers, legal filings).

Read this post in the full Engineering Journal →