I'm trying to create a scrolling important message (I don't particularly like them, but clients have requirements!). Ideally I'd like to avoid JavaScript for this, but I'm not sure that's going to be possible.
So far I have a few options, all of which have flaws.
The first 2 in the divs with the class "alert" scroll at different speeds (the longer the message the faster it scrolls). Whats more, if the message is shorter than the container, it starts the animation from the middle of the container.
The last 2 (with class "alert_x") scroll at the same speed but the logic is wrong because the animation is based on the viewport width rather than the message width.
Is there any way to ensure the messages scroll to and from the correct places (from the right of container to the left) and at the same speed no matter what the size of the message - preferably without using JavaScript?
If JS is needed then jQuery is not an option.
.alert {
height: 34px;
overflow: hidden;
position: relative;
background: #00B5D9;
margin-bottom: 20px;
display: flex;
}
.alert p {
position: absolute;
width: auto;
white-space: nowrap;
-moz-transform: translateX(100%);
-webkit-transform: translateX(100%);
transform: translateX(100%);
-moz-animation: scroll-left 10s linear infinite;
-webkit-animation: scroll-left 10s linear infinite;
animation: scroll-left 10s linear infinite;
}
/* Move it (define the animation) */
@-moz-keyframes scroll-left {
0% {
-moz-transform: translateX(100%);
}
100% {
-moz-transform: translateX(-100%);
}
}
@-webkit-keyframes scroll-left {
0% {
-webkit-transform: translateX(100%);
}
100% {
-webkit-transform: translateX(-100%);
}
}
@keyframes scroll-left {
0% {
-moz-transform: translateX(100%);
/* Browser bug fix */
-webkit-transform: translateX(100%);
/* Browser bug fix */
transform: translateX(100%);
}
100% {
-moz-transform: translateX(-100%);
/* Browser bug fix */
-webkit-transform: translateX(-100%);
/* Browser bug fix */
transform: translateX(-100%);
}
}
.alert_x {
height: 34px;
overflow: hidden;
position: relative;
background: #00B5D9;
margin-bottom: 20px;
display: flex;
}
.alert_x p {
position: absolute;
width: auto;
white-space: nowrap;
-moz-transform: translateX(calc(100vw));
-webkit-transform: translateX(calc(100vw));
transform: translateX(calc(100vw));
-moz-animation: scroll-left-x 10s linear infinite;
-webkit-animation: scroll-left-x 10s linear infinite;
animation: scroll-left-x 10s linear infinite;
}
/* Move it (define the animation) */
@-moz-keyframes scroll-left-x {
0% {
-moz-transform: translateX(calc(100vw));
}
100% {
-moz-transform: translateX(calc(100vw * -1));
}
}
@-webkit-keyframes scroll-left-x {
0% {
-webkit-transform: translateX(calc(100vw));
}
100% {
-webkit-transform: translateX(calc(100vw * -1));
}
}
@keyframes scroll-left-x {
0% {
-moz-transform: translateX(calc(100vw));
/* Browser bug fix */
-webkit-transform: translateX(calc(100vw));
/* Browser bug fix */
transform: translateX(calc(100vw));
}
100% {
-moz-transform: translateX(calc(100vw * -1));
/* Browser bug fix */
-webkit-transform: translateX(calc(100vw * -1));
/* Browser bug fix */
transform: translateX(calc(100vw * -1));
}
}
<div class="alert">
<p>
Short message
</p>
</div>
<div class="alert">
<p>
Long message... Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt. Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt.
</p>
</div>
<div class="alert_x">
<p>
Short message
</p>
</div>
<div class="alert_x">
<p>
Long message... Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt. Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt.
</p>
</div>
View on JSFiddle.
EDIT!
OK, so I've found a better option which takes a similar approach. It solves all the problems except the fact that the speed differs depending on the length of message.
@-webkit-keyframes ticker {
0% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
visibility: visible;
}
100% {
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
}
}
@keyframes ticker {
0% {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
visibility: visible;
}
100% {
-webkit-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
}
}
.alert-wrap {
width: 100%;
overflow: hidden;
background-color: teal;
padding-left: 100%;
}
.alert {
display: inline-block;
white-space: nowrap;
padding-right: 100%;
-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
animation-timing-function: linear;
-webkit-animation-name: ticker;
animation-name: ticker;
-webkit-animation-duration: 30s;
animation-duration: 30s;
}
body {
margin: 0;
}
<div class="alert-wrap">
<div class="alert">
<div>Long message... Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt. Long message... Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt. Long message... Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.
</div>
</div>
</div>
I'm not sure if I understand the question correctly, but if I do, is this the kind of thing you are looking for:
Working Example:
body {
overflow-x: hidden;
}
p {
transform: translateX(100vw);
white-space: nowrap;
animation: scrollLeft 15s linear infinite;
}
@keyframes scrollLeft {
0% {transform: translateX(100vw);}
100% {transform: translateX(-375vw);}
}
<p>Tiny message.</p>
<p>This is a short message.</p>
<p>This is something which at least approaches a medium length message.</p>
<p>This is, as you can see, a rather longer message which takes up a lot more space and is certainly visually longer than the preceding three messages.</p>
<p>This is an absolutely enormous message which seems to go on and on forever and never really looks like it's going to end and you start to wonder if it might actually go on infinitely but then, eventually, almost unexpectedly it does, finally... wait for it... suggest that it might stop... before it actually continues a little more and then, reluctantly does indeed, finally come to an end.</p>
Now that I've got a better grasp of what the intended effect is, I've gone for a javascript approach (using CSSOM). I've got most of the way there, but I'm stuck on trying to get all the messages to scroll at the same speed.
As it is:
But, predictably, that means the messages aren't all moving at the same speed - the longer messages are moving faster than the shorter messages in order to complete their scrolling animation at the same time.
Working Example:
const paragraphs = [... document.getElementsByTagName('p')];
paragraphs.forEach(function(paragraph){
paragraph.dataset.width = parseInt(window.getComputedStyle(paragraph).getPropertyValue('width')) + 12;
const stylesheet = document.styleSheets[(document.styleSheets.length - 1)];
stylesheet.insertRule('[data-width="' + paragraph.dataset.width + '"]{animation: scrollLeft_' + paragraph.dataset.width + ' ' + ((paragraph.dataset.width + window.innerWidth) / ((paragraph.dataset.width + window.innerWidth) / 20)) + 's linear infinite;}', stylesheet.cssRules.length);
stylesheet.insertRule('@keyframes scrollLeft_' + paragraph.dataset.width + '{0%{transform: translateX(100vw);} 100%{transform: translateX(calc(0vw - ' + paragraph.dataset.width + 'px));}}', stylesheet.cssRules.length);
});
body {
overflow-x: hidden;
}
p {
display: inline-block;
float: left;
clear: left;
padding: 6px;
color: rgb(255, 255, 255);
background-color: rgb(255, 0, 0);
border-radius: 3px;
transform: translateX(100vw);
white-space: nowrap;
}
<p>Tiny message.</p>
<p>This is a short message.</p>
<p>This is something which at least approaches a medium length message.</p>
<p>This is, as you can see, a rather longer message which takes up a lot more space and is certainly visually longer than the preceding three messages.</p>
<p>This is an absolutely enormous message which seems to go on and on forever and never really looks like it's going to end and you start to wonder if it might actually go on infinitely but then, eventually, almost unexpectedly it does, finally... wait for it... suggest that it might stop... before it actually continues a little more and then, reluctantly does indeed, finally come to an end.</p>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With