Text & fonts
Path-mode glyphs, run-based shaping, every common script — with a few caveats.
For the design rationale (path mode, run-based shaping, decoration metrics) see Text rendering. The Fonts & non-Latin scripts guide covers practical font choices.
Standard CSS typography round-trips: font-size,
font-weight (100–900), font-style: italic,
letter-spacing (captured per character so subpixel offsets land
correctly), word-spacing, line-height,
text-align: left / right / center / start / end, all the
word-wrap properties (overflow-wrap, word-break,
hyphens) since the visual line breaks Chromium chose are
captured directly, and white-space: pre / pre-wrap
/ nowrap. Underline, line-through, and overline use the font's
post.underlinePosition / OS/2.yStrikeoutPosition
tables to match Chromium exactly, and text-decoration-color /
-style / -thickness all flow through.
Pseudo-elements: ::before / ::after (captured as
text segments with per-pseudo color / size / weight; content: url(...)
honored), ::first-letter drop caps (rasterized when
font-size differs), ::first-line,
::placeholder (color / font-style / font-weight applied to
placeholder text), and ::marker all work.
Scripts: Latin, Cyrillic, Greek, Arabic with contextual forms and ligatures (run-based shaping plus bidi-js paired-bracket mirroring), Hebrew with niqqud, Devanagari with cluster reordering preserved, Thai with mark-on-base positioning, CJK (Han, Hiragana, Katakana, Hangul) with GPOS positioning, and other complex scripts (Tibetan, Khmer, Burmese) via the same fallback-run pipeline (not in the regression suite, but the mechanism is the same).
The exceptions
text-align: justify— text is left-aligned in the SVG output (no inter-word stretching). Warning logged.- Wavy underline (
text-decoration-style: wavy) — falls back to a straight line. Warning logged. - Web fonts not in the bundled mapping — capture works,
but path-mode glyph rendering needs the font file to be discoverable in
the host system; otherwise the renderer falls back to
<text>elements that depend on the consumer's font cache. Either switch to a system-installed font for the demo or accept the cross-engine font differences. - Variable font axes other than weight — the weight axis works for variable SF Pro; other axes interpolate to the nearest static instance.
- Emoji and color-bitmap glyphs — embedded as base64 PNGs (deduped per glyph). Vector emoji fonts (e.g. COLRv1) collapse to bitmap.
::selection— captures don't include user selection state.
Common pitfalls
- Web font not loaded yet. Always
await page.evaluate(() => document.fonts.ready)before capturing. Without it you'll capture the fallback typeface and the layout will shift the next time you render.