Domotion

CSS support overview

Modern HTML and CSS round-trip faithfully — these are the exceptions.

Domotion's goal is sub-3% pixel-diff fidelity against Chromium on the host platform. Treat that as the default: anything in modern HTML and CSS that Chromium paints, Domotion captures and re-emits as native SVG primitives. The per-area pages in this section exist for the few features that have caveats or aren't yet covered.

The exceptions, by area

Click through for the details and any workarounds.

  • Layoutposition: fixed and sticky render at the captured position with no scroll-following (the SVG is one static frame). Native scrollbar chrome on overflow: scroll / auto isn't drawn yet — the visible scroll region renders correctly.
  • Colors & backgrounds — output is sRGB; widely-separated stops in OKLCH-interpolated gradients drift slightly. background-image: url(...) embeds inlined PNG / JPEG / GIF / WebP / AVIF / SVG; other formats pass through with their original URL.
  • Gradientsconic-gradient has no SVG equivalent and is skipped (warning logged). Linear, radial, and both repeating-* variants are full-fidelity.
  • Borders & effectsborder-image is not yet implemented. backdrop-filter has no SVG equivalent in <img>-rendered SVG. clip-path: path() isn't emitted yet (warning logged); mask is captured but not yet emitted.
  • Transforms — currently the largest gap. Only translate round-trips faithfully; rotate, scale, skew, matrix, and 3D transforms render as the un-transformed bounding box. Workarounds on the page.
  • Text & fontstext-align: justify doesn't space-stretch (left-aligned in the output, warning logged). Wavy underline falls back to a straight line. Web fonts that aren't in the bundled mapping fall back to <text> instead of path-mode glyphs. ::selection isn't captured.
  • Writing mode — RTL (Arabic, Hebrew, etc.) is fully supported. Vertical writing modes (vertical-rl / vertical-lr / sideways-*) currently render as horizontal (warning logged); rasterized fallback is on the roadmap.
  • Form controls<input type=file> renders the button chrome only. Bare <button> / <select> with no author CSS only partially synthesizes the UA chrome. Open <select> dropdowns can't be captured (they live in OS chrome). <textarea> content is rasterized for pixel-perfect Chromium word-wrap.

Out of scope

These aren't bugs — they're outside what a static SVG snapshot can reasonably represent:

  • <canvas>, <video>, <iframe>, <object>, <embed> — bodies aren't rendered (warning logged). Capture a poster frame or screenshot instead.
  • CSS animations and transitions — Domotion captures one static frame. Multi-frame animation is composed at a higher layer (generateAnimatedSvg).
  • @page rules — print-media only.
  • Live focus / hover / selection state — set the desired state in Playwright before capturing.

Capture warnings

When a capture hits a feature that doesn't round-trip fully, Domotion records a structured warning so you can find what was skipped. Helpers are exported from the package root:

import { getLastCaptureWarnings, logCaptureWarnings } from "domotion";

logCaptureWarnings();                  // to stderr
const warnings = getLastCaptureWarnings(); // or programmatic

Each warning carries a selector (short ancestor-path identifier), a feature name, and a one-sentence detail. Warnings are deduped by (feature, selector) per capture.

Cross-platform note

Domotion targets pixel-faithful Chromium output on the host platform. Today the rendering pipeline is fully calibrated against Chromium-on-macOS (CoreText fallback chain). Linux (fontconfig — Noto / DejaVu / Liberation) and Windows (DirectWrite — Segoe UI / Consolas / Cambria Math / Yu Gothic) calibration is roadmap work; non-macOS captures will run but font fallback matching may diverge from Chromium until that's complete.