2

Demo of the problem: https://jsfiddle.net/t0qsek8n/1/

<div class="test" id="test">Test text</div>
.test {
  position: relative;
  top: 0px;
  border: 1px solid #ccc;
  animation: test 5s;
  transition: top 1s;
}

@keyframes test {
  0% {
    opacity: 0;
    transition: none;
  }
  100% {
    opacity: 1;
    transition: none;
  }
}
const test = document.getElementById('test');
setTimeout(() => {
    test.style.top = "100px"
}, 1000);

I expect if the value of top property is changed by JS, transition transition: top 1000ms doesn't happen because of transition: none that provides @keyframes test, but actually, the transition happens. I cannot understand why transition value from keyframes doesn't override any existing definition for transition.

Roman Zino
  • 23
  • 4

1 Answers1

2

let's take another example using display:

.test {
  position: relative;
  top: 0px;
  border: 1px solid #ccc;
  animation: test 5s forwards;
}

@keyframes test {
  0% {
    opacity: 0;
    display: none;
  }
  100% {
    opacity: 1;
    display: none;
  }
}
<div class="test" id="test">
  Test text
</div>

We logically expect to never see the element since we set display:none and we made the animation to be forwards but display is simply ignored because it cannot be animated. Same logic with transition since it's a property that we cannot animate ref.

Basically, any property that cannot be animated will simply get ignored when used with keyframes.

Properties that aren't specified in every keyframe are interpolated if possible — properties that can't be interpolated are dropped from the animation. ref

Temani Afif
  • 245,468
  • 26
  • 309
  • 415