Anyone who has built an HTML/CSS sheet-label generator for 30-up Avery 5160 sheets or 4×6 direct-thermal shipping labels eventually hits vertical creep: row 1 aligns inside the die-cut border, while row 10 clips 3 millimeters below the perforation.

1. Why CSS Pixels Drift Across Operating Systems

Browser print engines rasterize or paginate DOM layouts through CSS reference pixels (1in = 96px) before handing the spool to the OS print dialog. Two silent mutations commonly ruin physical pitch accuracy:

  • Fit-to-Page Auto-Scaling: Chrome and Edge shrink printable boxes by 94%–97% whenever unprintable printer hardware margins intersect the CSS @page box.
  • Sub-Pixel Rounding Accumulation: An Avery 5160 cell is 2.625 in × 1.0 in with a horizontal pitch of 2.75 in. Rounding fractional CSS flex/grid tracks over 10 rows accumulates enough vertical error to cross the die-cut line.

2. Computing Directly in PostScript Vector Points (72 pt = 1 inch)

Generating native PDF streams client-side in WebAssembly/JavaScript bypasses DOM layout rounding completely. In the PDF coordinate system (origin at bottom-left), physical measurements convert deterministically:

const INCH_TO_PT = 72; const MM_TO_PT = 72 / 25.4; // Avery 5160 exact geometry on US Letter (612 x 792 pt) const topMarginPt = 0.5 * INCH_TO_PT; // 36 pt const leftMarginPt = 0.1875 * INCH_TO_PT; // 13.5 pt const colPitchPt = 2.75 * INCH_TO_PT; // 198 pt const rowPitchPt = 1.0 * INCH_TO_PT; // 72 pt 

3. Crisp Code 128 & EAN-13 Quiet Zones on 203 DPI Thermal Heads

Direct thermal printers (Zebra, Rollo, Dymo) print at 203 DPI (8 dots/mm). Rendering a barcode into a PNG canvas first introduces anti-aliased gray edge pixels that thermal printheads dither, causing handheld laser scanners to reject narrow bars. Emitting each Code 128 module as an unstroked filled PDF vector rectangle guarantees sharp 1-bit bar boundaries at any DPI.

For client-side CSV-to-PDF batch generation with zero cloud uploads, see the CSV and Excel barcode sheet builder on LabelQueue, or query exact template pitches programmatically via npx labelqueue-cli demo.