Deepak Yadav
Deepak Yadav

Reputation: 7069

Flickering fill issue on SVG hover

New to SVG thing. I have a created a SVG shape using Illustrator and inserted an image tag inside that shave. After svg tag, have added some html, which is hidden by default and shown when user hovers over the svg. But doing so, i'm facing of image/color flickering. Try hovering over the SVG.

and suggest some better way to achieve this.

.svg-parent {
  position: relative;
}
.svg-parent svg {
  position: relative;
  z-index: 5;
}
.svg-parent svg:hover + .svg-child {
  display: block;
}
.svg-parent path:hover {
  fill: #fff802;
}
.svg-child {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  z-index: 10;
  display: none;
  color: #fff;
}
<div class="svg-parent">
  <svg x="0px" y="0px" viewBox="0 0 302 395" xml:space="preserve" width="302" height="395">
    <defs>
      <pattern id="america" patternUnits="userSpaceOnUse" width="302" height="395">
        <image xlink:href="https://i.sstatic.net/LNQ3H.png" width="100%" height="100%" x="0" y="0" />
      </pattern>
    </defs>
    <g>
      <path d="M0,0h302l-1,330L0,395V0z" fill="url(#america)" />
    </g>
  </svg>
  <div class="svg-child">This text and image flicker, when you move your mouse cursor around this svg shape</div>
</div>

image inserted inside svg tag

Upvotes: 1

Views: 4356

Answers (1)

AA2992
AA2992

Reputation: 1607

Your svg-child overlaps the svg. Its stacked above the image with z-index while its display is solely dependant on hovering over the svg. That is the reason your mouse events switch between states.

When the pointer enters the element for the first time, the hover triggers the display and path fill. But when you move, its no longer pointing at the svg, instead its pointing at the svg-child, since its placed higher by the z-index. This happens multiple times thereby causing the flicker.

Clip path method: For browser support check Caniuse = css-clip-path

.svg-parent {
  position: relative;
  display: inline-block;
 -webkit-clip-path: url(#clip);
  clip-path: url(#clip);
}

.svg-child {
  z-index: 2;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

.svg-child a {
  visibility: hidden;
}

.svg-child:hover a {
  visibility: visible;
}

.svg-child:hover + svg path {
  fill: #fff802;
}
<div class="svg-parent">
  <div class="svg-child">
    <a href>Your Link</a>
  </div>
  <svg x="0px" y="0px" viewBox="0 0 302 395" xml:space="preserve" width="302" height="395">
    <defs>
      <pattern id="america" patternUnits="userSpaceOnUse" width="302" height="395">
        <image xlink:href="https://i.sstatic.net/LNQ3H.png" width="100%" height="100%" x="0" y="0" />
      </pattern>
    </defs>
    <g>
      <path d="M0,0h302l-1,330L0,395V0z" fill="url(#america)" />
    </g>
    <defs>
      <clipPath id="clip">
        <path d="M0,0h302l-1,330L0,395V0z"/>
      </clipPath>
    </defs>
  </svg>
</div>

You can also just use SVG Anchor Element <a> this way to add a link on the svg.

<a xlink:href="https://www.example.org"
 target="_blank">
  <path d="M0,0h302l-1,330L0,395V0z" fill="url(#america)" />      
  <text x="20" y="20">Click On This SVG</text>
</a>

Here is a working example of that. JSFiddle

Add CSS to position the link text as you see fit.

Upvotes: 2

Related Questions