Search code examples
csssvghoverpseudo-element

CSS hover doesn't work (due to pseudo-elements)?


I am fiddling around with SVG and CSS-effects in order to achieve a look similar to the game "limbo".

The grain and tiltshift effects work as expected, but I cannot trigger the hover-behaviour on svg-elements any more. What am I doing wrong?

Using Firefox inspector I can trigger hover, when I select the element. So I suspect it's the pseudo-elements which block the hover on svg-elements.

.grain {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: auto;
  background-position: center
}

.grain:after {
  content: "";
  background-image: url("https://upload.wikimedia.org/wikipedia/commons/7/76/1k_Dissolve_Noise_Texture.png");
  height: 300%;
  width: 300%;
  position: fixed;
  opacity: 0.1;
  animation: animateGrain 8s steps(10) infinite;
}

@keyframes animateGrain {
  0%,
  100% {
    transform: translate(0, 0)
  }
  10% {
    transform: translate(-5%, -10%)
  }
  20% {
    transform: translate(-15%, -20%)
  }
  30% {
    transform: translate(-5%, -10%)
  }
  40% {
    transform: translate(-15%, -20%)
  }
  50% {
    transform: translate(-5%, -10%)
  }
  60% {
    transform: translate(-15%, -20%)
  }
  70% {
    transform: translate(-5%, -10%)
  }
  80% {
    transform: translate(-15%, -20%)
  }
  90% {
    transform: translate(-5%, -10%)
  }
  100% {
    transform: translate(-15%, -20%)
  }
}

.tiltshift:after {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  backdrop-filter: blur(26px);
  animation: clip-fade 12s infinite alternate;
}

.tiltshift {
  border: 1px solid red;
}

@keyframes clip-fade {
  0% {
    mask-image: linear-gradient(204deg, rgba(0, 0, 0, 1), transparent 100%);
  }
  100% {
    mask-image: linear-gradient(0deg, rgba(0, 0, 0, 1), transparent 100%);
  }
}

#rect1 {
  fill: red !important;
}

#rect1:hover {
  transform: scale(1.07) !important;
}
<div class="tiltshift">
  <div class="grain">
    <svg>...</svg>
  </div>
</div>


Solution

  • Your intuition was right, the pseudo-elements are interfering with the hover event. In fact, since they are taking all of the screen space, they are the ones "catching" the hover event before the rect element.

    You can solve this by adding pointer-events: none rules to the pseudo-elements. That way, they won't catch hovers anymore and the rect is now free to be affected by it.

    See https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events