Mark Hill Mark Hill - 1 month ago 14
CSS Question

SVG filter won't disappear on hover using transitions

I am currently working on some new stuff and I have been introduced to the world of SVG objects. They are nice. Anyways, I have a button that I have built and I put a filter on it. The designer I'm working with would like the filter (a drop shadow) to go from opacity 1 to 0 on hover, and return to 1 off hover.

I have tried just normal transitions on the filter, and I can get the filter to disappear but the transition is far from smooth.

Here's my code:

html

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 216 216" style="enable-background:new 0 0 216 216;" xml:space="preserve">
<filter id="fade" height="150%" width='150%'>
<feMerge>
<feMergeNode/>
<!-- this contains the offset blurred image -->
<feMergeNode in="SourceGraphic" />
<!-- this contains the element that the filter is applied to -->
</feMerge>
</filter>
<filter id="dropshadow" height="150%" width='150%'>
<feGaussianBlur in="SourceAlpha" stdDeviation="25" />
<!-- stdDeviation is how much to blur -->
<feOffset dx="0" dy="15vh" result="offsetblur" />
<!-- how much to offset -->
<feComponentTransfer>
<feFuncA type="linear" slope="0.4" />
</feComponentTransfer>
<feMerge>
<feMergeNode/>
<!-- this contains the offset blurred image -->
<feMergeNode in="SourceGraphic" />
<!-- this contains the element that the filter is applied to -->
</feMerge>
</filter>
<a href='' id='playvideo_button'>
<g>
<path class="st0" d="M108,24c-46.4,0-84,37.6-84,84s37.6,84,84,84s84-37.6,84-84S154.4,24,108,24z" />
<polygon class="st1" points="92,140 92,76 140,108" />
</g>
</a>
</svg>


CSS

svg {
width: 30vw;
height: 30vh;
cursor: pointer;

}

svg .st0 {
fill: #4982CF;
transition: filter.6s ease-out;
filter: url(#dropshadow);
}
svg .st1 {
fill: #ffffff;

}
svg:hover .st0{
filter: url(#fade);
}


Here, also, is a link to my fiddle that I have been playing around with, please let me know if any additional resources are required! Thank you in advance for all assistance.

https://jsfiddle.net/sfza69ry/7/

EDITS

I have created a second filter, which is just a transparent overlay, but that has also failed and does the same not smooth effect.

I'm pretty much at a loss here.

Answer

Using transitions on the filter is not the way to do this. Here is a more elegant way. There are a bunch of things here you should note:

  • You need to size both the svg and the filter regions properly to make sure the shadow isn't cut off
  • You can't transition filters
  • Support for CSS units isn't reliably supported inside an SVG filter, stick to either objectBoundingBox (%) or userSpaceOnUse (viewbox) units
  • Look at how I constructed the filter to allow it to be drawn on top of the shape (to capture hover) without obscuring it. That's the "operator="out" part of the filter.

  • Enclose your filter in a defs element. Some browsers require this.

  • DON'T use Illustrator exports as boilerplates. They're really not well constructed SVG.

In general, the worst way to learn SVG is by trying to decode or tweak Illustrator export code. It's just an unmitigated craptastic disaster.

svg {
  width: 30vw;
  height: 30vh;
  cursor: pointer;
}

svg .st0 {
  fill: #4982CF;
}

svg .st1 {
  fill: #ffffff;
}

#usedshadow {
   opacity: 1;
   transition: opacity 0.6s;
}

#usedshadow:hover {
   opacity: 0;
   transition: opacity 0.6s;
}
<svg version="1.1" x="0px" y="0px" width="300px" height="300px" viewBox="0 0 300 300">

  <defs>
    <filter id="dropshadow" x="-50%" y="-50%" height="200%" width='200%'>
      <feGaussianBlur in="SourceAlpha" stdDeviation="10" />
      <!-- stdDeviation is how much to blur -->
      <feOffset dx="0" dy="15" result="offsetblur" />
      <!-- how much to offset -->
      <feComponentTransfer>
        <feFuncA type="linear" slope="0.4" />
      </feComponentTransfer>
      <feComposite operator="out" in2="SourceGraphic"/>
    </filter>

    <g id="myshape">
      <path class="st0" d="M108,24c-46.4,0-84,37.6-84,84s37.6,84,84,84s84-37.6,84-84S154.4,24,108,24z" />
      <polygon class="st1" points="92,140 92,76 140,108" />
    <g>

  </defs>

  <use xlink:href="#myshape"/>
  <use id="usedshadow" filter="url(#dropshadow)" xlink:href="#myshape"/>

</svg>

Comments