Coercing an element's property to a specific value, even if it is animated

I have two types of elements, name them .a

and .b

.

They may have specific CSS animations. I have no control over these keyframes, whether set or not, over what they animate.

They can be animated opacity

. However, I want to keep a specific value opacity

in my .a

elements, even if 1

it is animated or not.

Consider the following code where I have three cases:

  • there is no animation on my elements
  • there is animation, but it does not animate opacity

  • animation and opacity

    are among the animated properties

div {
  /* some dummy styles so we can see stuff */
  display: inline-block;
  width: 5em; height: 5em;
  background: purple;
}

[class*='ani'] { animation: a 1s ease-out infinite alternate }

.ani--one { animation-name: ani-one }

@keyframes ani-one { to { transform: scale(.5) } }

.ani--two { animation-name: ani-two }

@keyframes ani-two {
  to {
    opacity: 0;
    background: orange;
  }
}
      

<div class='a'></div>
<div class='b'></div>
<div class='a ani--one'></div>
<div class='b ani--one'></div>
<div class='a ani--two'></div>
<div class='b ani--two'></div>
      

Run code


In the first two cases (1 = no keyframe animation and 2 = keyframe animation, but this is not an animation opacity

) I don't need to do anything.

In the latter case, however, I need to somehow force the element of the opacity

element .a

to 1

cancel the animation effect only on that property.

I cannot remove the keyframe animation from the element .a

because I want other properties ( background

in this case, whatever else in general) to keep the animation going.

I can't change the animation because I want it to work as originally set by animating opacity

for other elements ( .b

).

So the question is, how do I determine if a .a

property is being opacity

animated on an element , and if so, how can I make its value stay at 1

, then how other properties set through the same keyframes are animated?

I want to solve this problem using vanilla JS, no libraries.

+3


source to share


2 answers


Now, it just amazed me that I could do this by adding additional animation to CSS keyframes:

@keyframes opacity-override { 0%, 100% { opacity: 1 } }

      

Now for all the elements .a

that have a set animation

, I can add an opacity-override

animation to the name and it should take care of things!



Also, I can use it to enforce opacity: 1

styles that can be set on hover or other classes are added, which is great!

const _A = document.querySelectorAll('.a');

_A.forEach(a => {
  let aname = getComputedStyle(a).animationName;
  
  if(aname !== 'none') a.style.animationName = `${aname}, opacity-override`;
  else a.style.animation = 'opacity-override 1s infinite';
});
      

div {
  /* some dummy styles so we can see stuff */
  display: inline-block;
  width: 5rem; height: 5rem;
  background: purple;
  color: white;
  font: 700 3em/5rem verdana;
  text-align: center;
}

div:hover { opacity: .7 }

[class*='ani'] { animation: a 1s ease-out infinite alternate }

.ani--one { animation-name: ani-one }

@keyframes ani-one { to { transform: scale(.5) } }

.ani--two { animation-name: ani-two }

@keyframes ani-two {
  to {
    opacity: 0;
    background: orange;
  }
}

@keyframes opacity-override { 0%, 100% { opacity: 1 } }
      

<div class='a'>A</div>
<div class='b'>B</div>
<div class='a ani--one'>A</div>
<div class='b ani--one'>B</div>
<div class='a ani--two'>A</div>
<div class='b ani--two'>B</div>
      

Run code


+2


source


You can hack it using! important

.solid-always { opacity:1 !important; }

      



and then just put in the class in the one you don't need so that its opacity changes. The keyframe must not overwrite! It's important if you don't add an important tag to the keyframe and then it whichever comes last.

0


source







All Articles