How can I create a marquee effect?
With a small change of the markup, here's my approach (I've just inserted a span
inside the paragraph):
.marquee {
width: 450px;
margin: 0 auto;
overflow: hidden;
box-sizing: border-box;
}
.marquee span {
display: inline-block;
width: max-content;
padding-left: 100%;
/* show the marquee just outside the paragraph */
will-change: transform;
animation: marquee 15s linear infinite;
}
.marquee span:hover {
animation-play-state: paused
}
@keyframes marquee {
0% { transform: translate(0, 0); }
100% { transform: translate(-100%, 0); }
}
/* Respect user preferences about animations */
@media (prefers-reduced-motion: reduce) {
.marquee span {
animation-iteration-count: 1;
animation-duration: 0.01;
/* instead of animation: none, so an animationend event is
* still available, if previously attached.
*/
width: auto;
padding-left: 0;
}
}
<p class="marquee">
<span>
When I had journeyed half of our life's way, I found myself
within a shadowed forest, for I had lost the path that
does not stray. – (Dante Alighieri, <i>Divine Comedy</i>.
1265-1321)
</span>
</p>
No hardcoded values — dependent on paragraph width — have been inserted.
The animation applies the CSS3 transform
property (use prefixes where needed) so it performs well.
If you need to insert a delay just once at the beginning then also set an animation-delay
. If you need instead to insert a small delay at every loop then try to play with an higher padding-left
(e.g. 150%
)
Based on the previous reply, mainly @fcalderan, this marquee scrolls when hovered, with the advantage that the animation scrolls completely even if the text is shorter than the space within it scrolls, also any text length takes the same amount of time (this may be a pros or a cons) when not hovered the text return in the initial position.
No hardcoded value other than the scroll time, best suited for small scroll spaces
.marquee {
width: 100%;
margin: 0 auto;
white-space: nowrap;
overflow: hidden;
box-sizing: border-box;
display: inline-flex;
}
.marquee span {
display: flex;
flex-basis: 100%;
animation: marquee-reset;
animation-play-state: paused;
}
.marquee:hover> span {
animation: marquee 2s linear infinite;
animation-play-state: running;
}
@keyframes marquee {
0% {
transform: translate(0%, 0);
}
50% {
transform: translate(-100%, 0);
}
50.001% {
transform: translate(100%, 0);
}
100% {
transform: translate(0%, 0);
}
}
@keyframes marquee-reset {
0% {
transform: translate(0%, 0);
}
}
<span class="marquee">
<span>This is the marquee text (hover the mouse here)</span>
</span>
The accepted answers animation does not work on Safari, I've updated it using translate instead of padding-left which makes for a smoother, bulletproof animation.
Also, the accepted answers demo fiddle has a lot of unnecessary styles.
So I created a simple version if you just want to cut and paste the useful code and not spend 5 mins clearing through the demo.
http://jsfiddle.net/e8ws12pt/
.marquee {
margin: 0 auto;
white-space: nowrap;
overflow: hidden;
box-sizing: border-box;
padding: 0;
height: 16px;
display: block;
}
.marquee span {
display: inline-block;
text-indent: 0;
overflow: hidden;
-webkit-transition: 15s;
transition: 15s;
-webkit-animation: marquee 15s linear infinite;
animation: marquee 15s linear infinite;
}
@keyframes marquee {
0% { transform: translate(100%, 0); -webkit-transform: translateX(100%); }
100% { transform: translate(-100%, 0); -webkit-transform: translateX(-100%); }
}
<p class="marquee"><span>Simple CSS Marquee - Lorem ipsum dolor amet tattooed squid microdosing taiyaki cardigan polaroid single-origin coffee iPhone. Edison bulb blue bottle neutra shabby chic. Kitsch affogato you probably haven't heard of them, keytar forage plaid occupy pitchfork. Enamel pin crucifix tilde fingerstache, lomo unicorn chartreuse plaid XOXO yr VHS shabby chic meggings pinterest kickstarter.</span></p>