Reputation: 63
I need to replace a vertical scroller with a CSS equivalent, for compliance reasons. The replacement needs to be a 100% high marquee, scrolling vertically at a fixed speed.
This example does what I need it to with three exceptions: https://codepen.io/strongpom/pen/qmooZe
I've tried using the code linked above, but find a way to accommodate the following three requirements:
(1) I need it to be 100% high, and for the text to scroll from the top to the bottom.
(2) I can't specify the length of the slider div, because it will be determine by (variable) contents. This means I cant set absolute scroll positions, other than that the top of the div should start at the bottom of the viewport, and keep scrolling until the bottom of that div hits the top of the viewport.
and
(3) The scrollspeed cannot be fixed at e.g. 15 seconds, because if there's lots of content, it then scrolls too fast, whilst if there's little content, it scrolls too slowly. I need to be able to specify a fixed scrolling speed, independent of length.
.container {
width: 20em;
height: 10em;
margin: 2em auto;
overflow: hidden;
background: #ffffff;
position: relative;
}
.slider {
top: 1em;
position: relative;
box-sizing: border-box;
animation: slider 15s linear infinite;
list-style-type: none;
text-align: center;
}
.slider:hover {
animation-play-state: paused;
}
@keyframes slider {
0% { top: 10em }
100% { top: -14em }
}
.blur .slider {
margin: 0;
padding: 0 1em;
line-height: 1.5em;
}
.blur:before, .blur::before,
.blur:after, .blur::after {
left: 0;
z-index: 1;
content: '';
position: absolute;
width: 100%;
height: 2em;
background-image: linear-gradient(180deg, #FFF, rgba(255,255,255,0));
}
.blur:after, .blur::after {
bottom: 0;
transform: rotate(180deg);
}
.blur:before, .blur::before {
top: 0;
}
p {
font-family: helvetica, arial, sans serif;
}
<div class="container blur">
<ul class="slider">
<li><p> Hello, it's me</p></li>
<li><p> I was wondering if after all these years you'd like to meet</p></li>
<li><p>To go over everything</p></li>
<li><p> They say that time's supposed to heal ya</p></li>
<li><p> But I ain't done much healing</p></li>
</ul>
</div>
Upvotes: 3
Views: 12136
Reputation: 71
I could not find a pure CSS way to have a consistent speed, but with a little math and small javascript, you can achieve fixed speed with variable height items. The key factor below is the / 500 which is in pixels per second. The code below will scroll at approx 500 px per second, no matter the length of the items.
The javascript/css is verbose for readability.
window.onload = function() {
var lineHeight = document.querySelector(".slider li").clientHeight;
var viewHeight = window.innerHeight;
var slider = document.querySelector(".slider");
var time = (slider.offsetHeight * 2.0 + viewHeight * 2) / 500.0;
slider.style.animationDuration = time + "s";
}
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
overflow: hidden;
height: 100%;
}
.slider {
position: absolute;
list-style-type: none;
text-align: center;
animation: slider linear infinite;
}
.slider li {
line-height: 50px;
width: 100vw;
}
@keyframes slider {
0% {
transform: translateY(100vh)
}
100% {
transform: translateY(-100%)
}
}
<ul class=slider>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
Upvotes: 3