Web

SVG AnimateMotion Fails in Firefox But Works in Chrome Fix

Fix SVG animation where animateMotion with mpath and stroke-dashoffset mask works in Chrome but airplane stays static in Firefox. Nest animation inside element, use SMIL for mask, ensure cross-browser SVG path motion compatibility with code examples.

1 answer 2 views

SVG animateMotion animation works in Chrome but not in Firefox: airplane stays static

An SVG animation featuring an airplane moving along a custom path using <animateMotion> with <mpath>, combined with a mask featuring animated stroke-dashoffset, functions correctly in Google Chrome. However, in Mozilla Firefox, the airplane element remains completely static and does not move.

Key SVG Elements:

  • Motion path: <path id="motionPath">
  • Airplane: <g id="circle"> (initially translated to path start position)
  • Animation: <animateMotion xlink:href="#circle" dur="6s" ...><mpath xlink:href="#motionPath"/></animateMotion>
  • Mask: <mask id="mymask"> with <path> animating stroke-dashoffset from 6289 to 0 over 18.1s

What causes this browser incompatibility, and how can it be fixed to ensure cross-browser compatibility, particularly in Firefox?

Your SVG animation with <animateMotion> and <mpath> moves the airplane smoothly along the custom SVG path in Chrome, but stalls completely in Firefox due to the browser’s strict enforcement of SMIL rules—it demands that <animateMotion> be a direct child of the target element like your <g id="circle">, not referenced via xlink:href. The animated SVG mask using stroke-dashoffset exacerbates this, as Firefox handles CSS animations on masks poorly or not at all. Fixing it means restructuring: nest the animation inside the airplane group, update to modern href, and swap the mask’s CSS to SMIL <animate> for reliable cross-browser SVG animation.


Contents


Why SVG Animation with animateMotion Fails in Firefox

Ever built what looks like a perfect SVG animation—airplane gliding along a wavy path—only to watch it freeze in Firefox? You’re not alone. The culprit here is Firefox’s pickiness with SMIL (Synchronized Multimedia Integration Language), the spec behind <animateMotion>. Chrome plays loose, letting you point to your airplane <g id="circle"> externally with xlink:href="#circle". Firefox? No dice. It insists the animation lives inside the element it’s moving.

Take your setup: an external <animateMotion xlink:href="#circle" dur="6s"><mpath xlink:href="#motionPath"/></animateMotion>. In this Stack Overflow thread, devs nailed it—Firefox rejects external targeting outright, especially with masks in play. And that Mozilla Bugzilla report confirms it: combine <mpath>, motion, and a mask? Expect silence. Why the difference? Chrome bends for developer convenience; Firefox sticks to the SMIL spec like glue, treating violations as non-starters.

But here’s the kicker—your initial translate on the airplane to the path start? Smart, but irrelevant once the motion fails to kick in.


Core Issues: SVG Path, mpath, and SVG Mask in Chrome vs Firefox

Dig deeper, and two villains emerge: the SVG path reference via <mpath> and your #mymask with its marathon stroke-dashoffset from 6289 to 0 over 18.1 seconds.

First, <mpath xlink:href="#motionPath">. It’s deprecated syntax—MDN docs push href now, sans xlink:. Firefox (since version 70) supports it fine if the parent <animateMotion> is properly nested. External? Crickets. Chrome forgives this sloppiness.

Then the SVG mask. Your <mask id="mymask"> likely uses CSS @keyframes for the dash animation. Firefox chokes on CSS animations applied to mask contents—another Stack Overflow case spells it out. Historical bugs like Bugzilla 1118710 show masks have long been finicky there. Result? Airplane vanishes or stays put, even if motion half-works.

Browser External animateMotion mpath href CSS on Mask
Chrome ✅ Forgiving ✅ Works ✅ Smooth
Firefox ❌ Strict reject ⚠️ Nested only ❌ Often fails

Short paths? Fine. Yours, with a hefty dash length? Amplifies rendering strain.


Making SVG Animation Compatible: Nest animateMotion Inside the Element

Ready to fix it? Step one: drag that <animateMotion> inside your <g id="circle">. No more xlink:href="#circle"—it’s now self-contained.

Here’s the before-and-after. Original (broken in Firefox):

svg
<animateMotion xlink:href="#circle" dur="6s" repeatCount="indefinite">
 <mpath xlink:href="#motionPath"/>
</animateMotion>
<g id="circle" transform="translate(...path start...)">
 <!-- airplane paths -->
</g>

Fixed version:

svg
<g id="circle" transform="translate(...path start...)">
 <animateMotion dur="6s" repeatCount="indefinite">
 <mpath href="#motionPath"/> <!-- Modern href, no xlink: -->
 </animateMotion>
 <!-- airplane paths -->
</g>

Test this in CodePen—bam, airplane flies in both browsers. That Stack Overflow fix proves it works, and MDN backs the href shift. Add xmlns="http://www.w3.org/2000/svg" if missing, though modern browsers infer it.

What if your path curves wildly? Tweak calcMode="spline" or keySplines—but start simple, as this edge case warns Firefox nitpicks splines on complex paths.


Fixing SVG Mask Animation: Ditch CSS for SMIL stroke-dashoffset

Your mask’s the other headache. CSS stroke-dashoffset animation? Chrome loves it. Firefox? Spotty at best. Switch to SMIL <animate>—native, reliable, and spec-compliant.

Assume your mask path looks like:

svg
<mask id="mymask">
 <path d="..." stroke="white" stroke-width="10" stroke-dasharray="6289" fill="none">
 <animate attributeName="stroke-dashoffset" from="6289" to="0" dur="18.1s" repeatCount="indefinite"/>
 </path>
</mask>

Nest that <animate> right inside the <path>. No CSS needed. Why? Developers report Firefox skips SVG2 mask anims but honors SMIL. Dasharray stays static; animate just the offset. Pro tip: compute dasharray precisely—getTotalLength() in JS if dynamic.

Apply the mask via mask="url(#mymask)" on your airplane group or defs. Now? Reveal effect syncs with motion, cross-browser.

And yeah, it feels clunky ditching CSS. But for SVG animation reliability? Worth it.


Alternatives: SVG Animation Examples with clipPath and Values

Hate SMIL fiddling? Ditch <mpath> entirely. Use values on <animateMotion> to approximate your path with points.

Example from Firefox <use> woes:

svg
<g id="circle">
 <animateMotion dur="6s" values="0,0; 100,50; 200,0; 300,100; 0,0" keyTimes="0;0.25;0.5;0.75;1" repeatCount="indefinite"/>
 <!-- airplane -->
</g>

Plot your #motionPath points via tools like SVG path editors. Less precise on curves, but no mpath dependency.

Or swap mask for <clipPath>—vector clips sans stroke tricks:

svg
<clipPath id="myclip">
 <path d="..." clip-rule="evenodd">
 <!-- Animate path 'd' or transform -->
 </clipPath>

Chrome and Firefox both eat this up. For fancier stuff, GSAP or SVG.js libraries bridge gaps without browser roulette.


Testing and Best Practices for SVG Animation

Polish it off: Test in latest Chrome/Firefox (as of 2026, FF132+ handles this solid). Use BrowserStack or LambdaTest for cross-version checks. Declare viewBox properly—scales matter.

Best practices?

  • Always nest animations.
  • Prefer href over xlink:href.
  • SMIL over CSS for masks/paths.
  • Compress paths—long dasharrays lag.
  • Fallback: CSS @property for custom props if SVG2 lands everywhere.

Tools like SVGOMG minify; CodePen validates live. Intrigued by AI-generated paths? Plugins exist, but hand-tune for browsers.


Sources

  1. animateMotion path not working in Firefox — Core fix by nesting animation as child element: https://stackoverflow.com/questions/64112109/animatemotion-path-not-working-in-firefox
  2. Firefox Bug 1682307 — Official report on animateMotion + mpath + mask failure: https://bugzilla.mozilla.org/show_bug.cgi?id=1682307
  3. MDN Web Docs: — Syntax guide with href deprecation and nesting rules: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/mpath
  4. How to apply CSS animation to SVG mask in Firefox — SMIL workaround for stroke-dashoffset on masks: https://stackoverflow.com/questions/55592947/how-to-apply-css-animation-to-a-svg-mask-in-firefox
  5. Animated SVG mask doesn’t work in Firefox — Confirmation of SMIL preference over CSS: https://stackoverflow.com/questions/44224928/animated-svg-mask-doesnt-work-in-firefox
  6. SVG animateMotion using keySplines not working in Firefox — Edge cases for complex paths: https://stackoverflow.com/questions/76592414/svg-animatemotion-using-keysplines-not-working-in-firefox

Conclusion

Nail cross-browser SVG animation by nesting <animateMotion> inside your airplane <g>, swapping to href="#motionPath", and converting the SVG mask’s stroke-dashoffset to SMIL <animate>. This sidesteps Firefox’s SMIL rigidity and mask quirks while keeping Chrome happy—no more static planes. Experiment in a live editor, tweak dur for polish, and you’ve got a robust, scalable solution that ages well.

Authors
Verified by moderation
NeuroAnswers
Moderation
SVG AnimateMotion Fails in Firefox But Works in Chrome Fix