Limitations
PdfPecker is built for fast conversion of HTML templates you control, not for rendering arbitrary web pages. These are the known gaps; most are scope choices for speed and size, and they are the first candidates for future work. Anything not listed in What is supported should be assumed missing; CSS support marks every CSS property one by one. The PDF feature checklist marks every PDF feature as supported, partly supported or missing.
By design
- No JavaScript. Scripts are never run, so content must be in the HTML before conversion (render it server-side first).
- No network access:
http:/https:stylesheets and images are not downloaded. Supply them through yourResourceResolver, as files underBaseDirectory, or asdata:URIs. <canvas>,<iframe>,<video>,<audio>,<object>and<embed>are not drawn, nor are file, range, colour and image inputs. Form fields have no JavaScript (no calculations, formats or submit actions), and a field inside a transformed box, a running header or footer, or aposition: fixedbox is drawn but not fillable.
Text and fonts
- Without registered fonts or
EmbedStandardFonts, text uses the standard PDF fonts, so characters are limited to the Windows-1252 set (Western European languages) plus what the built-in fallback fonts add: Central European, Greek and Cyrillic letters and common symbols. They have no CJK or other scripts, and no emoji: register fonts for those. - Complex-script shaping covers Arabic and Hebrew (and other scripts written with Arabic letters, such as Persian and Urdu), nine Indic scripts, Thai and Lao. Khmer, Myanmar, Sinhala, Tibetan, Mongolian, Javanese, Adlam and Syriac are not shaped, so their vowel signs and conjuncts come out wrong. Thai and Lao text breaks only at spaces, since there is no dictionary for word breaks.
- Vertical text is drawn as turned horizontal text: Chinese and Japanese characters
are turned rather than upright (
text-orientationandtext-combine-uprightare not supported),vertical-lrstacks several lines right to left, a box nested inside a vertical box takes its width as its height, and a verticalhtmlorbodyis laid out horizontally.viandvbstay the page width and height in vertical boxes (Chrome swaps them), andinitial-lettermakes no drop cap in a vertical box. - CJK punctuation trimming does not use the vertical
vhalfeature, and thetext-spacingshorthand is not read.text-emphasismarks andhanging-punctuationare not supported. - In Latin and other simple scripts, shaping is limited to kerning, standard ligatures and features that swap one
glyph for another (see OpenType features) and fractions; contextual alternates
(
calt) and ordinals are not applied, andsmall-capsis synthesized from scaled capitals when the font has no small capitals of its own.font-variant-alternatesandfont-palette(colour font palettes) are not supported. - Solid underlines, overlines and line-throughs are a little thinner than Chrome's (about 1.5 px for 20 px text where
Chrome draws 2 px), and a solid overline sits about a pixel lower; dashed, dotted, double and wavy lines match Chrome.
text-decorationon SVG text is always a solid line in the text's fill, and is not drawn ontextPathtext. - Automatic hyphenation (
hyphens: auto) has built-in patterns for English, Danish, German, Dutch, Norwegian, Swedish, Spanish, French, Italian, Portuguese and Polish; other languages need their patterns inPdfOptions.Hyphenation. - SVG
<text>uses only the first value of position lists; in a text chunk with right-to-left text,dxon itstspans is ignored.
CSS
- Container queries: no
scroll-state()queries,style()works only on custom properties, and style containment (counter scoping) and thecontainproperty are not implemented. A document with container queries takes about two to four times as long to lay out, and queries that keep changing the layout stop after six passes. In running headers and footers,@pagemargin boxes and SVG images, thecqunits fall back to viewport units. - Footnotes:
@footnoteinside@page :first,:leftor:rightis ignored,footnote-policy: blockacts likeline, andfootnote-display: compactis always inline. A note split across pages does not carry its background or border onto the next page, and margins between block notes do not collapse. - When
@page :first,:leftor:rightgive pages different widths, floats, inline-blocks, flex, grid and multi-column containers, and boxes with transforms or filters keep the width of the page they start on (Chrome re-sizes floats, inline-blocks and multi-column per page). A named page's:firstis the document's first page, as in Chrome, not the first page of the named run. - Selectors: a rule with an unsupported selector is skipped. A complex selector may have at most 64 compound parts and
16 levels of nesting, and
:has()cannot contain:has(). - Blurred text shadows are drawn as images at 144 dpi (down to 72 dpi for wide blurs, with the blur capped at about
200px), so shadowing long body text adds to the file size; the shadow of an underline is painted under the glyphs
rather than between them and their own underline.
filter: blur()anddrop-shadow()draw the box as an image; its text stays selectable, and the colour filters keep everything as vectors. text-overflowapplies only at the end of the line, as in the spec and Chrome.inline-size,block-sizeand theirmin-andmax-forms always mean width and height, also in vertical writing modes; the logical margins, paddings, insets and borders do followwriting-mode.- Percentage heights still count as
autoin a flexed item of a container that has only amin-height, against a table row's height on its own or a rowspanning cell, and in footnotes and running headers and footers. When pages differ in size, a box resolves its percentage height against the page it starts on and keeps that height if it breaks onto a page of another height (Chrome recomputes it there). background-attachment: fixedscrolls with the box, since paper has no scrolling viewport.- Not supported:
contain,content-visibility,cross-fade(),element(),paint(),env(),anchor(),attr()outsidecontent,::selectionand:nth-col(). In@pagemargins and media queries,ex,chand the other font units use the initial 16 px font. - 3D transforms are drawn flat, since a PDF page has only flat transforms: a box with
a perspective stays a rectangle or parallelogram where Chrome draws a trapezoid, only the parent's
perspectivecounts, and nestedpreserve-3dscenes, such as a cube, do not come out the way a screen shows them. backdrop-filterdraws what is behind the box as a 144 dpi image, up to 64 per document. A mask with more than 16 layers is ignored, andmask-clip: no-clip,stroke-boxandview-boxact asborder-box.- Float shapes: an SVG image in
shape-outsidefalls back to the margin box, and image and path shapes are measured at 1 px per CSS pixel, up to 4 million pixels and ashape-marginof 1,024 px (beyond that the float keeps its rectangle). text-wrap: balanceandprettydo not apply beside floats, with::first-line, or on pages of different widths.display: contents: a link to theidof such an element finds no place on the page when its children are blocks, and in a tagged PDF the wrapper's own tag (a list or link around blocks) is left out; its children are tagged.- Gradient stops that fade to transparent are mixed in unpremultiplied colours, so the middle of such a gradient is a little greyer than in Chrome.
- A document without a doctype is laid out in standards mode; Chrome uses quirks mode for it, which, among other things, ignores the first paragraph's top margin in the body.
Backgrounds and transparency
- Inset box shadows of inline elements (
<span>) are not drawn.box-decoration-breakapplies to inline elements, not to blocks split across pages or columns. - Inline boxes nested more than 16 deep are not decorated, and one layout paints at most 50,000 inline box fragments with a shared budget for their layers, shadows and outlines; past it, fragments show only their background colour.
- A translucent box shadow without blur is blended onto white rather than truly see-through. Blurs are drawn as bands, so very wide blurs may show faint steps when zoomed in.
Layout
- Subgrid: percentage gaps, margins and padding on a subgrid resolve against the parent
grid's width rather than the subgrid's area; subgrid items are not baseline-aligned with the parent's items; and only
the horizontal
writing-modeis supported. - Multi-column:
column-span: allworks only on direct children of the multi-column box, and multi-column boxes nested more than two levels deep keep their children whole instead of splitting them. Footnotes inside columns are placed at their call and do not reserve space at the bottom of the column, orphans and widows are not applied to lines beside floats, and content that overflows a fixed-height multi-column box withoverflow: hiddenis clipped from view but stays in the PDF's text. - Overflow: a positioned child with a
z-indexinside a clipping box stays stacked within that box. - Collapsed table borders on
colandcolgroupare not drawn; borders on cells, rows, row groups and the table are.
Images and SVG
- No AVIF images: decoding them needs an AV1 video decoder, which is not planned. Convert them to WebP, PNG or JPEG.
- SVG filters are applied in pixels at 144 dpi, so filtered shapes become an image (text keeps an invisible, selectable copy).
- A missing image with alt text shows the text without Chrome's small broken-image icon, and a missing image without alt text or a size has no box rather than Chrome's 16 px icon box.
- An SVG
symbolis not clipped to its viewport, and itspreserveAspectRatiois always the default (xMidYMid meet).
Reading and changing existing PDFs
- Text extraction reads columns that sit side by side across, line by line, rather than one
column after the other, and it does not use the structure tree of a tagged PDF to find the reading order. Text drawn
only as outlines or images is not extracted; there is no OCR. Indic vowel signs drawn before their consonant come
out in that visual order unless the PDF carries
/ActualText. - PDF to HTML keeps the PDF's layout: the page is an image and the text an invisible layer over it, so the HTML does not reflow into paragraphs and tables, text zooms as an image does, and what text extraction cannot read (outlines, scans) cannot be selected either.
- Form filling does not shape text, so values in Arabic, Hebrew, Devanagari and other scripts that need shaping are stored but not drawn correctly. XFA forms are not filled: their XFA data is removed and the AcroForm fields are filled instead. Field JavaScript (calculations, formats) is not run.
- Signature verification checks the changes made after a
certification signature against its level, but not field locks
(FieldMDP), so after an approval signature it counts the updates but cannot tell an allowed form fill from a changed
page. Revocation is checked only when
RevocationModeasks the platform to, not from the OCSP responses and CRLs stored in the PDF.
Markdown and the PDF renderer
- Markdown: no math. Definition list terms are one line each (no several terms for one definition), and
~does not start a definition. A footnote's text cannot hold another page-bottom footnote: a reference inside a footnote links to its note, and a note that only other notes reference is listed after the text. PdfRenderer(PDF to image): no predefined CJK CMaps or non-embedded CJK fonts, and ICC profiles are not applied (ICC-based colours use their device equivalents). WebP output is lossless only (no lossy VP8), and JPEG output is baseline only (no progressive or arithmetic coding).