I'm trying to create a marquee using the following css styling:
@keyframes scroll {
0% { transform: translateX(0) }
100% { transform: translate(-100%) }
}
animation: scroll var(--duration) linear infinite;
I want to make it slows down and stops on hover, then continue looping onMouseLeave
, but I can't seem to achieve this effect due to css animation recomputing / resetting position each time I apply a new animation.
Is there a way to achieve this effect? Thank you!
You can toggle the animation-play-state: pause
of the marquee, on :hover
of the parent component.
The animation-play-state CSS property sets whether an animation is running or paused.
With the marquee paused, you can then animate the parent's transform: translateX();
on :hover
which you can control to make it feel like the Marquee is slowing down to a stop.
When :hover
is removed, the DOM will resume the Marquee animation, with the combination of the parent wrapper's translate
returning to 0.
.container {
--duration: 20s;
height: 100px;
background: red;
transform: translateX(0);
transition: calc(var(--duration) * .1) ease-out;
}
.container h1 {
display: inline-block;
width: max-content;
animation: scroll var(--duration) linear infinite;
}
.container:hover {
transform: translateX(-20%);
}
.container:hover h1 {
animation-play-state: paused;
}
@keyframes scroll {
0% {
transform: translateX(0);
}
100% {
transform: translate(-100%);
}
}
<div class="container">
<h1>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras vestibulum nulla ut nibh vulputate egestas. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras vestibulum nulla ut nibh vulputate egestas. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras vestibulum nulla ut nibh vulputate egestas. </h1>
</div>