Adjusting the Pace of a CSS Marquee

My CSS marquee effect is working perfectly, but I am having trouble with the speed. The issue arises when the text length varies - shorter text takes longer to scroll while longer text scrolls quickly. This inconsistency is due to the animation duration

animation: marquee 15s linear infinite;

I am looking for a solution to run the marquee at a consistent speed regardless of the text length. If necessary, I am willing to explore using Javascript (although my attempts so far have not been successful).

Below is my current CSS code:

<style>
    /* Make it a marquee */
    .marquee {
        width: 100%;
        margin: 0 auto;
        white-space: nowrap;
        overflow: hidden;
        background-color: #000000;
        bottom: 0px;
        color: white;
    }
    .marquee span {
        display: inline-block;
        padding-left: 100%;
        text-indent: 0;
        animation: marquee 15s linear infinite;
        animation-delay: 10s;
        background-color: #000000;
        color: white;
        bottom: 0px;
    }
    /* Make it move */

    @keyframes marquee {
        0% {
            transform: translate(10%, 0);
        }
        100% {
            transform: translate(-100%, 0);
        }
    }
    /* Make it pretty */

    .scroll {
        padding-left: 1.5em;
        position: fixed;
        font: 50px 'Verdana';
        bottom: 0px;
        color: white;
        left: 0px;
        height: 10%;
    }
</style>

HTML

<div class="marquee">
<p class="scroll marquee"><span id="scrolltext"></span></p>
</div>

Answer №1

Looks like we have a math problem on our hands.

We can solve this by using the formula Time = Distance/Speed

function calcVelocity(velocity) {
  // Time = Distance/Speed
  var spanSelector = document.querySelector('.marquee span');
  var spanLength = spanSelector.offsetWidth;
  var timeTaken = spanLength / velocity;
  spanSelector.style.animationDuration = timeTaken + "s";
}
calcVelocity(100);

function calcHigherVelocity(velocity) {
  // Time = Distance/Speed
  var spanSelector = document.querySelector('.fast.marquee span');
  var spanLength = spanSelector.offsetWidth;
  var timeTaken = spanLength / velocity;
  spanSelector.style.animationDuration = timeTaken + "s";
}
calcHigherVelocity(500);
/* Creating an animated marquee */

.marquee {
  width: 100%;
  margin: 0 auto;
  white-space: nowrap;
  overflow: hidden;
  background-color: #000000;
  bottom: 0px;
  color: white;
}
.marquee span {
  display: inline-block;
  padding-left: 100%;
  text-indent: 0;
  animation: marquee linear infinite;
  animation-delay: 5s;
  background-color: #000000;
  color: white;
  bottom: 0px;
}
/* Setting up movement animation */

@keyframes marquee {
  0% {
    transform: translate(10%, 0);
  }
  100% {
    transform: translate(-100%, 0);
  }
}
/* Styling it nicely */

.scroll {
  padding-left: 1.5em;
  position: fixed;
  font: 50px'Verdana';
  bottom: 0px;
  color: white;
  left: 0px;
  height: 10%;
}
<div class="marquee">
  <span>Lots of text, written in a long sentence to make it go off the screen. Well I hope it goes off the screen</span>
</div>
<br />
<div class="fast marquee">
  <span>Lots of text, written in a long sentence to make it go off the screen. Well I hope it goes off the screen</span>
</div>

Keep in mind that this is a simplified example without considering the actual distance covered, but now you have the basics to figure it out :-)

Let's try another example with two different text lengths moving at the same speed.

function calcSpeed(velocity) {
  // Time = Distance/Speed
  var spanSelector = document.querySelectorAll('.marquee span'),
    i;
  for (i = 0; i < spanSelector.length; i++) {
    var spanLength = spanSelector[i].offsetWidth,
      timeTaken = spanLength / velocity;
    spanSelector[i].style.animationDuration = timeTaken + "s";
  }
}
calcSpeed(100);
/* Creating an animated marquee */

.marquee {
  width: 100%;
  margin: 0 auto;
  white-space: nowrap;
  overflow: hidden;
  background-color: #000000;
  bottom: 0px;
  color: white;
}
.marquee span {
  display: inline-block;
  padding-left: 100%;
  text-indent: 0;
  animation: marquee linear infinite;
  animation-delay: 5s;
  background-color: #000000;
  color: white;
  bottom: 0px;
}
/* Setting up movement animation */

@keyframes marquee {
  0% {
    transform: translate(10%, 0);
  }
  100% {
    transform: translate(-100%, 0);
  }
}
/* Styling it nicely */

.scroll {
  padding-left: 1.5em;
  position: fixed;
  font: 50px'Verdana';
  bottom: 0px;
  color: white;
  left: 0px;
  height: 10%;
}
<div class="marquee">
  <span>Lots of text, written in a long sentance to make it go off the screen. Well I hope it goes off the screen</span>
</div>
<br />
<div class="marquee">
  <span>Well I hope it goes off the screen</span>
</div>

Answer №2

To ensure your sliding element scrolls at the same speed, you can give them equal width. However, this method is not very dynamic.

Alternatively, you can dynamically calculate the speed based on the width of the element. Check out my small demo below:

// Calculate time for 10px movement in seconds
var timeFor10Px = 0.2;
var animationSettings = 'marquee linear infinite';
var $marque = $('.marque');

$marque.each(function() {
  var outerWidth = $(this).outerWidth();
  var calc = outerWidth / 10 * timeFor10Px;
  $(this).css('animation', animationSettings + ' ' + calc + 's');
});
.holder {
  background: black;
  width: 100%;
  color: white;
}

.marque {
  /* removed, see js tab */
  /*animation: marquee 15s linear infinite; */
  display: inline-block;
}

@keyframes marquee {
  from {
    transform: translate(0%);
  }
  to {
    transform: translate(100%);
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="holder">
  <span class="marque marqu1">
  Some nice Text
  </span>
  <br>
  <span class="marque marqu2">
  Some nice Text Lorem Ipsum dolor sit amet.....
  </span>
</div>

Note: @Andrew Bones also suggested a similar solution a bit faster than mine.

Answer №3

Hey there! Below is an example that you may find helpful: Example

If you can provide the proper HTML code details along with your question, we can offer more assistance.

body { margin: 20px; }

.marquee {
  height: 25px;
  width: 420px;

  overflow: hidden;
  position: relative;
}

.marquee div {
  display: block;
  width: 200%;
  height: 30px;

  position: absolute;
  overflow: hidden;

  animation: marquee 5s linear infinite;
}

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

@keyframes marquee {
  0% { left: 0; }
  100% { left: -100%; }
}
<div class="marquee">
  <div>
    <span>You spin me right round, baby. Like a record, baby.</span>
    <span>You spin me right round, baby. Like a record, baby.</span>
  </div>
</div>

It seems to be working properly with the following CSS animation:

 @keyframes marquee {
        0% {
            transform: translate(10%, 0);
        }
        100% {
            transform: translate(-100%, 0);
        }
   }

-------- I have used the below animation which works fine for me ----------
------------------ you can give it a try ---------------------

@keyframes marquee {
        0% {
            transform: translate(0%, 0);
        }
        100% {
            transform: translate(-100%, 0);
        }
   }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What could be causing my Ionic button to not initialize in the expected state while using ngIf with a boolean property connected to an Ionic checkbox?

I'm currently in the process of setting up a list of ingredients with checkboxes and conditional buttons, but I'm facing some challenges with the default state. Ideally, I only want the button to be visible when the checkbox is unchecked so that ...

Utilizing Vue to create multiple components and interact with Vuex state properties

I am currently learning Vue and using it with Vuex (without Webpack). However, I am facing some challenges while implementing a simple example and the documentation is not very clear to me. One issue I encountered is that I cannot access the Vuex st ...

Confirming the presence of an image using jQuery without enforcing it as mandatory

Situation: In my setup, I maintain a database that holds details about various items. Currently, I utilize a dynamic form to retrieve and exhibit the existing information on any item stored in the database. Any modifications made on the form are promptly ...

End of ImageButton tag

I am currently working on this code : <div runat="server" class="slide"> <img src="images/picto_detail.gif" onclick='<%# Eval("CampagneRappelId","hideshow(\"details{0}\")")%>' /> <div id='details<%# Eval("C ...

Displaying data from a PHP form

I'm working on a table that is populated with data from my controller. The issue I am facing is that only the first record, in this case Sephen C. Cox, does not redirect me when I click the "add employee" button. For all other records, the button work ...

What is the best way to display a modal box using NodeJs on the server side?

I recently created a contact page on my website where users can fill out a form. Upon submitting the form, I capture the information using a post method in my server.js file. If everything is correct, I want to display a modal box on the contact page to co ...

Unable to locate the JavaScript files within the NextJs and ReactJs project

I've encountered an issue when trying to import js files (which are libraries) in my project. I am currently using NextJS version 14.1.3 and ReactJS version 18.2.0. You can find the path to these files here Here is a glimpse of the project structure ...

Utilizing Z-index for the arrangement of DIVs and elements in a webpage

I am facing an issue with my website design where the content section overlaps with the banner. This causes the content section to be hidden behind the banner, and I need it brought to the front. The problem specifically lies with the search element on my ...

Switching the ASP.NET XHTML Display Mode

I have been given HTML code from a designer to create a master page. The doctype in the HTML is set to HTML 4.0 Strict. The meta tags in the HTML do not contain closing end tags (they end with > instead of />) and the HTML is compliant when checked using ...

Is it possible for PHP to dynamically load a file based on a condition set in JavaScript?

I am attempting to dynamically insert a PHP include onto the page once the user scrolls to a specific part of the page. Is this feasible? For example: var hasReachedPoint = false; $(window).scroll(function() { var $this = $(this); if ($this.scrollTo ...

Sending data to and retrieving data from a server

Just a quick query. I've been using ajax POST and GET methods to send JSON data to a server and then fetch it back. However, I'm facing some confusion while trying to extract JSON information from the GET call. getMessage = function(){ $.ajax ...

Invisible boundary line within the column

My task involves creating a table using div elements. The layout of the table includes two columns structured as follows: <div> <div class = "columnborder"><span>Some text for column 1</span></div> <div><span>Some ...

Send a signal to a space, leveraging the distinct characteristics of each socket as input parameters

I am looking to send a function to a group of sockets, with each socket receiving the function along with a specific parameter unique to that particular socket. In my coding scenario, this distinctive variable represents the player's number. As socke ...

Using JQuery to switch out images that do not have an ID or class assigned

Currently, I am using a Google Chrome Extension to apply an external theme to a website. Unfortunately, the logo on the site does not have an ID or class that can be used to call it. I am searching for a solution to replace it with a different image. My ...

Utilizing a fallback option for HTML5 video with a flash player and the ability to manipulate the

My dilemma involves an HTML5 video where I am utilizing jquery to interact with the player using the code snippet: video.currentTime += 1;. However, when Internet Explorer switches to Flash plugins, my JQ commands cease to function. How can I manage and co ...

Clear Vuex state upon page refresh

In my mutation, I am updating the state as follows: try { const response = await axios.put('http://localhost:3000/api/mobile/v3/expense/vouchers/form_refresh', sendForm, { headers: { Accept: 'application/json', 'C ...

Is there a way to upload files in AngularJS without using AJAX or jQuery?

Currently, I am looking to create a gallery that allows for the uploading of multiple images. While I have come across some options that utilize ajax to immediately send the files, I prefer a solution that involves form submission. In addition, I would li ...

Tips for choosing a dynamically generated ajax element

Question for you: I have a snippet of HTML code that looks like this: <li class='entry'> <div class='entryContent'> <p class='entryText'>Entry text></p> <a href="#" c ...

React error: "Unable to locate property 'bind' within the undefined"

After reviewing several solutions, I'm still struggling to understand. Below is my code snippet: // userInputActions.js ... export function dummy() { console.log('dummy function called'); } ... // *userInputPage.js* import * as use ...

Populate a pair of div elements using just one AJAX request

Currently, I am attempting to use the load() function to ajaxly load two separate divs, #follow-x and #follow-y, by clicking a button. The approach I have taken is as follows within the success function of my code snippet. However, this method does not see ...