Limitations
Browser support
Transitions run in any browser with WebGL. How VFX-JS captures the content depends on the browser.
With HTML-in-Canvas
The browser draws the element into the canvas itself, with drawElementImage, so the capture matches the page. HTML-in-Canvas is still experimental: it is in Chrome Canary, or in Chrome with chrome://flags/#canvas-draw-element on.
Without it
Safari, Firefox and Chrome by default use dom-to-canvas. VFX-JS clones the element, copies its computed styles onto the clone, and draws the clone as an SVG image. This is a workaround, and it can't match the page exactly. Some content doesn't make it into the capture:
::beforeand::after. The clone has no stylesheets.- Web fonts and CSS background images. An SVG image can't load other files, so text falls back to a local font.
- Cross-origin images served without CORS.
- The content of
<canvas>,<video>and<iframe>. - Content inside shadow roots.
The SVG renderer can also draw some CSS differently from the page. Safari, for example, draws box-shadow wrong in the capture. These gaps show only during a run; the page itself is plain DOM before and after.
Reduced motion
VFX-JS doesn't check prefers-reduced-motion. Set duration to 0 to cut without animation.
const reduce = matchMedia("(prefers-reduced-motion: reduce)").matches;
const t = vfx.addTransition(el, {
transition: Swipe,
duration: reduce ? 0 : 0.6,
});Other limits
Nested VFX elements freeze
VFX elements inside the container stop during a run and show their plain content.
<body> can't be the target
Target the router outlet instead, like <main>.
Size changes aren't animated
If the new content has a different size, the box stays at the old size during the run and jumps afterwards.
One pending click spec per page
All <VFXTransition>s on the page share it.
autoReverse needs the Navigation API
Without navigation.currentEntry, back plays like any other navigation, with no reverse. After a reload or in a new tab, no spec is stored yet, so the first back plays its own spec too.
On back, the stored spec wins
With autoReverse, back plays the spec that entered the page, even after setNextTransition().
Reduced motion cuts
With prefers-reduced-motion: reduce, every run cuts to the new content.
Browser swipes cut
A phone animates a swipe back or forward on its own. The run then cuts to the new page instead of playing a second animation. Browsers without hasUAVisualTransition play it as usual.
No multi-page navigation
Cross-document navigation isn't supported. With Turbo or htmx, call core run(cb) by hand.