如何在mouseout上平滑地反转此动画?

问题描述 投票:3回答:4

我把这张卡片放在一起,当你将它悬停在它上面时,它会在它的x轴上翻转180度,然后展开。当我鼠标移开元素时,我希望这个元素以相反的方式向后翻转,就像它进入的方式一样。而不是当你像鼠标一样突然改回来的时候。

此外,应该注意的是,只要鼠标悬停在元素上,我希望动画使用animation: forwards。 (即,只要用户悬停在元素上,它就应该保持翻转和放大。)

有没有办法只用CSS做到这一点?或者我需要Javascript吗?如果是这样,我想用纯香草JS做到这一点。

我一直在寻找Stack Overflow上的解决方案,似乎无法找到明确的答案,或者没有输入正确的问题。

html, body {
  background: #f2edea;
  height: 100%;
  width: 100%;
}

.container {
  width: 250px;
  height: 320px;
  margin: auto;
  position: relative;
  top: 35%;
}

img {
  width: 100%;
  max-height: 100%;
}

.flipcard {
  height: 100%;
  width: 100%;
  margin: auto;
  top: 20%;
  position: relative;
  box-shadow: 5px 5px 20px #94989e;
  border: 3px solid #b8b8ba;
  border-radius: 5px;
  background: pink;
  transform-style: preserve-3d;
} 

@keyframes grow {
  from {
    transform: rotateY(0) scale(1);
  }
  to {
    transform: rotateY(180deg) scale(2);
  }
}

.flipcard:hover {
  animation: grow 1s forwards;
}

.front-side  {
  height: 100%;
  width: 100%;
  position: relative;
  backface-visibility: hidden;
  
}

.back-side {
  width: 100%;
  height: 100%;
  transform: rotateY(180deg);
  position: absolute;
  top: 0;
  border-radius: 3px;
}
<div class='container'>
  <div class='flipcard'>
  <div class='front-side'>
    <img src='https://pre00.deviantart.net/4121/th/pre/i/2018/059/6/7/brigitte_by_raikoart-dc4kzas.png'>
  </div>
  <div class='back-side'>
    <img src="https://img00.deviantart.net/e0ec/i/2017/297/8/c/mercy_by_raikoart-dbrm54b.png">
  </div>
</div>
</div>
javascript html css
4个回答
1
投票

你最好在正常状态和悬停状态之间使用transition。 请注意,您必须在hover上跟踪.container以避免跳跃和闪烁。

html, body {
  background: #f2edea;
  height: 100%;
  width: 100%;
}

.container {
  width: 250px;
  height: 320px;
  margin: auto;
  position: relative;
}

img {
  width: 100%;
  max-height: 100%;
}

.flipcard {
  height: 100%;
  width: 100%;
  margin: auto;
  top: 20%;
  position: relative;
  box-shadow: 5px 5px 20px #94989e;
  border: 3px solid #b8b8ba;
  border-radius: 5px;
  background: pink;
  transform-style: preserve-3d;
  transition: all .5s ease-in-out;
} 

.container:hover .flipcard {
    transform: rotateY(180deg) scale(2);
}

.front-side  {
  height: 100%;
  width: 100%;
  position: relative;
  backface-visibility: hidden;
  
}

.back-side {
  width: 100%;
  height: 100%;
  transform: rotateY(180deg);
  position: absolute;
  top: 0;
  border-radius: 3px;
}
<div class='container'>
  <div class='flipcard'>
  <div class='front-side'>
    <img src='https://pre00.deviantart.net/4121/th/pre/i/2018/059/6/7/brigitte_by_raikoart-dc4kzas.png'>
  </div>
  <div class='back-side'>
    <img src="https://img00.deviantart.net/e0ec/i/2017/297/8/c/mercy_by_raikoart-dbrm54b.png">
  </div>
</div>
</div>

1
投票

发生这种情况的原因是因为在默认的非悬停状态下没有要返回的动画状态。你有两种选择。

  1. 不要使用动画,只是将效果转换为悬停。

通过这种方式,属性将返回到具有转换的非悬停状态。

.flipcard {
  height: 100%;
  width: 100%;
  margin: auto;
  top: 20%;
  position: relative;
  box-shadow: 5px 5px 20px #94989e;
  border: 3px solid #b8b8ba;
  border-radius: 5px;
  background: pink;
  transform-style: preserve-3d;
  transform: rotateY(0) scale(1);
  transition: all 0.3s ease;
} 

.flipcard:hover {
  transform: rotateY(180deg) scale(2);
}

https://jsfiddle.net/255mnwxr/5/

  1. 拥有动画属性。

这是最不希望的,因为在加载时动画将播放一次以使其动画,然后它自然地起作用。

.flipcard {
  animation: return 1s forwards;
  height: 100%;
  width: 100%;
  margin: auto;
  top: 20%;
  position: relative;
  box-shadow: 5px 5px 20px #94989e;
  border: 3px solid #b8b8ba;
  border-radius: 5px;
  background: pink;
  transform-style: preserve-3d;
  transition: all 0.3s ease;
} 

@keyframes grow {
  from {
    transform: rotateY(0) scale(1);
  }
  to {
    transform: rotateY(180deg) scale(2);
  }
}

@keyframes return {
  from {
    transform: rotateY(180deg) scale(2);
  }
  to {
    transform: rotateY(0) scale(1);
  }
}

https://jsfiddle.net/255mnwxr/2/


0
投票

你需要在鼠标悬停上添加@keyframes。

html, body {
  background: #f2edea;
  height: 100%;
  width: 100%;
}

.container {
  width: 250px;
  height: 320px;
  margin: auto;
  position: relative;
  top: 35%;
}

img {
  width: 100%;
  max-height: 100%;
}

.flipcard {
  height: 100%;
  width: 100%;
  margin: auto;
  top: 20%;
  position: relative;
  box-shadow: 5px 5px 20px #94989e;
  border: 3px solid #b8b8ba;
  border-radius: 5px;
  background: pink;
  transform-style: preserve-3d;
} 


@-webkit-keyframes in {
    from   { -webkit-transform: rotate(0deg); }
    to {-webkit-transform: rotateY(180deg) scale(2);}
}

@-webkit-keyframes out {
    0%   { -webkit-transform: rotateY(180deg) scale(2); }
    100% { -webkit-transform: rotate(0deg); }
}

.flipcard:hover {
  animation: out 1s forwards;
}

.flipcard {
  animation: in 1s forwards;
}

.front-side  {
  height: 100%;
  width: 100%;
  position: relative;
  backface-visibility: hidden;
  
}

.back-side {
  width: 100%;
  height: 100%;
  transform: rotateY(180deg);
  position: absolute;
  top: 0;
  border-radius: 3px;
}
<div class='container'>
  <div class='flipcard'>
  <div class='front-side'>
    <img src='https://pre00.deviantart.net/4121/th/pre/i/2018/059/6/7/brigitte_by_raikoart-dc4kzas.png'>
  </div>
  <div class='back-side'>
    <img src="https://img00.deviantart.net/e0ec/i/2017/297/8/c/mercy_by_raikoart-dbrm54b.png">
  </div>
</div>
</div>

0
投票

你不需要关键帧动画,你可以为此使用基本的CSS过渡,它们将使用transition属性在mouseout上回放:

.flipcard {
  transform: rotateY(0) scale(1);
  transition: 1s all ease-out;
} 

.flipcard:hover {
  transform: rotateY(180deg) scale(2);
}

但是,如果您确实想要使用动画(对于更复杂的交互),我在底部有一个片段,只知道这可能有点难以维护,只是在默认元素上反转它将无法工作。

另请注意,您可能需要一个不旋转的鼠标容器,但可以控制悬停状态,否则鼠标可能会在转换过程中脱落,如:

.flipcard-container:hover .flipcard {
    transform: rotateY(180deg) scale(2);
}

html, body {
  background: #f2edea;
  height: 100%;
  width: 100%;
}

.container {
  width: 250px;
  height: 320px;
  margin: auto;
  position: relative;
  top: 35%;
}

img {
  width: 100%;
  max-height: 100%;
}

.flipcard {
  height: 100%;
  width: 100%;
  margin: auto;
  top: 20%;
  position: relative;
  box-shadow: 5px 5px 20px #94989e;
  border: 3px solid #b8b8ba;
  border-radius: 5px;
  background: pink;
  transform-style: preserve-3d;
  transform: rotateY(0) scale(1);
  transition: 1s all ease-out;
} 

.flipcard:hover {
  transform: rotateY(180deg) scale(2);
}

.front-side  {
  height: 100%;
  width: 100%;
  position: relative;
  backface-visibility: hidden;

}

.back-side {
  width: 100%;
  height: 100%;
  transform: rotateY(180deg);
  position: absolute;
  top: 0;
  border-radius: 3px;
}
<div class='container'>
  <div class='flipcard'>
    <div class='front-side'>
      <img src='https://pre00.deviantart.net/4121/th/pre/i/2018/059/6/7/brigitte_by_raikoart-dc4kzas.png'>
    </div>
    <div class='back-side'>
      <img src="https://img00.deviantart.net/e0ec/i/2017/297/8/c/mercy_by_raikoart-dbrm54b.png">
    </div>
  </div>
</div>

html, body {
  background: #f2edea;
  height: 100%;
  width: 100%;
}

.container {
  width: 250px;
  height: 320px;
  margin: auto;
  position: relative;
  top: 35%;
}

img {
  width: 100%;
  max-height: 100%;
}

@keyframes grow {
  from {
    transform: rotateY(0) scale(1);
  }
  to {
    transform: rotateY(180deg) scale(2);
  }
}

@keyframes shrink {
  from {
    transform: rotateY(180deg) scale(2);
  }
  to {
    transform: rotateY(0) scale(1);
  }
}

.flipcard {
  height: 100%;
  width: 100%;
  margin: auto;
  top: 20%;
  position: relative;
  box-shadow: 5px 5px 20px #94989e;
  border: 3px solid #b8b8ba;
  border-radius: 5px;
  background: pink;
  transform-style: preserve-3d;
  transform: rotateY(0) scale(1);
  animation: shrink 1s forwards;
} 


.flipcard:hover {
  animation: grow 1s forwards;
}

.front-side  {
  height: 100%;
  width: 100%;
  position: relative;
  backface-visibility: hidden;
  
}

.back-side {
  width: 100%;
  height: 100%;
  transform: rotateY(180deg);
  position: absolute;
  top: 0;
  border-radius: 3px;
}
<div class='container'>
  <div class='flipcard'>
    <div class='front-side'>
      <img src='https://pre00.deviantart.net/4121/th/pre/i/2018/059/6/7/brigitte_by_raikoart-dc4kzas.png'>
    </div>
    <div class='back-side'>
      <img src="https://img00.deviantart.net/e0ec/i/2017/297/8/c/mercy_by_raikoart-dbrm54b.png">
    </div>
  </div>
</div>
© www.soinside.com 2019 - 2024. All rights reserved.