I have a client of mine that’s using a marquee, I know, I know it’s a depreciated tag and frankly shouldn’t be used. This is a personal website of his, and he’s been a client of mine for a while, so I figured I’d implement the marquee but do so in a modern way without using depreciated tags. I have seen lots of different solutions for this. I generally use flexbox for something like this because it doesn’t rely on javascript or jQuery, but flexbox marquee examples often rely on a hard-coded width to calculate the speed of keyframe animations.
So, long story short, I am seeking to create a marquee that’s responsive, but the speed doesn’t change based on how much content it’s scrolling (I know it’s alot to ask). My client also writes a ton of content (I’ve tried to convince him otherwise, but he still does it).
I put something together that’s very close to being a solution. It doesn’t use flexbox, but it does resize well without changing the speed…I’m getting pretty close to what I’m after. At the end of the day I don’t have to use flexbox, so if all the other boxes are checked I’m good with that!
This is the code I’m using:
<div class="pizza">
<p class="duck"><span class="red">Start Lorem ipsum dolor sit amet consectetur adipisicing elit. Ut sed placeat aperiam quod nostrum itaque blanditiis soluta! Aliquid fuga molestias aut magni, pariatur doloremque, voluptas ipsa nobis ipsum voluptatibus end.</span> <span class="green">Start Lorem ipsum dolor sit amet consectetur adipisicing elit. Ut sed placeat aperiam quod nostrum itaque blanditiis soluta! Aliquid fuga molestias aut magni, pariatur doloremque, voluptas ipsa nobis ipsum voluptatibus end.</span> <span class="blue">Start Lorem ipsum dolor sit amet consectetur adipisicing elit. Ut sed placeat aperiam quod nostrum itaque blanditiis soluta! Aliquid fuga molestias aut magni, pariatur doloremque, voluptas ipsa nobis ipsum voluptatibus end.</span>.</p>
</div>
The CSS:
.green {
color: green;
}
.red {
color: red;
}
.blue {
color: blue;
}
.pizza {
line-height: 60px;
font-size: 16px;
overflow: hidden;
position: relative;
white-space: nowrap;
}
p.duck {
animation: scroll-left 20s linear infinite;
}
@keyframes scroll-left {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(-100%, 0);
}
}
p.duck:hover {
animation-play-state: paused;
}
Fiddle: https://jsfiddle.net/L7kbhyg6/
I added some spans so the problem is easier to see, but basically not all of the text is scrolling. I see red, then green, then the marquee jumps and it starts over again. Not sure how to get it to display all of my content.
Thanks,
Josh
3
Answers
I did some additional research and found an example using the gsap JS library.
CSS:
HTML:
JS:
This gives me the flexibility of adding or reducing the content without affecting the speed. This one is also responsive and restarts scrolling when the browser is resized.
Thanks,
Josh
To ensure smooth scrolling regardless of viewport size or size of the scrolled elements, have a second copy.
The transform is then to -50% not -100% (so the second copy gets to the left hand side then gets replaced by the first and so on, making it look continuous).
I can’t see the need for JS unless you want to do something fancier with speed.
UPDATE: OK, we want a constant speed whatever the client puts in the marquee.
For this you do need a couple of lines of JS as CSS doesn’t ‘know’ the width of the overall text.
This snippet gets CSS to calculate the overall length of time for one animation cycle. This depends on the speed you want the marquee to flow (a constant across all viewport sizes and amount of text) and the actual width of the overall marquee.
The p.duck is set with flex, justify-content set so there is equal spacing between all elements, and a minimum width so even if the client goes down to a single character in each element the marquee will cover the viewport.
well here it is..
[ Edit : changed to take care on screen resizing masking]
[ Edit : first version with unique
ID
=> code for only one "marquee" per page]