atelier

Catalog / Technique

Compatibility

Use before any recipe is written, and before one is marked passed: what every recipe owes every browser. Covers the three engines (Chrome and Edge, Safari, Firefox) and what each lacks today, the rest state, the second engine a recipe carries where one exists, feature tests in script, the needs readout, and what is run by hand before a recipe is passed.

Loads as
technique-compatibility
Written for
An agent, to follow

Compatibility

One sentence: a recipe is judged in the browser the reader has, not the one it was built in. Every recipe rests at the page as laid out, carries a second engine where the platform has one, says what it could not do, and is run by hand in the three engines before it is passed.

When to use

  • Before a recipe is written: which features it rests on, in which engine each is missing, and what the recipe does there.
  • Before a recipe is marked passed: it was looked at in Chrome, in Firefox and in Safari, and did the right thing in each.
  • When the owner reports “it does not work”: the first question is which browser, and the bench’s readout under the stage answers it.

Do not use it to argue a feature out of the lab. A feature one engine lacks is used, with a fallback; what is refused is a recipe that works in one engine and breaks the page in another.

Rules

  1. Feature-test in script, at mount, once per recipe. typeof, 'x' in, CSS.supports. Never a user-agent string. The stage overrides matchMedia to preview reduced motion, and a decision made in CSS cannot see that, so motion is decided in script too.
  2. The rest state is the page as laid out. Nothing a recipe adds is needed for the page to be read, and nothing it hides stays hidden when it cannot run. The failure path is the rest state, in every engine.
  3. Carry a second engine where the platform has one. The same effect done another way, chosen by the feature test, in the same file. Today’s pairs: cross-document view transitions, or a fetched page swapped in under a same-document one (page-morph); view timelines, or the same keyframes scrubbed by script on scroll (mask-settle); a shader lid, or a CSS treatment (shader-lift and dither-lift, two recipes for one idea). A second engine is the effect, not an apology for it.
  4. The second engine is honest about its cost. A swap is a small router and runs the new body’s inline scripts only; a scrub by script is on the main thread. The doc says so.
  5. The bench says what the browser lacks. demo.ts lists needs, the stage reports what it has, and the readout under the stage says in one line why a recipe is quiet. A recipe with a second engine lists the floor it rests on, not the feature it prefers.
  6. Never add crossorigin, never depend on an API newer than the feature it serves. navigation.activation arrived in Safari after cross-document transitions did; PageSwapEvent.activation and the clicked link serve instead.
  7. A Chromium-only feature is an enhancement by feature test, never a foundation: scroll-triggered animations, nested transition groups, element-scoped transitions, generated carousel controls, WebGPU.
  8. Firefox and Safari are run by hand. Headless Chrome drives every check; the other two engines are not on the check’s machine. Nothing is marked passed until both have been looked at once, and the recipe’s doc records what was seen.
  9. Write down the day. Support changes month to month (Firefox shipped scroll-driven animations in 159 three weeks after the research said it had not). Every claim here carries its date.

Decisions

Question Choose Because
Firefox has no cross-document transitions: wait, or swap? Swap, inside the recipe The owner asked for every recipe to work in Firefox; the swap is the same effect by the engine Firefox has, bounded to inline scripts
Firefox has no view timelines before 159: wait, or scrub by script? Scrub by script The same move, on the main thread, until 159 lands; the feature test picks the timeline where it exists
No WebGL2: a CSS engine, or nothing? A CSS recipe beside the shader one where the idea allows it dither-lift beside shader-lift; a contour field has no CSS twin and rests at the page
Detect by user agent? Never A feature test is true the day the feature ships
How is a missing feature reported? The bench’s readout, in words Said quietly it was read past, and a recipe that could not run was taken for one that was broken

Tuning

Dial Start Range One end The other
Where the feature test runs At mount Mount, or at each use A decision made once A feature that arrives later is noticed
What the swap runs of a new body Inline classic scripts None, to everything Stale page state A router

Rest state

The page as laid out. The same in every engine, under reduced motion, without script, and when a feature test fails.

Cost

  • To build: a second engine is most of a recipe’s size where it exists (page-morph carries about a kilobyte for the swap).
  • To run: a fallback engine is usually the costlier one, on the main thread or over the network; the preferred engine is chosen wherever it exists.
  • To the reader: nothing, which is the point.

Checklist

  • Every feature the recipe rests on has a test in script, and the recipe’s doc says what happens without it.
  • demo.ts lists needs as the floor the recipe rests on.
  • npm run check:browser exercises the second engine where one exists, by taking the preferred feature away in Chrome.
  • Looked at in Firefox and in Safari by hand, and what was seen is in the doc, before passed.
  • Support claims carry their date.

Recipes

  • page-morph: cross-document transitions, or a fetched page swapped in under a same-document one.
  • mask-settle: a view timeline, or the same keyframes scrubbed by script.
  • shader-lift: the shader engine of an idea whose CSS engine is dither-lift.
  • dither-lift: the CSS engine, which needs no WebGL.

Sources

  • bcd-view-transition-at-rule: cross-document view transitions in Chrome 126 and Safari 18.2, not in Firefox
  • webdev-vt-baseline: same-document view transitions in every engine
  • bugzilla-2020327: Firefox parses the at-rule and does not run the transition, as of May 2026
  • bugzilla-1324602: Firefox ships scroll-driven animations in 159, due 2026-10-27
  • bcd-animation-timeline: support for scroll-driven animations
  • bcd-files-2026-10-06: the engine versions behind every claim here, read on that day
  • webdev-interop-2026: what the engines have agreed to converge on this year
  • mdn-firefox-experimental: what Firefox keeps behind a preference
  • wcag-animation-from-interactions: motion from interaction must be possible to switch off, in every engine