How to Create a Scrolling Call to Action Marquee Button

A nice simple tutorial this week. We’re creating a… marquee button! OK – it’s not just any ol’ button, but a scrolling call to action button that (in my opinion) should draw your users in, and hopefully gains you that click to contact you, buy a product, or generally lead to some kind of important action.

I seen this marquee button effect while perusing the wonderful website of Jordon Fried. If you scroll to the bottom of the website, there is a pretty nifty call to action button which scrolls some text in a loop.

Here I will deconstruct this marquee button and come up with my own version. Let’s go!

The Call to Action marquee button demo is found here.

1. Let’s Setup the HTML, CSS, and JavaScript Files

  • index.htm
  • style.css
  • main.js
<!doctype html>
	<meta charset="UTF-8">
	<title>Marquee Call to Action Button | Frontend Hero</title>
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<link rel="shortcut icon" href="" type="image/x-icon">
	<link rel="stylesheet" href="style.css">

   <div id="feh-marquee-wrapper"></div>
   <script src="main.js"></script>
* { padding: 0; margin: 0; box-sizing: border-box; }
html, body { height: 100%; font-family: uniform; }

body { 
   display: flex;
   justify-content: center;
   align-items: center;
   height: 100%;
let matchMediaMobile = window.matchMedia("(pointer:coarse)");


After including our style.css, and main.js files, here is a little rundown on what e have done so far.

  • index.htm <div id="feh-marquee-wrapper"></div> is our button wrapper.
  • style.css – Reset the page’s margins, paddings etc, and centred our button.
  • main.js – As I only want this marquee animation to to run on typical desktop computers, (non touch devices), the first code block we have is checking if the pointing device uses something coarse, such as as a finger as the pointing device.

That’s our files ready to go. Next, we are going to create the #feh-marquee-wrapper ‘marquee button’.

2. Creating Our Marquee Button

As we can see below, our ‘marquee button’ has a few elements inside.

  • index.htm
  • style.css
<div id="feh-marquee-wrapper">
   <div id="feh-marquee">
      <a href="/">
         <span class="feh-text">Contact Us Today</span>
      <a href="/">
         <span class="feh-text">Contact Us Today</span>
      <a href="/">
         <span class="feh-text">Contact Us Today</span>
      <a href="/">
         <span class="feh-text">Contact Us Today</span>
#feh-marquee-wrapper {
   position: relative; 
   overflow: hidden;
   display: flex;
   background: #331a9c;
   border: 7px solid #817ac4;
   max-width: 350px;
   border-radius: 100px;
   #feh-marquee {
      display: flex;
      #feh-marquee a {
         color: #fff;
         font-weight: 800;
         width: 320px;
         font-size: 22px;
         padding: 30px 25px;
         text-transform: uppercase;
         text-decoration: none;
         position: relative;
      #feh-marquee a:before {
         content: "";
         position: absolute;
         width: 70px;
         height: 15px;
         background: url("line.svg") no-repeat;
         bottom: 12px;
         right: 72px;
      #feh-marquee a:after {
         content: "";
         position: absolute;
         width: 50px;
         background: url(phone.svg) no-repeat;
         top: 50%;
         right: 5px;
         height: 50%;
         transform: translateY(-50%);


Let’s go through and see what’s going on here.

  • #feh-marquee-wrapper is essentially our button. We give it a fixed size, and hide anything that overflows from inside.
  • The #feh-marquee element is where the magic will happen. This will with be the scrolling element.
  • Inside of #feh-marquee, we have four anchor elements with a width of 320px. This width was chosen to accommodate the length of our text and associated icon.

An idea of what is going behind the scenes is below.

2. Scrolling Our Marquee Element.

Now we just have to animate our #feh-marquee element.

  • main.js
const marquee = document.getElementById('feh-marquee');

let translateValue = 0;  // start value
const step = 0.015;  // the step for smoother increment
let intervalId = null;

function startAnimation() {
   if (intervalId === null) {
      intervalId = setInterval(function() { = "translate3d(" + translateValue.toFixed(3) + "%, 0, 0)";
         translateValue -= step;
         if (translateValue <= -25) {
            translateValue = 0;
      }, 0.5); 


And that’s our marquee button ready to go!


The main part of this JavaScript code is that we are just manipulating the translate3d property of the #feh-marquee element to move from 0% to -25% (right to left). Once the translateValue reaches -25%, it resets to 0, and starts the process again.

Also, for any eagle eyed visitors here, you will notice that we are only scrolling the width of the first anchor element. Once the translateValue reaches 25% (one quarter of our anchor elements), the #feh-marquee just shifts back to the beginning. It looks so fluid you shouldn’t be able to spot anything.

A video of this is seen in the video below:

3. Pause the Marquee Scrolling When Hovering

Last thing I’d just like to do is pause the scrolling when we hover over the ‘button’. We’ll add two event listeners below to achieve this by clear the intervalId, and setting it to NULL.

  • main.js
marquee.addEventListener('mouseover', function() {
   intervalId = null; 

marquee.addEventListener('mouseout', startAnimation);

4. Conclusion & Code

And that’s it, a short and sweet way to draw attention to your button. You can grab the code here. Any feed back, please let me know down below.

If this tutorial has helped you, I wouldn't say no to a coffee as a tip ☕️

Buy Me a Coffee at

One thought on "How to Create a Scrolling Call to Action Marquee Button"

  1. I used this on my website, it works perfectly on desktop, but often when viewed on mobile the text moves very slow.

    How can I fix this?

Leave a Reply

Your email address will not be published. Required fields are marked *