【问题标题】:CSS Transition after animation ends动画结束后的 CSS 过渡
【发布时间】:2016-02-23 02:31:40
【问题描述】:

我有一个在悬停时移动元素的 css 过渡和一个在悬停时旋转元素的动画。动画的延迟等于过渡持续时间,因此在过渡到正确位置后,动画开始。而且效果很好,但是,当我们关闭鼠标时,动画会停止,但不会向下过渡。

鼠标移开动画结束后,是否可以让它转回来?

您可以在此处查看示例:http://codepen.io/jhealey5/pen/zvXBxM

这里是简化代码:

    div {
        width: 200px;
        height: 200px;
        margin: 40px auto;
        background-color: #b00;
        position: relative;

        &:hover {
            span {
                transform: translateY(-60px);
                animation-name: rotate;
                animation-duration: 1s;
                animation-delay: .5s;
                animation-iteration-count: infinite;
                animation-direction: alternate;
            }
        }
    }

    span {
        position: absolute;
        width: 20px;
        height: 20px;
        background-color: #fff;
        bottom: 10px;
        left: 0;
        right: 0;
        margin: auto;
        transition: .5s;
    }

    @keyframes rotate {
        from {
            transform: translateY(-60px) rotate(0);
        }
        to {
            transform: translateY(-60px) rotate(-90deg);
        }
    }

【问题讨论】:

  • 我使用的是稍旧版本的 Chrome,它也不会在悬停时转换(动画效果很好)。
  • 而且,我认为它在 Chrome 上不起作用的原因是动画和过渡都应用于同一个属性(如讨论的here)。我认为你最好同时使用动画本身。
  • 或者,另一种选择是将bottom 用于transition,而animation 仅用于rotate,如this snippet。我不确定这种方法是否适合您的需求。如果有,请告诉我,我会添加为答案。
  • 干杯,我确实尝试将顶部属性与翻译分开设置动画,但是直到我将默认顶部设置为 0 时它才起作用。动画顶部不是理想的事情,但我也无法访问 dom 来包装它。至少现在工作:)
  • 这是另一个已知问题。浏览器不会转换属性值,除非我们有 my answer here 中提到的初始值。如标题所示,该问题并非仅针对 Firefox。

标签: css animation css-animations


【解决方案1】:

作为Harry pointed out,问题在于您正在动画/转换相同的属性,在本例中为transform。看起来当前版本的 Chrome/FF 将允许 animation 控制该属性,从而破坏 transition。似乎解决这个问题的唯一方法是转换/动画一个不同的属性。由于您需要继续旋转元素,您可以通过更改 bottom 属性来平移/定位元素。我知道这不会产生完全相同的结果,但它确实会移动元素(只是不相对于父元素)。

Updated Example

div:hover  span {
  bottom: 80px;
}

作为替代方案,您也可以包装 span 元素,然后转换该元素。

在下面的示例中,.wrapper 元素在悬停时转换为 translateY(-60px),然后子 span 元素旋转并保持动画。

Example Here

div {
  width: 200px;
  height: 200px;
  margin: 40px auto;
  background-color: #b00;
  position: relative;
}
div:hover .wrapper {
  transform: translateY(-60px);
}
div:hover .wrapper span {
  animation-name: rotate;
  animation-duration: 1s;
  animation-delay: .5s;
  animation-iteration-count: infinite;
  animation-direction: alternate;
}
.wrapper {
  display: inline-block;
  transition: .5s;
  position: absolute;
  bottom: 10px;
  left: 0;
  right: 0;
  text-align: center;
}
.wrapper span {
  display: inline-block;
  width: 20px;
  height: 20px;
  background-color: #fff;
}
@keyframes rotate {
  from {
    transform: rotate(0);
  }
  to {
    transform: rotate(-90deg);
  }
}
<div>
  <span class="wrapper">
	  <span></span>
  </span>
</div>

【讨论】:

  • 不错的乔希。再一次,我们似乎有相同的想法 :) 我刚刚在 cmets 中链接了类似的东西。
  • @evu 我刚刚更新了答案。您可以包装span 元素,然后将变换过渡应用到父元素,同时保持子元素的旋转动画。
  • 您的更新似乎过于复杂?还是只有我一个人?
  • 添加一个全新的 div,当只转换顶部(或底部,在你的情况下)就足够了?我知道如果使用transform: 很重要,这是必要的,但将translateY(-60px) 更改为top: 0; 似乎不是问题。
  • @Rvervuur​​t 同意。但尽管如此,我想证明在产生相同输出的同时仍然可以转换/动画transform 属性。例如,如果我们想使用transform: scaleX(2) 进行缩放转换并使用其他东西为transform 属性设置动画,那么我们就没有其他选择了,而这种方法可以解决这个问题。
【解决方案2】:

我已经对您的项目进行了分叉并对其进行了调整以使其正常工作。 You can find it here.

我所做的更改如下:

我给白色方块一个起始位置top: 150px,让它在div 的hover 上得到一个top: 0。跨度得到一个transition: top .5s,并在悬停时转到top: 0;,并在鼠标离开时返回top: 150px;。

我已经从动画中删除了translateY(-60px);,因为当animation 开始时,它会向上移动。

这是你的新 CSS:

div {
    width: 200px;
    height: 200px;
    margin: 40px auto;
    background-color: #b00;
    position: relative;

    &:hover {
        span {
            top: 0px;
            animation: rotate 1s infinite .5s alternate;
            animation-direction: alternate;
        }
    }
}

span {
    position: absolute;
    width: 20px;
    height: 20px;
    background-color: #fff;
    bottom: 10px;
    left: 0;
    right: 0;
    top: 150px;
    margin: auto;
    transition: top .5s;
}

@keyframes rotate {
    from {
        transform: rotate(0);
    }
    to {
        transform: rotate(-90deg);
    }
}

编辑:问题在于动画是基于时间的而不是基于动作的,这意味着一旦您触发动画,计时器就会开始运行,它将运行所有keyframes直到设定时间已通过。悬停和悬停没有任何效果,除了计时器可以提前停止,但之后动画将不会继续(或反转,你想要的)。 transition 是基于动作的,这意味着每次发生动作(例如:hover)时都会触发它。在:hover 上,这意味着需要0.5 秒才能到达top:0,而当悬停结束时,需要0.5 秒才能到达top:150px。

我希望上面的添加有意义:)

如您所见,我还清理了您的animation-name:等,因为它可以合并为一行。

【讨论】:

  • 是的,在我看来(转换定位属性)是最好的选择,因为同一属性上的 animation 和 transition 不能共存。
  • 谢谢,因为它是最详细的,我将其标记为答案。作为旁注,我对 git 都使用长手持续时间,因为我永远记不起顺序:)
猜你喜欢
  • 2012-11-30
  • 2019-10-17
  • 2018-04-20
  • 1970-01-01
  • 1970-01-01
  • 2020-03-20
  • 1970-01-01
  • 2017-09-17
  • 2015-09-19
相关资源
最近更新 更多