fairly new to css. I spent a long time trying to figure out how to do a nice smooth text ticker, and one that resizes neatly from desktop to mobile
The scroller is pulled in where “textticker” / “textticker” appears, and the JS is at the bottom.
It seems to generally work fine on desktop.
But when I try it on iPhone… the text scrolls, jitters, or suddenly starts over, breaking the smooth scroll effect. Any ideas how to fix?
body {
background-color:;
padding: 0px;
margin:0px;
font-family: 'Times New Roman', Times, serif
font-size: 1.1rem;
color: #333333; /* Set default text color to #333333 */
line-height: 1;
overflow-x: hidden;
}
.container {
margin: 0px;
width: 100%;
background-color: #e5e5e5;
padding: 0px;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column; /* Change flex direction to column */
box-sizing: border-box;
}
/* product starts <<<<<<<<<<<<<<<<<<< */
/* Product container */
/* Product container */
.product-container {
margin: auto;
width: 100vw;
height: 80svh;
display: flex;
justify-content: center;
align-items: center;
background-color: #e5e5e5;
padding: 0px;
border-bottom: 1px solid black;
position: relative; /* Allows positioning of product-info */
}
/* Product inner */
.product-inner {
margin: auto;
width: 100%;
height: 100%;
display: flex;
justify-content: flex-start; /* Align the product-image to the left */
align-items: center; /* Vertically center the content */
padding: 0px;
}
/* Flex container for product-stats and product-ticker */
.product-info {
position: absolute; /* Keeps the container in the top right */
top: 40px;
right: 40px;
display: flex;
flex-direction: column; /* Stacks child elements vertically */
width: 400px; /* Fixed width for both elements */
gap: 10px; /* Adds space between the product-stats and product-ticker */
}
/* Product ticker */
.product-ticker {
width: 100%; /* Takes full width of the flex container */
border: 1px solid #333333;
padding: 8px;
margin: 0px;
box-sizing: border-box;
overflow: hidden;
user-select: none;
--gap: 5px;
display: flex;
gap: var(--gap);
font-family: 'BookmanRoman';
font-size: 1.1rem;
color: black;
line-height: 1;
letter-spacing: -0.6px;
}
.product-ticker textticker {
flex-shrink: 0;
min-width: 100%;
display: flex;
gap: var(--gap);
animation: scroll 30s linear infinite;
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: 'BookmanRoman';
font-size: 1.1rem;
color: black;
line-height: 1;
letter-spacing: -0.6px;
}
@keyframes scroll {
to {
transform: translateX(calc(-100% - var(--gap)));
}
}
/* Outer table container */
.outer-table-container {
border: 10px solid white;
width: 100%; /* Fixed width for the outer table */
background-color: white;
box-sizing: border-box;
}
/* Outer table styling */
.outer-table {
border-collapse: collapse;
width: 100%; /* Ensure outer table takes up the full container width */
}
/* Outer table cells */
.outer-table td {
border: none;
padding: 5px; /* Match the cellpadding of the inner table */
}
/* Button styling for the 'BUY NOW' button */
.product-buy-now-btn {
width: 100%;
height: auto;
background: silver; /* Green background */
border-radius: 0px;
padding-top: 10px;
padding-bottom: 10px;
color: blue;
border: 2px solid blue; /* Blue border */
cursor: pointer;
text-align: center;
vertical-align: middle;
font-family: 'BookmanJF';
letter-spacing: 0px;
font-size: 1.3rem;
text-decoration: underline;
}
/* Button hover effect */
.product-buy-now-btn:hover {
background-color: blue;
color: white !important;
}
/* Styling for the link that wraps the button */
.product-buy-now-link {
display: block; /* Make the link fill the entire cell */
text-decoration: none; /* Remove underline from the link */
}
/* product ends <<<<<<<<<<<<<<<<<<< */
/* <<<<<<<<< MEDIA QUERIES <<<<<<<<< */
/* <<<<<<<<< MEDIA QUERIES <<<<<<<<< */
/* <<<<<<<<< MEDIA QUERIES <<<<<<<<< */
@media (width <= 768px) {
/* Header section <<<<<<<<<<<<<<<< */
/* product <<<<<<<<<<<<<<<< */
/* Product container */
.product-container {
width: 100vw;
height: auto;
display: flex;
flex-direction: column; /* Ensure divs stack in mobile view */
align-items: center; /* Center items horizontally */
justify-content: flex-start; /* Align items to the top */
position: static;
box-sizing: border-box;
}
.product-info {
width: 100vw;
height: auto;
display: flex;
flex-direction: column; /* Ensure divs stack in mobile view */
align-items: center; /* Center items horizontally */
justify-content: flex-start; /* Align items to the top */
position: static;
box-sizing: border-box;
gap: 0px;
}
/* Product inner */
.product-inner {
width: 100%;
height: auto;
display: flex;
justify-content: center; /* Center horizontally */
align-items: center; /* Center vertically */
margin: auto;
margin-top: 12svh;
margin-bottom: 5svh;
box-sizing: border-box;
}
/* Product stats */
.product-stats {
position: static; /* Keep it in the normal document flow */
width: 100%;
height: 100%;
margin: 0; /* Ensure there's no extra margin pushing it */
padding: 0;
box-sizing: border-box;
}
/* Product ticker */
.product-ticker {
width: 100%; /* Takes full width of the flex container */
border: 0px;
border-radius: 0;
background-color:;
padding: 12px 5px;
margin: 0px;
box-sizing: border-box;
border-top: 1px solid black;
}
/* ends <<<<<<<<<<<<<<<<<<<<<<<<< */
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div class="container" style="background-color: ;">
<!-- Product -->
<div class="product-container">
<div class="product-inner">
</div>
<!-- New Flex Container for product-stats and product-ticker -->
<div class="product-info">
<div class="product-stats">
<!-- Outer Table -->
<div class="outer-table-container">
<table class="outer-table">
<tr>
<td>
lorem ipsum text
</td>
</tr>
<tr>
<td>
</td>
</tr>
<tr>
<td>
<!-- Cell with clickable button styled link -->
<a href="https://example.com" class="product-buy-now-link" target="_blank">
<button class="product-buy-now-btn">
BUY NOW
</button>
</a>
</td>
</tr>
</table>
</div>
</div>
<!-- Ticker directly below the product-stats >> text in js at end-->
<div class="product-ticker">
<textticker>
</textticker>
<textticker>
</textticker>
</div>
</div>
</div>
</div>
<!-- Smooth scroll script -->
<script>
function smoothScroll(targetId) {
const target = document.getElementById(targetId);
if (target) {
const targetPosition = target.getBoundingClientRect().top;
const startPosition = window.pageYOffset;
const distance = targetPosition - 50; // Optional offset for smoother position
const duration = 2000; // Increased duration for slower scroll
let start = null;
// Easing function for smoother ease-in-out effect (Quartic)
function easeInOutQuart(t, b, c, d) {
t /= d / 2;
if (t < 1) return c / 2 * t * t * t * t + b;
t -= 2;
return -c / 2 * (t * t * t * t - 2) + b;
}
// The animation loop
function animation(currentTime) {
if (start === null) start = currentTime;
const timeElapsed = currentTime - start;
const run = easeInOutQuart(timeElapsed, startPosition, distance, duration);
window.scrollTo(0, run);
if (timeElapsed < duration) requestAnimationFrame(animation);
}
requestAnimationFrame(animation);
}
}
document.getElementById('shop-link').addEventListener('click', function(e) {
e.preventDefault();
smoothScroll('shop');
});
</script>
<script src="https://unpkg.com/aos@next/dist/aos.js"></script>
<script>
AOS.init();
</script>
<script>
// Define the text content once
const tickerText = "This is the text ticker. It mostly works ok on desktop and android, but stutters and skips on iphone • This is the text ticker. It mostly works on desktop and android, but stutters and skips on iphone •";
// Find all <textticker> elements and insert the text content
document.querySelectorAll('textticker').forEach(el => {
el.innerHTML = tickerText;
});
</script>
</body>
</html>