csssvgsvg-transforms

CSS transform Center out of balance?


I am trying to animyte a little SVG for my Hamburger Menu but I have a odd problem, where the transform origin is slightly out of center when using transform-origin: center center.

I made a little Fiddle to demonstrate: https://jsfiddle.net/mnicolas/8sdyg0ea/13/

svg{
  border: 1px solid black;
}

.wrap:hover svg #line1 {
  animation: one1 1s ease normal forwards;
}
.wrap:hover svg #line2 {
  animation: one2 1s ease normal forwards;
}


.wrap.b:hover svg #line1 {
  transform-origin: center center;
}
.wrap.b:hover svg #line2 {
  transform-origin: center center;
}


@keyframes one1 {
  50% {
    transform: translateY(15%);
  }
  100% {
    transform: translateY(15%) rotate(45deg);
  }
}
@keyframes one2 {
  50% {
    transform: translateY(-15%);
  }
  100% {
    transform: translateY(-15%) rotate(-45deg);
  }
}
<div class="wrap a">
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" viewbox="0 0 100 100">
  
  <line id="line1" x1="10" y1="35" x2="90" y2="35" stroke="black" stroke-width="10" stroke-linecap="round" />
  <line id="line2" x1="10" y1="65" x2="90" y2="65" stroke="black" stroke-width="10" stroke-linecap="round" />
  <circle cx="50" cy="50" r="3" fill="red"/>
  
</svg>
</div>

<hr>
<div class="wrap b">
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" viewbox="0 0 100 100">
  
  <line id="line1" x1="10" y1="35" x2="90" y2="35" stroke="black" stroke-width="10" stroke-linecap="round" />
  <line id="line2" x1="10" y1="65" x2="90" y2="65" stroke="black" stroke-width="10" stroke-linecap="round" />
  <circle cx="50" cy="50" r="3" fill="red"/>
  
</svg>
</div>

Does anyone know why this happens and how to fix it?

Tanks a lot!


Solution

  • Rotate then translate. The order matters

    svg{
      border: 1px solid black;
    }
    
    .wrap:hover svg #line1 {
      animation: one1 1s ease normal forwards;
    }
    .wrap:hover svg #line2 {
      animation: one2 1s ease normal forwards;
    }
    
    
     svg #line1,
     svg #line2 {
      transform-origin: center;
    }
    
    @keyframes one1 {
      50% {
        transform: translateY(15%);
      }
      100% {
        transform:  rotate(45deg) translateY(15%);
      }
    }
    @keyframes one2 {
      50% {
        transform: translateY(-15%);
      }
      100% {
        transform: rotate(-45deg) translateY(-15%) ;
      }
    }
    <div class="wrap b">
    <svg width="100" height="100" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" viewbox="0 0 100 100">
      
      <line id="line1" x1="10" y1="35" x2="90" y2="35" stroke="black" stroke-width="10" stroke-linecap="round" />
      <line id="line2" x1="10" y1="65" x2="90" y2="65" stroke="black" stroke-width="10" stroke-linecap="round" />
      <circle cx="50" cy="50" r="3" fill="red"/>
      
    </svg>
    </div>