JSFiddle - React, Tailwind, and code Playground

Animating SVG test

by Travis Almand

HTML

<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" style="">
  <symbol id="save" viewbox="0 0 32 32">
	  <path class="base" d="m29.4 5.7 0 23.6-26 0 0-26 23.4-0.1" fill="#000" />
	  <path class="offcolor" d="m5.8 3.3 0.1 8.9 16.8 0-0.1-8.9-16.8 0zm0.1 11.9 0 14.2 21 0 0-14.2-21 0z" fill="#2b2b2b"/>
	  <path class="labelback" d="m6.4 15.6 20.1 0 0 13-20.1 0z" fill="#fff" />
	  <path class="labelcolor" d="m6.5 15.6 0 2 20.1 0 0-2-20.1 0zm0 12.2 0 0.8 20.1 0 0-0.8-20.1 0z" fill="#37b03b" />
	  <path class="slide" d="m10.7 12.2 0-9 11.3 0 0 9-11.3 0zm6.7-0.8 3 0 0.1-7.3-3 0-0.1 7.3z" fill="#a5a5a5" />
  </symbol>
</svg>

<div>default</div>
<div class="svg-container">
  <svg><use xlink:href="#save"></use></svg>
</div>

<div>ready</div>
<div class="svg-container ready">
  <svg><use xlink:href="#save"></use></svg>
</div>

<div>not ready</div>
<div class="svg-container notready">
  <svg><use xlink:href="#save"></use></svg>
</div>

<div>error</div>
<div class="svg-container error">
  <svg><use xlink:href="#save"></use></svg>
</div>

SCSS

$height: 48px;
$width: 48px;

.svg-container {
  height: $height;
  overflow: hidden;
  position: relative;
  width: $width;
}
.svg-container svg {
  height: 100%;
  left: 0;
  position: absolute;
  top: 0;
  width: 100%;
}

.svg-container {
  cursor: pointer;
  transition: transform 0.25s;
  
  &:hover {
    .slide {
      transform: translate(-4px, 0);
      transition: transform 0.25s;
    }
  }
  &.ready {
    .base,
    .offcolor {
      animation: 0.75s infinite alternate ready;
    }
    
    &:hover {
      transform: scale(1.25, 1.25);
      transition-timing-function: cubic-bezier(.17,.67,.32,1.49);
    }
  }
  &.notready {
    transition: all 0.25s;
    transition-timing-function: cubic-bezier(.17,.67,.32,1.49);
    
    &:hover {
      opacity: 0.5;
      transform: scale(0.75, 0.75);
    }
    & .base,
    & .offcolor {
      fill: grey;
    }
  }
  &.error {
    .base,
    .offcolor {
      animation: 0.75s infinite alternate error;
    }
    
    &:hover {
      animation: 0.5s infinite errorHover;
    }
  }
  
  .slide {
    transition: transform 0.05s;
  }
}

@keyframes ready {
  from { fill: #000; }
  to { fill: green; }
}

@keyframes error {
  from { fill: #000; }
  to { fill: red; }
}
@keyframes errorHover {
  0% { transform: translate(0, 0); }
  25% { transform: translate(-10px, 0); }
  50% { transform: translate(0, 0); }
  75% { transform: translate(10px, 0); }
}