title: SVG transform origin differences in FireFox / Chrome
body: <p>Here is my character animation I was working on, which is working fine in Chrome but in FireFox it's kind of mess because FireFox has a different method of calculating transform origin related to the SVG canvas itself not to the group object.</p>
  
  <p><div class="snippet" data-lang="js" data-hide="true" data-console="false" data-babel="false">
  <div class="snippet-code snippet-currently-hidden">
  <pre class="snippet-code-css lang-css prettyprint-override"><code>.st0 {
    fill: #30363f;
  }
  .st1 {
    fill: #dba897;
  }
  .st2 {
    fill: #e2e2e2;
  }
  .st3 {
    fill: #1f2329;
  }
  .st4 {
    fill: #60562b;
  }
  .st5 {
    fill: #bf9286;
  }
  .st6 {
    fill: #251b1b;
  }
  .st7 {
    fill: #2d1c1c;
  }
  .st8 {
    fill: #fff;
  }
  .st9 {
    fill: #46ba7c;
  }
  .st10 {
    fill: #ccc;
  }
  svg {
    display: block;
    max-width: 400px;
    margin: auto;
  }
  g {
    -webkit-transition: all 0.5s ease-in-out;
    transition: all 0.5s ease-in-out;
  }
  #head {
    -webkit-transform-origin: 50% 100%;
    transform-origin: 50% 100%;
    -webkit-animation: head-rotate 10s infinite;
    animation: head-rotate 10s infinite;
  }
  #arm-l {
    -webkit-transform-origin: 80% 2%;
    transform-origin: 80% 2%;
    -webkit-animation: arm-anger 5s infinite;
    animation: arm-anger 5s infinite;
  }
  #hand-l {
    -webkit-transform-origin: 70% 12%;
    transform-origin: 70% 12%;
    -webkit-animation: hand-anger 5s infinite;
    animation: hand-anger 5s infinite;
  }
  #desk {
    -webkit-transform-origin: 50% 50%;
    transform-origin: 50% 50%;
    -webkit-animation: desk-anger 5s infinite;
    animation: desk-anger 5s infinite;
  }
  #eye-r,
  #eye-l {
    -webkit-transform-origin: 50% 50%;
    transform-origin: 50% 50%;
    -webkit-animation: eye-blinking 10s infinite;
    animation: eye-blinking 10s infinite;
  }
  #arm-r {
    -webkit-transform-origin: 30% 2%;
    transform-origin: 30% 2%;
  }
  #hand-r {
    -webkit-transform-origin: 30% 12%;
    transform-origin: 30% 12%;
  }
  @-webkit-keyframes head-rotate {
    0% {
      -webkit-transform: rotate(4deg);
      transform: rotate(4deg);
    }
    50% {
      -webkit-transform: rotate(-4deg);
      transform: rotate(-4deg);
    }
    100% {
      -webkit-transform: rotate(5deg);
      transform: rotate(5deg);
    }
  }
  @keyframes head-rotate {
    0% {
      -webkit-transform: rotate(4deg);
      transform: rotate(4deg);
    }
    50% {
      -webkit-transform: rotate(-4deg);
      transform: rotate(-4deg);
    }
    100% {
      -webkit-transform: rotate(5deg);
      transform: rotate(5deg);
    }
  }
  @-webkit-keyframes arm-anger {
    0% {
      -webkit-transform: rotate(0);
      transform: rotate(0);
    }
    5% {
      -webkit-transform: rotate(45deg);
      transform: rotate(45deg);
    }
    10% {
      -webkit-transform: rotate(10deg);
      transform: rotate(10deg);
    }
    15% {
      -webkit-transform: rotate(20deg);
      transform: rotate(20deg);
    }
    20% {
      -webkit-transform: rotate(0);
      transform: rotate(0);
    }
  }
  @keyframes arm-anger {
    0% {
      -webkit-transform: rotate(0);
      transform: rotate(0);
    }
    5% {
      -webkit-transform: rotate(45deg);
      transform: rotate(45deg);
    }
    10% {
      -webkit-transform: rotate(10deg);
      transform: rotate(10deg);
    }
    15% {
      -webkit-transform: rotate(20deg);
      transform: rotate(20deg);
    }
    20% {
      -webkit-transform: rotate(0);
      transform: rotate(0);
    }
  }
  @-webkit-keyframes hand-anger {
    0% {
      -webkit-transform: rotate(0);
      transform: rotate(0);
    }
    5% {
      -webkit-transform: rotate(50deg);
      transform: rotate(50deg);
    }
    10% {
      -webkit-transform: rotate(0deg);
      transform: rotate(0deg);
    }
    15% {
      -webkit-transform: rotate(30deg);
      transform: rotate(30deg);
    }
    20% {
      -webkit-transform: rotate(0);
      transform: rotate(0);
    }
  }
  @keyframes hand-anger {
    0% {
      -webkit-transform: rotate(0);
      transform: rotate(0);
    }
    5% {
      -webkit-transform: rotate(50deg);
      transform: rotate(50deg);
    }
    10% {
      -webkit-transform: rotate(0deg);
      transform: rotate(0deg);
    }
    15% {
      -webkit-transform: rotate(30deg);
      transform: rotate(30deg);
    }
    20% {
      -webkit-transform: rotate(0);
      transform: rotate(0);
    }
  }
  @-webkit-keyframes desk-anger {
    9% {
      -webkit-transform: rotate(0);
      transform: rotate(0);
    }
    10% {
      -webkit-transform: rotate(-2deg);
      transform: rotate(-2deg);
    }
    13% {
      -webkit-transform: rotate(1deg);
      transform: rotate(1deg);
    }
    15% {
      -webkit-transform: rotate(0deg);
      transform: rotate(0deg);
    }
  }
  @keyframes desk-anger {
    9% {
      -webkit-transform: rotate(0);
      transform: rotate(0);
    }
    10% {
      -webkit-transform: rotate(-2deg);
      transform: rotate(-2deg);
    }
    13% {
      -webkit-transform: rotate(1deg);
      transform: rotate(1deg);
    }
    15% {
      -webkit-transform: rotate(0deg);
      transform: rotate(0deg);
    }
  }
  @-webkit-keyframes eye-blinking {
    0% {
      -webkit-transform: scaleY(1);
      transform: scaleY(1);
    }
    1% {
      -webkit-transform: scaleY(0.1);
      transform: scaleY(0.1);
    }
    2% {
      -webkit-transform: scaleY(1);
      transform: scaleY(1);
    }
  }
  @keyframes eye-blinking {
    0% {
      -webkit-transform: scaleY(1);
      transform: scaleY(1);
    }
    1% {
      -webkit-transform: scaleY(0.1);
      transform: scaleY(0.1);
    }
    2% {
      -webkit-transform: scaleY(1);
      transform: scaleY(1);
    }
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;svg version="1.1" id="character_1" viewBox="0 0 1024 1024" preserveAspectRatio="xMinYMin meet"&gt;
    &lt;g id="body"&gt;
      &lt;g id="arm-r"&gt;
        &lt;path id="upperArm-r" class="st0" d="M582.7,804.3L582.7,804.3c-7.3,2.1-14.8-2-17-9.3l-24.2-82.9l26.3-7.7l24.2,82.9
     C594.1,794.5,590,802.1,582.7,804.3z" /&gt;
        &lt;g id="hand-r"&gt;
          &lt;path class="st1" d="M604.4,857.2l-1.9-6.6l-11.2,3.3l1.9,6.6c-3.8,3.4-5.6,8.8-4.1,14.1c2.1,7.3,9.7,11.4,17,9.3
      s11.4-9.7,9.3-17C613.8,861.7,609.4,858,604.4,857.2z" /&gt;
  
          &lt;rect x="584.1" y="847.1" transform="matrix(0.9598 -0.2806 0.2806 0.9598 -214.7713 201.5524)" class="st2" width="24.6" height="7.1" /&gt;
          &lt;path class="st0" d="M607.8,841l-26.3,7.7l-15.6-53.4c-2.1-7.3,2-14.8,9.3-17v0c7.3-2.1,14.8,2,17,9.3L607.8,841z" /&gt;
  
          &lt;rect x="578.9" y="839.8" transform="matrix(0.9598 -0.2806 0.2806 0.9598 -213.2036 200.8397)" class="st3" width="31.5" height="10.1" /&gt;
        &lt;/g&gt;
      &lt;/g&gt;
      &lt;g id="arm-l"&gt;
        &lt;path id="upperArm-l" class="st0" d="M441,804.3L441,804.3c7.3,2.1,14.8-2,17-9.3l24.2-82.9l-26.3-7.7l-24.2,82.9
     C429.6,794.5,433.8,802.1,441,804.3z" /&gt;
        &lt;g id="hand-l"&gt;
          &lt;path class="st1" d="M419.4,857.2l1.9-6.6l11.2,3.3l-1.9,6.6c3.8,3.4,5.6,8.8,4.1,14.1c-2.1,7.3-9.7,11.4-17,9.3
      c-7.3-2.1-11.4-9.7-9.3-17C409.9,861.7,414.3,858,419.4,857.2z" /&gt;
  
          &lt;rect x="415.1" y="847.1" transform="matrix(-0.9598 -0.2806 0.2806 -0.9598 598.7922 1787.1604)" class="st2" width="24.6" height="7.1" /&gt;
          &lt;path class="st0" d="M415.9,841l26.3,7.7l15.6-53.4c2.1-7.3-2-14.8-9.3-17l0,0c-7.3-2.1-14.8,2-17,9.3L415.9,841z" /&gt;
  
          &lt;rect x="413.3" y="839.8" transform="matrix(-0.9598 -0.2806 0.2806 -0.9598 603.7693 1776.2122)" class="st3" width="31.5" height="10.1" /&gt;
        &lt;/g&gt;
      &lt;/g&gt;
      &lt;g id="clothes"&gt;
        &lt;polygon class="st2" points="520.7,864.7 520.7,683.9 503.3,683.9 503.3,864.7 456.2,864.7 456.2,874.2 567.8,874.2 567.8,864.7
       " /&gt;
        &lt;path class="st3" d="M531.7,681.8c0,3.5-5.7,6.4-13.5,7.4c-1.9,0.3-4,0.4-6.1,0.4c-2.1,0-4.2-0.1-6.1-0.4c-7.9-1-13.5-4-13.5-7.4
     c0-4.3,8.8-7.8,19.7-7.8C522.9,674,531.7,677.5,531.7,681.8z" /&gt;
        &lt;ellipse class="st2" cx="512" cy="685.3" rx="13.4" ry="5.4" /&gt;
        &lt;path class="st0" d="M505.9,689.3c-7.9-1-13.5-4-13.5-7.4V693l-36.1,11.3v160.4h47V704.2h2.6V689.3z" /&gt;
        &lt;path class="st0" d="M531.7,693v-11.2c0,3.5-5.7,6.4-13.5,7.4v14.9h2.6v160.5h47V704.3L531.7,693z" /&gt;
        &lt;circle class="st4" cx="512" cy="751.9" r="1.8" /&gt;
        &lt;circle class="st4" cx="512.1" cy="722.5" r="1.8" /&gt;
        &lt;circle class="st4" cx="512" cy="781.3" r="1.8" /&gt;
        &lt;circle class="st4" cx="512" cy="810.7" r="1.8" /&gt;
        &lt;circle class="st4" cx="512" cy="840.1" r="1.8" /&gt;
        &lt;path class="st5" d="M500.2,664.4v18.8c0,2.6,5.3,4.7,11.8,4.7c6.5,0,11.8-2.1,11.8-4.7v-18.8H500.2z" /&gt;
      &lt;/g&gt;
    &lt;/g&gt;
    &lt;g id="head"&gt;
      &lt;path id="ear-r" class="st1" d="M638.2,511.8h-8.7v-76.4h8.7c9.8,0,17.7,7.9,17.7,17.7v41.1C655.8,503.9,647.9,511.8,638.2,511.8z" /&gt;
      &lt;path id="ear-l" class="st1" d="M385.8,511.8h8.7v-76.4h-8.7c-9.8,0-17.7,7.9-17.7,17.7v41.1C368.2,503.9,376.1,511.8,385.8,511.8z
    " /&gt;
      &lt;path id="face" class="st1" d="M386.5,316.8v255.9c0,5,1.5,9.9,4.3,14.1l58.7,72.5c7.8,9.6,19.5,15.2,31.9,15.2h61.3
    c12.4,0,24.1-5.6,31.9-15.2l58.7-72.5c2.8-4.2,4.3-9.1,4.3-14.1V316.8H386.5z" /&gt;
      &lt;polygon id="eyebrow-r" class="st6" points="595.2,463.9 521.3,480.2 591.1,451.2  " /&gt;
      &lt;g id="eye-r"&gt;
        &lt;circle class="st7" cx="558.3" cy="505.3" r="15.7" /&gt;
        &lt;circle class="st8" cx="551.1" cy="498.1" r="4.4" /&gt;
      &lt;/g&gt;
      &lt;polygon id="eyebrow-l" class="st6" points="437.8,441.2 502.5,480.2 431.9,453.2  " /&gt;
      &lt;g id="eye-l"&gt;
        &lt;circle class="st7" cx="465.7" cy="505.3" r="15.7" /&gt;
        &lt;circle class="st8" cx="457.9" cy="497.4" r="3.8" /&gt;
      &lt;/g&gt;
      &lt;path id="hair" class="st6" d="M625.8,293.2c-4.1-0.3-7.9,1.5-10.3,4.3c-1.6,1.8-4.5,1.9-6.1,0c-2.3-2.7-5.7-4.4-9.5-4.4
    s-7.2,1.7-9.5,4.4c-1.6,1.8-4.5,1.8-6,0c-2.3-2.7-5.7-4.4-9.5-4.4c-3.8,0-7.2,1.7-9.5,4.4c-1.6,1.8-4.5,1.8-6,0
    c-2.3-2.7-5.7-4.4-9.5-4.4s-7.2,1.7-9.5,4.4c-1.6,1.8-4.5,1.8-6,0c-2.3-2.7-5.7-4.4-9.5-4.4s-7.2,1.7-9.5,4.4c-1.6,1.8-4.5,1.8-6,0
    c-2.3-2.7-5.7-4.4-9.5-4.4c-3.8,0-7.2,1.7-9.5,4.4c-1.6,1.8-4.5,1.8-6,0c-2.3-2.7-5.7-4.4-9.5-4.4c-3.8,0-7.2,1.7-9.5,4.4
    c-1.6,1.8-4.5,1.8-6,0c-2.3-2.7-5.7-4.4-9.5-4.4s-7.2,1.7-9.5,4.4c-1.6,1.8-4.5,1.8-6,0c-2.3-2.7-5.7-4.4-9.5-4.4s-7.2,1.7-9.5,4.4
    c-1.6,1.8-4.5,1.8-6.1,0c-2.5-2.9-6.2-4.6-10.3-4.3c-6.7,0.4-11.7,6.3-11.7,13v1.5v7.6v35.3v83.7V476H399v-41.8l12.6-12.6v-67.3
    c0-2.1,1.7-3.8,3.8-3.8h193.2c2.1,0,3.8,1.7,3.8,3.8v67.3l12.6,12.6V476h12.6v-41.8v-83.7v-35.3v-7.6v-1.5
    C637.5,299.5,632.5,293.6,625.8,293.2z" /&gt;
      &lt;polygon id="mouth" class="st8" points="460.1,600.5 562.6,601 563.9,578 461.7,592.5  " /&gt;
    &lt;/g&gt;
    &lt;rect id="desk" x="166" y="867.8" class="st9" width="692" height="25.8" /&gt;
    &lt;g id="laptop"&gt;
      &lt;polygon class="st10" points="627.6,738.7 396.4,738.7 402.4,873.3 621.6,873.3   " /&gt;
      &lt;circle class="st8" cx="510.4" cy="811.4" r="22.2" /&gt;
    &lt;/g&gt;
  &lt;/svg&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>Here is the question is there is a way that i can make FireFox behave like Chrome or reverse Chrome act like FireFox so my animation can run on cross browsers.</p>