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

Leveraging the power of CSS id selectors to customize the appearance of a Grid

In my current CSS file, I have defined two id selectors: #TableHead { font-family: Arial, Helvetica, sans-serif; font-size:11px; font-weight: bold; color: #000000; border-top-width: thin; border-top-style: solid; border-top-color: #A9AAAA; border-bottom-w ...

What are the methods for altering the material of a glTF model using THREE.js?

I've created a model using Blender and baked all the lighting and textures. However, when I import it into THREE.js in .glb format, it automatically uses the standard material. While this may work in certain cases, my concern is that I want to retain ...

Update the URL and content in Django dynamically

When accessing a json response from my Django backend via the URL /inbox/<str:username>, all messages in the conversation with that user are retrieved. The issue arises on the inbox page, where both threads and chatbox are displayed together, similar ...

Conceal any ng-repeat elements that do not contain corresponding grandchildren within two levels of nested ng-repeats

Apologies for the enigmatic title, but the issue at hand is quite cryptic ¯\_(ツ)_/¯ I'm dealing with a complex problem involving 3 nested ng-repeats to display Google Analytics' account structure. Within this structure are multiple acco ...

Python_scraping <li style="display: hidden;">

I am having trouble extracting the text from the following HTML using Selenium in Python. <div class="tt"> <ul style="list-style-type:none" id="abs2"> <li> Funeral rites have undergone significant changes due to the ...

Error: Unable to locate module: Unable to locate '@material-ui/core/Container'

Encountering an error in the browser: Error message: Module not found: Can't resolve '@material-ui/core/Container' The search for the component is directed towards my components directory instead of node_modules. Unfortunately, changing ...

Altering CSS attribute values using a random number generator

Is there a way to randomly change the animation-duration attribute in the following CSS code? I want it to range from 0 to 1. @keyframes blink { 50% { border-color: #ff0000; } } p{ animation-name: blink ; animation-duration: 0.1s ; animatio ...

Looking to install nodemon for Node.js on macOS? If you're encountering a "command not found" error, here's

After installing nodemon using the command npm install -g nodemon, I encountered a Permissions issue. To resolve this, I used the sudo npm install -g nodemon command. However, when attempting to run the "nodeman" command, I kept receiving an error that s ...

AngularJS radio buttons can now be selected as multiple options

Currently, I am in the process of learning angular and have implemented a radio button feature in my program. However, I have encountered a perplexing issue that I cannot seem to explain. <!DOCTYPE html> <html> <head> <meta ch ...

The table is too large for the parent div in which it is placed, causing

Check out this example I have for putting a table in a div and making it fill the div: ex1_jsfiddle table { font-family: arial, sans-serif; border-collapse: collapse; width: 100%; height: 100%; table-layout: fixed; } td, th { border: 1px sol ...

A method for automatically refreshing a webpage once it switches between specific resolutions

On my page www.redpeppermedia.in/tc24_beta/, it functions well at a resolution of over 980px. However, when the resolution is brought down to 768px, the CSS and media queries alter the layout. But upon refreshing the page at 768px, everything corrects itse ...

Having trouble accessing undefined properties in ReactJs? Specifically, encountering issues when trying to read the property "name"?

I am facing an issue with using the data in my console even though I can log it. The structure of my data object is as follows: {_id: '616bf82d16a2951e53f10da4', name: 'abd', email: '[email protected]', phone: '123456789 ...

Instructions for including dependencies from a globally installed npm package into a local package

I've noticed that although I have installed a few npm packages globally, none of them are showing up in any of my package.json files. What is the recommended npm command to automatically add these dependencies to all of my package.json files? ...

"Include a song in a playlist without the need to sign in - Spotify API

I am looking to create a playlist where users on my website can collaborate, even if they are not logged into Spotify. I want these users to have the ability to add songs to the playlist. Below is the Ajax code snippet that I have: $.ajax({ dataType: &a ...

Ensuring proper functionality of JQModal when displayed above an iframe with the usage of ?wmode=

Here's an interesting one... I'm currently working on a site with JQModal and everything seems to be functioning properly except for the fact that the iframe appears on top of the modal. An easy fix is to append ?wmode=opaque at the end of the ...

Is there a method to incorporate JS code from one JS file into another JS file within a NodeJS application?

Currently, I am in the process of developing a web application using NodeJS. The basic idea behind my approach is to have a primary structure where different tools can be added based on specific requirements for the app. My challenge lies in having my mai ...

Authentication through Proxy and requests from nodes

I am attempting to make a get request to a website via https using the request module. However, I am behind a proxy that requires authentication. Despite my attempts to add the authentication, the connection to the site fails. I have experimented with add ...

Steps for creating new users using a post request

I've been working on developing a chat application using react-chat-engine, and everything is running smoothly except for one issue - I'm struggling to figure out how to send a post request to create new users. Below is the code snippet I'v ...

The utilization of media within the meta in Next.js is not allowed

Recently, I came across an interesting article about PWAs on web.dev. The article discusses color schemes and at one point, they talk about it in detail, I'm currently working with Next.js and decided to try implementing the following code snippet: & ...

Using Typescript to assign a new class instance to an object property

Recently, I crafted a Class that defines the properties of an element: export class ElementProperties { constructor( public value: string, public adminConsentRequired: boolean, public displayString?: string, public desc ...