5

I need to create two marquees (one with a repeating image and one with repeating links) that span the browser window at any size; the marquee items need to be displayed from the start and not take a few seconds to appear on screen and each of them need to be about 20px/30px apart. When a user hovers over it, the marquee needs to stop moving across the page.

I'm creating a website for a client and on one page we've decided on having a marquee to display the logo and on another, a marquee to display links to the client's social media. I'm unsure of how to calculate the necessary duration of the animation, based off the size of the text or image to make it appear infinite. I've looked into and tried out CSS options and I've asked around only to find that Javascript is usually recommended for this. I've just begun diving into Javascript, so I'm pretty clueless with where to start on this project. This is actually pretty similar to what I need: https://stackoverflow.com/a/45103608/11623961. This is an example of what I'm trying to achieve: http://maxsiedentopf.com/work-2 (only the one at the bottom, but with no overlap from the left side; simply moving from left to right). This is what I was trying to use to achieve the desired effect: https://codepen.io/jamesbarnett/pen/kfmKa.

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;
}

.marquee div {
  display: inline-block;
  width: 300%;
  height: 40px;

  position: absolute;
  overflow: hidden;

  animation: marquee 12s linear infinite;
}

.marquee span {
  float: left;
  width: 25%;
}

@keyframes marquee {
  0% { left: 0; }
  100% { left: -150%; }
}
        <div class="marquee">
            <div>
                <span><a href="#">twitter</a></span>
                <span><a href="#">instagram</a></span> 
                <span><a href="#">pinterest</a></span>
                <span><a href="#">spotify</a></span> 
                <span><a href="#">magazine</a></span>
            </div>
        </div>

Obviously, there are a lot of problems with what I tried to do. The marquee does not appear infinite, I have not figured out how to pause on hover, the items are too far apart. Any help would be greatly appreciated. Thank you!

lucygoosey
  • 127
  • 1
  • 2
  • 9
  • Does this answer your question? [How to create a marquee that appears infinite using CSS or Javascript](https://stackoverflow.com/questions/56639772/how-to-create-a-marquee-that-appears-infinite-using-css-or-javascript) – kontur Jan 20 '22 at 14:49

3 Answers3

2

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 &lt;marquee&gt; ★</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>
rafaelcastrocouto
  • 11,781
  • 3
  • 38
  • 63
  • 2
    Thank you! This is really helpful and I appreciate the time you took to put this together for me. I'm still struggling with a few other things: I don't understand how to make the marquee begin on screen, I don't understand how to make it appear without a gap between my last and first item (the magazine and twitter link) when the last item reaches the left side of the marquee, and I don't understand how to make spacing between the links even. If you have time to share insight on any of those things, I'd appreciate it. If not, thanks again for getting me on the right track with this example. – lucygoosey Jun 10 '19 at 17:38
  • I'm away from my note, but I will try to solve the issues you present asap. In the meantime you can open a new question and post it here as a comment so I might take a look. – rafaelcastrocouto Jun 11 '19 at 21:38
  • 1
    Thanks so much! This is the new post: https://stackoverflow.com/questions/56639772/how-to-create-a-marquee-that-appears-infinite-using-css-or-javascript – lucygoosey Jun 17 '19 at 22:53
  • I just saw you got a nice answer there so I'm glad I could be part of the help! – rafaelcastrocouto Jun 20 '19 at 00:09
  • 1
    Yes! Thank you for helping me get on the right track! – lucygoosey Jun 20 '19 at 15:05
0

Using CSS is always the best option, but for your requirement, it needs to pause on hover and resume from the last stopped position, which is not possible using CSS. So make use of Javascript for moving so. Set a timeInterval which changes left property of the element to move the element to left in intervals and onhover clear the timeinterval such that the animation will stop at the last left value. onmouseout again start the interval which will continue the animation.

Ajay Varghese
  • 741
  • 4
  • 14
0

lucygoosey ur problem is solve and if you want more than u should give more effort on that

body { 
  margin: 0;
  font-family: "UniversLTPro-Ex";
  font-size: 30px;
}

a {
    text-decoration: none;
    color: #000;
}

.marquee {
  height: 35px;
  width: 300%;
  position: relative;
  padding: 8px 0 4px 0;
  border: none;
}

.marq{
  background-color: #e9e5fb;
  border-top: 1px solid black;
  border-bottom: 1px solid black;
  
}


.marquee span {
  float: left;
  width: 300px;
}

@keyframes marquee {
  0% { left: 0; }
  100% { left: -150%; }
}
<div class="marq">  
<marquee onmouseover="this.stop();" onmouseout="this.start();">
           <div class="marquee">
                <span><a href="#">twitter</a></span>
                <span><a href="#">instagram</a></span> 
                <span><a href="#">pinterest</a></span>
                <span><a href="#">spotify</a></span> 
                <span><a href="#">magazine</a></span>
          </div>
 </marquee>     
</div>

Read more about marquee tag

Marquee tag documentation - here

Kiran Mistry
  • 2,614
  • 3
  • 12
  • 28
  • Thank you for taking time to demonstrate how to pause the marquee! I was unable to find a solution like that myself. As for more effort, I am a designer and not a programmer and this is something I've never done before. I've spent hours scouring the web for solutions and more hours on many failed iterations of what I wanted. The code I shared was the closest to a simple solution to my problem. If I didn't already put effort into finding a solution, I wouldn't have posted. I understand the marquee tag info you linked to, but I'm still lost on the other requirements I mentioned in my question. – lucygoosey Jun 10 '19 at 17:06