问题
I use an image and three spans as siblings within a wrapper (.avatar
), to display a small avatar. I added two animations. The animated elements are the spans. They are animated with a small delay.
One animation is executed immediately (@keyframes rings-load
). The other one (@keyframes rings-hover
) executes, when .avatar
is hovered.
Problem: After hovering .avatar
, leaving the element, the initial animation is triggered a second time. Why is that? What would be considered best practice to prevent this behaviour?
Expected: Animation rings-load
executes once on page load and is not executed again. Animation rings-hover
executes once on every hover on element with class .avatar
.
/* vars */
:root {
--avatar-size: 140px;
}
/* general */
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body {
background: #333;
margin: 0;
padding: 0;
}
main {
display: flex;
flex-flow: column wrap;
justify-content: center;
align-content: center;
height: 100vh;
}
/* avatar */
.avatar-container {
margin: 2rem;
padding: 21px;
}
.avatar img {
width: var(--avatar-size);
height: var(--avatar-size);
border-radius: 100%;
padding: 2px;
cursor: pointer;
}
.avatar span {
border-radius: 100%;
position: absolute;
width: var(--avatar-size);
height: var(--avatar-size);
border: 1px solid #ffffffee;
background: #333;
z-index: -1;
opacity: 0;
-webkit-transform: scale(1);
transform: scale(1);
-webkit-animation: rings-load 900ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
animation: rings-load 900ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
-webkit-animation-iteration-count: 1;
animation-iteration-count: 1;
}
.avatar span:nth-child(2) {
-webkit-animation-delay: 200ms;
animation-delay: 200ms;
}
.avatar span:nth-child(3) {
-webkit-animation-delay: 300ms;
animation-delay: 300ms;
}
.avatar:hover span {
-webkit-animation: rings-hover 900ms cubic-bezier(0.25, 0.46, 0.45, 0.94) infinite;
animation: rings-hover 900ms cubic-bezier(0.25, 0.46, 0.45, 0.94) infinite;
-webkit-animation-iteration-count: 1;
animation-iteration-count: 1;
}
.avatar:hover span:nth-child(2) {
-webkit-animation-delay: 200ms;
animation-delay: 200ms;
}
.avatar:hover span:nth-child(3) {
-webkit-animation-delay: 300ms;
animation-delay: 300ms;
}
/* animations */
@-webkit-keyframes rings-load {
75% {
opacity: 1;
-webkit-transform: scale(1.3);
transform: scale(1.3);
}
100% {
opacity: 0;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
}
@keyframes rings-load {
75% {
opacity: 1;
-webkit-transform: scale(1.3);
transform: scale(1.3);
}
100% {
opacity: 0;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
}
@-webkit-keyframes rings-hover {
0% {
opacity: 0;
-webkit-transform: scale(1.3);
transform: scale(1.3);
}
50% {
opacity: 1;
}
75% {
opacity: 0;
-webkit-transform: scale(1);
transform: scale(1);
}
}
@keyframes rings-hover {
0% {
opacity: 0;
-webkit-transform: scale(1.3);
transform: scale(1.3);
}
50% {
opacity: 1;
}
75% {
opacity: 0;
-webkit-transform: scale(1);
transform: scale(1);
}
}
<main>
<div class="avatar-container">
<div class="avatar">
<span></span>
<span></span>
<span></span>
<img src="https://picsum.photos/140/140/?17" alt="Avatar Books" />
</div>
</div>
</main>
回答1:
Your hover resets the base animation. Then, when you unhover, it is apllied again, so it plays again.
Instead, on hover add the new animation on top of the previous one. This will make the animation not to be reset, and the unhover won't trigger it
Alos, you can forget about webkit prefixes.
/* vars */
:root {
--avatar-size: 140px;
}
/* general */
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body {
background: #333;
margin: 0;
padding: 0;
}
main {
display: flex;
flex-flow: column wrap;
justify-content: center;
align-content: center;
height: 100vh;
}
/* avatar */
.avatar-container {
margin: 2rem;
padding: 21px;
}
.avatar img {
width: var(--avatar-size);
height: var(--avatar-size);
border-radius: 100%;
padding: 2px;
cursor: pointer;
}
.avatar span {
border-radius: 100%;
position: absolute;
width: var(--avatar-size);
height: var(--avatar-size);
border: 1px solid #ffffffee;
background: #333;
z-index: -1;
opacity: 0;
transform: scale(1);
animation: rings-load 900ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
animation-iteration-count: 1;
}
.avatar span:nth-child(2) {
animation-delay: 200ms;
}
.avatar span:nth-child(3) {
animation-delay: 300ms;
}
.avatar:hover span {
animation: rings-load 900ms cubic-bezier(0.25, 0.46, 0.45, 0.94),
rings-hover 900ms cubic-bezier(0.25, 0.46, 0.45, 0.94) 1;
}
.avatar:hover span:nth-child(2) {
animation-delay: 200ms;
}
.avatar:hover span:nth-child(3) {
animation-delay: 300ms;
}
/* animations */
@-webkit-keyframes rings-load {
75% {
opacity: 1;
-webkit-transform: scale(1.3);
transform: scale(1.3);
}
100% {
opacity: 0;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
}
@keyframes rings-load {
75% {
opacity: 1;
-webkit-transform: scale(1.3);
transform: scale(1.3);
}
100% {
opacity: 0;
-webkit-transform: scale(1.2);
transform: scale(1.2);
}
}
@-webkit-keyframes rings-hover {
0% {
opacity: 0;
-webkit-transform: scale(1.3);
transform: scale(1.3);
}
50% {
opacity: 1;
}
75% {
opacity: 0;
-webkit-transform: scale(1);
transform: scale(1);
}
}
@keyframes rings-hover {
0% {
opacity: 0;
-webkit-transform: scale(1.3);
transform: scale(1.3);
}
50% {
opacity: 1;
}
75% {
opacity: 0;
-webkit-transform: scale(1);
transform: scale(1);
}
}
<main>
<div class="avatar-container">
<div class="avatar">
<span></span>
<span></span>
<span></span>
<img src="https://picsum.photos/140/140/?17" alt="Avatar Books" />
</div>
</div>
</main>
来源:https://stackoverflow.com/questions/55004015/animation-on-page-load-is-executed-a-second-time-on-mouse-leave