Transition on new pseudo-element with filter

Viewed 99

I'm working on a glowing effect for images. To make the glow more than one colour, I'm actually making a pseudo-element copy of the image with a blur and saturation filter applied. This pseudo-element is created through the addition of a class to the image's div.

Now this is all well and good, but I'd like to transition the glow effect with an ease-out, however no matter where I put the transition attributes, I just can't seem to get it to work.

I've made a codepen to illustrate: https://codepen.io/anon/pen/eYGJGPG

function addGlow() {
  document.getElementById('example').classList.toggle('mask')
}
.img {
  height: fit-content;
  width: fit-content;
  display: block;
  /* Doesn't transition */
  transition: all 0.3s ease-out;
  -webkit-transition: all 0.3s ease-out;
  -moz-transition: all 0.3s ease-out;
  -o-transition: all 0.3s ease-out;
}

.go {
  height: 400px;
  width: 400px;
  background: url("https://upload.wikimedia.org/wikipedia/commons/3/32/RGB_color_wheel_72.svg");
  background-size: initial;
}

.mask::after {
  content: "";
  width: inherit;
  height: inherit;
  position: absolute;
  background: inherit;
  background-position: center center;
  filter: blur(10px) saturate(3);
  z-index: -1;
}
<div id="example" class="img go"></div>
<button onclick="addGlow()">Press</button>

2 Answers

Possibly consider using animation instead of transition. See working snippet below.

function addGlow(){
  document.getElementById('example').classList.toggle('mask')
}
.img {
  height: fit-content;
  width: fit-content;
  display: block;
  /* Doesn't transition */

}

.go {
  height: 400px;
  width: 400px;
  background: url("https://upload.wikimedia.org/wikipedia/commons/3/32/RGB_color_wheel_72.svg");
  background-size: initial;

}


.mask::after {
  content: "";
  width: inherit;
  height: inherit;
  position: absolute;
  background: inherit;
  background-position: center center;
  z-index: -1;
  animation: example-animation .5s ease-out;
  animation-direction: normal;
  animation-iteration-count: 1;
  filter: blur(10px) saturate(3);
}

@keyframes example-animation {
  0% {
      filter: blur(0) saturate(3);

  }
  100% {
     filter: blur(10px) saturate(3);

  }
}
<div id="example" class="img go"></div>
<button onclick="addGlow()">Press</button>

When you remove class .mask the pseudo element ::after is removed from the DOM. You need to keep ::after in the DOM all the time to see transitions happening on it:

function addGlow() {
  document.getElementById('example').classList.toggle('mask')
}
.img {
  height: fit-content;
  width: fit-content;
  display: block;
}

.go {
  height: 400px;
  width: 400px;
  background: url("https://upload.wikimedia.org/wikipedia/commons/3/32/RGB_color_wheel_72.svg");
  background-size: initial;
}

.img::after {
  content: "";
  width: inherit;
  height: inherit;
  position: absolute;
  background: inherit;
  background-position: center center;
  z-index: -1;
  
  /* initial state */
  filter: blur(0px) saturate(0);
  transition: all 1.3s ease-out;
  -webkit-transition: all 1.3s ease-out;
  -moz-transition: all 1.3s ease-out;
  -o-transition: all 1.3s ease-out;
}

.mask::after {
  /* glow */
  filter: blur(30px) saturate(3);
}
<div id="example" class="img go"></div>
<button onclick="addGlow()">Press</button>

Related