Interruption of a CSS transition does not work for same attribute value

后端 未结 2 1409
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-02-14 03:32

I\'ve answered a question on how to start an animation when hovering the child element and then preserve the applied style until un-hovering the parent. However, I discovered a

2条回答
  •  梦毁少年i
    2021-02-14 03:59

    Sorry - I missunderstood what was happening in yopur question.

    I have done a new snippet with a simplified case:

    #a, #b {
      width: 200px;
      height: 100px;
      border: solid 1px black;
      display: inline-block;
      background-color: lightgreen;
      margin-top: 50px;
    }
    
    #a {
      margin-right: -5px;
    }
    
    #container {
      width: 400px;
      height: 50px;
      border: solid 1px black;
      margin: 0px;
    }
    
    #child {
      width: 0px;
      height: 50px;
      position: absolute;
      background-color: blue;  
    }
    
    
    #child {
      transition: width 0.5s;
      width: 400px;
    }
    
    #a:hover ~ #container #child {
      transition: width 10s;
      width: 0px;
    }
    
    #b:hover ~ #container #child {
      transition: width 0.5s;
      width: 0px;
    }
    A
    B

    Hover on A, and then (before the transition ends) hover B. You will see the same behaviour: the transition goes on unchanged.

    The reason is that when hovering a, the width (as a property of the element) is 0px. (Not the calculated width, that is being transitioned). So, when you hover on B, and the new style of 0px will not trigger a property a change, and hende will not start a new transition.

    Old answer

    The key part of the specs is this one: (emphasis mine)

    reversing transitions spec

    To meet this expectation, when a transition is started for a property on an element (henceforth, the new transition) that has a currently-running transition whose reversing-adjusted start value is the same as the end value of the new transition (henceforth, the old transition), implementations must cancel the old transition [...] and adjust the new transition as follows (prior to following the rules for computing the combined duration, start time, and end time): [...]

    So, when the new width is the same as the old one, it's not really that the un-hover has no effect, it's that the effect is very slow (600s) as the browser is reversing the transition that was running.

    To prove this, I have set a snippet where the width in the last rule is the same (10px). And the delay is set to 10 seconds.

    Hover the child, and unhover it leaving the parent. You will see that 10 seconds later, the child width is modified.

    .parent {
      border: 1px solid orange;
      padding: 20px;
      width: 400px;
    }
    
    .parent .child {
      display: inline-block;
      height: 40px;
      background: blue;
      
      transition: width 0.5s ease 10s;
      width: 10px;
    }
    
    .parent .child:hover {
      transition-delay: 0s;
      width: 100px;
    }
    
    .parent:not(:hover) .child {
      transition: width 0.5s ease 0s;
      width: 10px; 
      

提交回复
热议问题