How to Create a Marquee Using CSS or JavaScript

How to create a marquee using CSS or Javascript

Here are a few ways you can achieve the result, you can choose the one u like the best.

  • HTML marquee tag
  • CSS animation and text-indent
  • CSS animation and position relative
  • JS vanilla (no libs)
  • JS Jquery animate

/* Vanilla JS */
var rightJS = { init: function(){ rightJS.Tags = document.querySelectorAll('.rightJS'); for(var i = 0; i < rightJS.Tags.length; i++){ rightJS.Tags[i].style.overflow = 'hidden'; } rightJS.Tags = document.querySelectorAll('.rightJS div'); for(var i = 0; i < rightJS.Tags.length; i++){ rightJS.Tags[i].style.position = 'relative'; rightJS.Tags[i].style.right = '-'+rightJS.Tags[i].parentElement.offsetWidth+'px'; } rightJS.loop(); }, loop: function(){ for(var i = 0; i < rightJS.Tags.length; i++){ var x = parseFloat(rightJS.Tags[i].style.right); x ++; var W = rightJS.Tags[i].parentElement.offsetWidth; var w = rightJS.Tags[i].offsetWidth; if((x/100) * W > w) x = -W; if (rightJS.Tags[i].parentElement.parentElement.querySelector(':hover') !== rightJS.Tags[i].parentElement) rightJS.Tags[i].style.right = x + 'px'; } requestAnimationFrame(this.loop.bind(this)); }};window.addEventListener('load',rightJS.init);
/* JQUERY */
$(function(){ var rightJQ = { init: function(){ $('.rightJQ').css({ overflow: 'hidden' }); $('.rightJQ').on('mouseover',function(){ $('div', this).stop(); }); $('.rightJQ').on('mouseout',function(){ $('div', this).animate({ right: '100%' }, 14000, 'linear' ); }); rightJQ.loop(); }, loop: function(){ $('.rightJQ div').css({ position: 'relative', right: '-100%' }).animate({ right: '100%' }, 14000, 'linear', rightJQ.loop); } }; rightJQ.init();});
marquee { background: #0089fa; }
.rightTI { background: #ff002b; white-space: nowrap; overflow: hidden; animation: marquee 18s linear infinite;}.rightTI:hover { animation-play-state: paused;}@-webkit-keyframes marquee { 0% {text-indent: 100%;} 100% {text-indent: -100%;}}
.rightCSS { background: #a35dc1; overflow: hidden;} .rightCSS div { position: relative; animation: CSSright linear 18s infinite;} @keyframes CSSright { 0% { right: -100% } 100% { right: 100% }}.rightCSS:hover div { animation-play-state: paused;}
.rightJS { background: #ffa900; }
.rightJQ { background: #00a753; }
.li { float: left; width: 80%; padding: 1%; margin: 1% 10%; height: 20px; border-radius: 0.5em; box-shadow: 0 0.1em 0.5em;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><marquee class="li" direction=”right” onmouseover="stop()" onmouseout="start()">★ HTML tag <marquee> ★</marquee><div class="rightTI li">★ CSS animation and text-indent ★</div><div class="rightCSS li"><div>★ CSS animation and position relative ★</div></div><div class="rightJS li"><div>★ pure javascript ★</div></div><div class="rightJQ li"><div>★ Jquery animate ★</div></div>

How to create a marquee that appears infinite using CSS or Javascript

You are so close. Hopefully the demo below is self explainable but, basically you need to start your key frames at -100% your marquee's width then end at 100% so it's off screen before it restarts.

Hope this helps!

[edit] added continuous scrolling

body {   margin: 0;  font-family: "UniversLTPro-Ex";  font-size: 30px;}
a { text-decoration: none; color: #000;}
.marquee { height: 35px; width: 100%;
overflow: hidden; position: relative; background-color: #e9e5fb; border-top: 1px solid black; border-bottom: 1px solid black; padding: 8px 0 4px 0;}

/* would need to be adjusted depending on time */.marquee .marqueeone{ animation: marquee 10s linear infinite}
.marquee .marqueetwo{ animation: marquee 10s linear 2.5s infinite }
.marquee .marqueethree{ animation: marquee 10s linear 5s infinite}
.marquee .marqueefour{ animation: marquee 10s linear 7.5s infinite}
/* even out the elements */.marquee div { position: absolute; width: 100%; left: 100%; height: 40px; display: flex; justify-content: space-between;}
.marquee:hover div { animation-play-state: paused;}
/* add delay at the end of animation so you dont start while another div is going */@keyframes marquee { 0% { left: 100%; } 50% { left: -100%; } 100% {left: -100%}}
/* @import must be at top of file, otherwise CSS will not work */@import url("//hello.myfonts.net/count/3909a7");
@font-face {font-family: 'UniversLTPro-Ex';src: url('webfonts/3909A7_0_0.eot');src: url('webfonts/3909A7_0_0.eot?#iefix') format('embedded-opentype'),url('webfonts/3909A7_0_0.woff2') format('woff2'),url('webfonts/3909A7_0_0.woff') format('woff'),url('webfonts/3909A7_0_0.ttf') format('truetype');}
<div class="marquee">    <div class="marqueeone"><a href="#">twitter</a>                   <a href="#">instagram</a>                    <a href="#">pinterest</a>                   <a href="#">spotify</a>                   <a href="#">magazine</a>                  </div>    <div class="marqueetwo"><a href="#">twitter</a>                   <a href="#">instagram</a>                    <a href="#">pinterest</a>                   <a href="#">spotify</a>                   <a href="#">magazine</a>   </div>         <div class="marqueethree"><a href="#">twitter</a>                   <a href="#">instagram</a>                    <a href="#">pinterest</a>                   <a href="#">spotify</a>                   <a href="#">magazine</a>   </div>                   <div class="marqueefour"><a href="#">twitter</a>                   <a href="#">instagram</a>                    <a href="#">pinterest</a>                   <a href="#">spotify</a>                   <a href="#">magazine</a>         </div></div>

How to create running text (marquee) using CSS

You could animate both transform and simultaneously the margin-left so that the animation will end exactly at the text-end:

.marquee {  position: relative;  overflow: hidden;  background: rgb(161, 61, 175);  color: #fff;}
.marquee span { display: inline-block; min-width: 100%; /* this is to prevent shorter text animate to right */ white-space: nowrap; font-size: 2.5em; animation: marquee 4s ease-in-out forwards;}
@keyframes marquee { from {transform: translateX(0); margin-left: 0;} to {transform: translateX(-100%); margin-left: 100%; }}
<h1 class="marquee">  <span>The only thing that matters now is everything You think of me</span></h1>
<p class="marquee"> <span>Beware of short texts!</span></p>

How to use CSS to achieve the marquee effect?

We can achieve this with "Slick Carousel" here is an example.

.marquee-item {
padding: .5em 1em;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.css" integrity="sha512-yHknP1/AwR+yx26cB1y0cjvQUMvEa2PFzt1c9LlS4pRQ5NOTZFWbhBig+X9G9eYW/8m0/4OXNx8pxJ6z57x0dw==" crossorigin="anonymous" referrerpolicy="no-referrer" />

<div class="marquee">
<div class="marquee-item">your content</div>
<div class="marquee-item">your content</div>
<div class="marquee-item">your content</div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.js" integrity="sha512-XtmMtDEcNz2j7ekrtHvOVR4iwwaD6o/FUJe6+Zq+HgcCsk3kj4uSQQR8weQ2QVj1o0Pk6PwYLohm206ZzNfubg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
$(document).ready(function(){
$('.marquee').slick({
arrows: false,
autoplay: true,
autoplaySpeed: 0,
cssEase: 'linear',
centerMode: true,
dots: false,
infinite: true,
speed: 3000,
variableWidth: true,
});
});
</script>

Why do I use javascript to make the marquee effect and it will shake when it is running?

I guess, you can achieve this this css transform. But it will work , if the last parameter should be the same as the div's height in the slideLine function and control the speed with the fourth parameter.

css

:root {
--height: 60px; /* Same as last parameter in function */
}
#ann_box {
min-width: 400px;
height: var(--height);
overflow: hidden;
border: 1px solid rgba(255, 0, 0, 0.4);
}

.ann {
height: inherit;
text-align: center;
line-height: 1; /* new line */
/* height / 2 - 10px = transform to define center */
transform: translateY(calc(var(--height) / 2 - 10px));
}

javascript

slideLine('ann_box', 'div', 2000, 25, 60); // The last parameter should be 60

function slideLine(box, stf, delay, speed, h) {
var slideBox = document.getElementById(box);
var delay = delay || 1000,
speed = speed || 50,
h = h || 20;
var tid = null,
pause = false;
var s = function() {
tid = setInterval(slide, speed);
};
var slide = function() {
if (pause) return;
slideBox.scrollTop += 1;
if (slideBox.scrollTop % h == 0) {
clearInterval(tid);
slideBox.appendChild(slideBox.getElementsByTagName(stf)[0]);
// slideBox.scrollTop = 0;
setTimeout(s, delay);
}
};
slideBox.onmouseover = function() {
pause = true;
};
slideBox.onmouseout = function() {
pause = false;
};
setTimeout(s, delay);
}
slideLine('ann_box', 'div', 2000, 10, 60); // The last parameter should be 60
*,
::after,
::before {
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
height: 100vh;
background-color: hsl(201, 27%, 10%);
color: white;
display: flex;
flex-flow: column;
align-items: center;
justify-content: center;
}
:root {
--height: 60px; /* Same as last parameter in function */
}
#ann_box {
min-width: 400px;
height: var(--height);
overflow: hidden;
border: 1px solid rgba(255, 0, 0, 0.4);
}

.ann {
height: inherit;
text-align: center;
line-height: 1; /* new line */
/* height / 2 - 10px = transform to define center */
transform: translateY(calc(var(--height) / 2 - 10px));
}

/* height 30px = transform 5px */
/* height 40px = transform 10px */
/* height 50px = transform 15px */
/* height 60px = transform 20px */
<div id="ann_box">
<div id="a1" class="ann">HTML</div>
<div id="a2" class="ann">CSS</div>
<div id="a3" class="ann">Vue</div>
<div id="a4" class="ann">javascript</div>
</div>

How do I make an Infinite marquee with JS?

Your items are overlapping because you're not allowing any lerping diffing when the items should switch positions.

The current value should never equal the target value. If the values match, than the current value needs to catch up the target — giving that erratic movement and wrong calculations, additionally aggravated for the two sibling elements which should be perfectly in sync to give that immediate snap-back, perceived as a fluid continuous motion.

Solution

  • Instead of animating two (or more) children independently,
    animate only the parent .loop-container.
  • The container should be as wide as one child element exactly.
  • "Push" one child element to the far left using position: absolute; left: -100%
  • To allow the target value to be always greater than the current value:
    when the target value is greater than 100 — set current to the negative difference of the two values, and target to 0

Demo time:

const lerp = (current, target, factor) => current * (1 - factor) + target * factor;

class LoopingText {
constructor(el) {
this.el = el;
this.lerp = {current: 0, target: 0};
this.interpolationFactor = 0.1;
this.speed = 0.2;
this.direction = -1; // -1 (to-left), 1 (to-right)

// Init
this.el.style.cssText = `position: relative; display: inline-flex; white-space: nowrap;`;
this.el.children[1].style.cssText = `position: absolute; left: ${100 * -this.direction}%;`;
this.events();
this.render();
}

events() {
window.addEventListener("scroll", () => this.lerp.target += this.speed * 5);
}

animate() {
this.lerp.target += this.speed;
this.lerp.current = lerp(this.lerp.current, this.lerp.target, this.interpolationFactor);

if (this.lerp.target > 100) {
this.lerp.current -= this.lerp.target;
this.lerp.target = 0;
}

const x = this.lerp.current * this.direction;
this.el.style.transform = `translateX(${x}%)`;
}

render() {
this.animate();
window.requestAnimationFrame(() => this.render());
}
}

document.querySelectorAll(".loop-container").forEach(el => new LoopingText(el));
/* QuickReset */ * { margin: 0; box-sizing: border-box; }

body { min-height: 400vh; /* force some scrollbars */ }

.hero-section {
position: relative;
top: 50vh;
overflow: hidden;
font: 900 9vw/1 sans-serif;
min-height: 100vh;
}
<section class="hero-section">
<div class="loop-container">
<div class="item">Infinite Horizontal Looping Text </div>
<div class="item">Infinite Horizontal Looping Text </div>
</div>
</section>

Creating a marquee that appears infinite with CSS and is responsive

You are on the right track having more than one copy of the texts.

But you can simplify things - think of all the text stretched out in a line in just one banner. You have an even number of copies, so if you translate the whole banner to the left (negative X direction) by 50% on each iteration of the animation then start back again, where second half had got to (x=0) will be overwritten by the first half and it will all appear continuous.

You can probably get away with just two copies, it depends on how spread out you want things to be on really wide screens, but I've left the 4 copies in there just in case you need them.

.banner {
height: 40px;
position: relative;
overflow: hidden;
font-family: Roobert;
font-style: normal;
font-weight: normal;
font-size: 24px;
line-height: 36px;
min-width: 200vw;
/* ADDED */
animation: bannermove 40s linear infinite;
display: flex;
justify-content: space-between;
}

.banner:hover {
animation-play-state: paused;
}

@keyframes bannermove {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-50%);
}
}

.banner div {
padding: 10px;
/* just to ensure there is space between even on small devices */
}
<div class="banner">
<div>Dragon</div>
<div>Element</div>
<div>Charger</div>
<div>ZipDrive</div>
<div>LightHouse</div>
<div>Exxtra</div>
<div>Hub</div>
<div>iOS15</div>
<div>File Drive</div>
<div>Netherverse</div>
<div>CLpool</div>
<div>Dragon</div>
<div>Element</div>
<div>Charger</div>
<div>ZipDrive</div>
<div>LightHouse</div>
<div>Exxtra</div>
<div>Hub</div>
<div>iOS15</div>
<div>File Drive</div>
<div>Netherverse</div>
<div>CLpool</div>
<div>Dragon</div>
<div>Element</div>
<div>Charger</div>
<div>ZipDrive</div>
<div>LightHouse</div>
<div>Exxtra</div>
<div>Hub</div>
<div>iOS15</div>
<div>File Drive</div>
<div>Netherverse</div>
<div>CLpool</div>
<div>Dragon</div>
<div>Element</div>
<div>Charger</div>
<div>ZipDrive</div>
<div>LightHouse</div>
<div>Exxtra</div>
<div>Hub</div>
<div>iOS15</div>
<div>File Drive</div>
<div>Netherverse</div>
<div>CLpool</div>
</div>


Related Topics



Leave a reply



Submit