csssvgcss-animationscss-transformssvg-transforms

Animate only one path within an SVG without cropping


I am using an SVG for my logo and I want to give one of the letters a push-down effect:

body {
  background: skyblue;
}

@-webkit-keyframes push {
  0%,
  25%,
  75%,
  100% {
    -webkit-transform: translateY(0);
    transform: translateY(0);
  }
  50% {
    -webkit-transform: translateY(8px);
    transform: translateY(8px);
  }
}

#Path_9-2 {
  -webkit-animation: push 2s;
  animation: push 2s;
  -webkit-animation-iteration-count: infinite;
  animation-iteration-count: infinite;
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="258.313" height="58.791" viewBox="0 0 258.313 58.791">
  <defs>
    <filter id="Path_9" x="35.958" y="17.221" width="70.528" height="41.57" filterUnits="userSpaceOnUse">
      <feOffset dx="2" dy="4" input="SourceAlpha"/>
      <feGaussianBlur stdDeviation="1" result="blur"/>
      <feFlood flood-opacity="0.161"/>
      <feComposite operator="in" in2="blur"/>
      <feComposite in="SourceGraphic"/>
    </filter>
  </defs>
  <g id="Group_69" data-name="Group 69" transform="translate(-38 -19)">
    <path id="Path_7" data-name="Path 7" d="M18,17.15a13.73,13.73,0,0,0-9.31,3.42,4.3,4.3,0,0,0-4.22-3.42A4.43,4.43,0,0,0,0,21.71V47.24a4.49,4.49,0,0,0,4.56,4.62,4.44,4.44,0,0,0,4.49-4.62V31.69a6.12,6.12,0,0,1,6.29-6.43c3.69,0,6.17,2.61,6.17,6.43V47.24A4.48,4.48,0,0,0,26,51.86a4.4,4.4,0,0,0,4.49-4.62V30.49c0-8.11-4.9-13.34-12.47-13.34" transform="translate(38.002 19.001)" fill="#fff"/>
    <g transform="matrix(1, 0, 0, 1, 38, 19)" filter="url(#Path_9)">
      <path id="Path_9-2" data-name="Path 9" d="M84.61,51.79H53.83a17.29,17.29,0,0,1,0-34.57H84.61a17.29,17.29,0,0,1,0,34.57ZM53.83,25.85a8.66,8.66,0,1,0,0,17.32H84.61a8.66,8.66,0,1,0,0-17.32Z" transform="translate(0 0)" fill="#fff"/>
    </g>
    <path id="Path_10" data-name="Path 10" d="M257.24,44.89,247.72,33l8.44-8.58a4.47,4.47,0,0,0,1.48-3.22,4,4,0,0,0-4.16-4,4.27,4.27,0,0,0-3.14,1.41l-10.59,11A4.9,4.9,0,0,0,238.14,33a5.39,5.39,0,0,0,1.41,3.28l11.32,13.94a4,4,0,0,0,3.35,1.67,4.08,4.08,0,0,0,4.09-4.15,4.41,4.41,0,0,0-1.07-2.82M232.18,0a4.49,4.49,0,0,0-4.56,4.62V47.24a4.49,4.49,0,0,0,4.56,4.62,4.44,4.44,0,0,0,4.49-4.62V4.62A4.4,4.4,0,0,0,232.18,0M202.77,25.39c4.89,0,8.57,3.89,8.57,9.12s-3.68,9-8.57,9-8.58-3.75-8.58-9,3.62-9.12,8.58-9.12m0-8.24c-10,0-17.76,7.57-17.76,17.29A17.35,17.35,0,0,0,202.7,51.79c10,0,17.89-7.7,17.89-17.35s-7.91-17.29-17.82-17.29m-37.06,0a13.72,13.72,0,0,0-9.31,3.42,4.3,4.3,0,0,0-4.22-3.42,4.43,4.43,0,0,0-4.49,4.56V47.24a4.49,4.49,0,0,0,4.56,4.62,4.43,4.43,0,0,0,4.48-4.62V31.69a6.13,6.13,0,0,1,6.3-6.43c3.69,0,6.17,2.61,6.17,6.43V47.24a4.48,4.48,0,0,0,4.49,4.62,4.4,4.4,0,0,0,4.49-4.62V30.49c0-8.11-4.9-13.34-12.47-13.34M139.78,44.89,130.27,33l8.44-8.58a4.47,4.47,0,0,0,1.48-3.22,4,4,0,0,0-4.16-4,4.28,4.28,0,0,0-3.15,1.41l-10.58,11A4.9,4.9,0,0,0,120.69,33a5.43,5.43,0,0,0,1.4,3.28l11.33,13.94a4,4,0,0,0,3.35,1.67,4.08,4.08,0,0,0,4.09-4.15,4.37,4.37,0,0,0-1.08-2.82M114.73,0a4.49,4.49,0,0,0-4.56,4.62V47.24a4.49,4.49,0,0,0,4.56,4.62,4.43,4.43,0,0,0,4.48-4.62V4.62A4.39,4.39,0,0,0,114.73,0" transform="translate(38.002 19.001)" fill="#fff"/>
  </g>
</svg>

As you can see the 'o' is cropped when it's being pushed down. Tried using overflow: visible and increasing the height but that didn't help.


Solution

  • I've removed the size and position of the filter. Also I'm using svg{overflow:visible} as you intended. What was cut off was the shadow of the shape. Please take a look.

    body{background:skyBlue;}
    
     @-webkit-keyframes push {
    	0%,
    	25%,
    	75%,
    	100% {
    		-webkit-transform: translateY(0);
    		        transform: translateY(0);
    	}
    	50% {
    		-webkit-transform: translateY(8px);
    		        transform: translateY(8px);
    	}
    }
    #Path_9-2{
    
        -webkit-animation: push 2s;
        animation: push 2s;
        -webkit-animation-iteration-count: infinite;
        animation-iteration-count: infinite;
    }
    
    
    svg{overflow:visible}
    <svg width="258.313" height="58.791" viewBox="0 0 258.313 58.791">
      <defs>
        <filter id="Path_9"  filterUnits="userSpaceOnUse">
          <feOffset dx="2" dy="4" input="SourceAlpha"/>
          <feGaussianBlur stdDeviation="1" result="blur"/>
          <feFlood flood-opacity="0.161"/>
          <feComposite operator="in" in2="blur"/>
          <feComposite in="SourceGraphic"/>
        </filter>
      </defs>
      <g id="Group_69" data-name="Group 69" transform="translate(-38 -19)">
        <g transform="matrix(1, 0, 0, 1, 38, 19)" filter="url(#Path_9)">
          <path id="Path_9-2" data-name="Path 9" d="M84.61,51.79H53.83a17.29,17.29,0,0,1,0-34.57H84.61a17.29,17.29,0,0,1,0,34.57ZM53.83,25.85a8.66,8.66,0,1,0,0,17.32H84.61a8.66,8.66,0,1,0,0-17.32Z" transform="translate(0 0)" fill="#fff"/>
        </g>    
      </g>
    </svg>