Skip to content

Instantly share code, notes, and snippets.

@dieseltravis
Last active January 8, 2026 16:03
Show Gist options
  • Select an option

  • Save dieseltravis/7a01c2bb80a0758fdfbfa769386360e8 to your computer and use it in GitHub Desktop.

Select an option

Save dieseltravis/7a01c2bb80a0758fdfbfa769386360e8 to your computer and use it in GitHub Desktop.
html/css marquee
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Marquee demo</title>
<style>
html, body {
margin: 0;
padding: 2rem;
background-color: #ddd;
}
.marquee-parent {
width: 50vw;
margin: auto;
padding: 2rem 0;
background-color: #CCF;
display:block;
overflow: hidden;
/* fade at edges */
-webkit-mask-image: linear-gradient(to right, transparent, black 10%, black 90%, transparent);
mask-image: linear-gradient(to right, transparent, black 10%, black 90%, transparent);
}
.marquee {
/* set this to the number of items (sibling-count() not widely supported yet) */
--item-count: 5;
--duration: calc(3s * var(--item-count));
/* item width and space between, times count */
width: calc(240px * var(--item-count));
/* adjust as needed until entire item isn't visible before disappearing */
margin-left: -40px;
/* used to pause animation more slowly */
transform: translateX(0);
transition: 500ms ease-out;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
}
.marquee > .marquee-item {
/* draw an animation path starting at 0, 90 degrees to the right to the end of the element */
offset: ray(90deg sides at 0);
animation: marquee var(--duration) linear infinite;
/* sibling-index() not widely supported yet, so --item-index is set for each logo */
/* each item delayed by its index divided by total items times duration */
animation-delay: calc(-1 * (var(--item-count) - var(--item-index)) * var(--duration) / var(--item-count));
}
.marquee:hover {
/* transitioned for a less jarring pause */
transform: translateX(-20px);
}
.marquee:hover > .marquee-item {
animation-play-state: paused;
}
@keyframes marquee {
/* from right to left*/
from { offset-distance: 100%; }
to { offset-distance: 0%; }
}
/* graceful fallback for when user prefers less motion */
@media (prefers-reduced-motion: reduce) {
.marquee {
flex-wrap: wrap;
gap: 3.0rem;
}
.marquee:hover {
transform: translateX(0);
}
.marquee .marquee-item {
animation-play-state: paused;
offset: none;
}
}
</style>
</head>
<body>
<main>
<div class="marquee-parent">
<div class="marquee">
<span class="marquee-item" style="--item-index:1">Item one</span>
<div class="marquee-item" style="--item-index:2"><img src="2" alt="item 2" /></div>
<div class="marquee-item" style="--item-index:3">Item three</div>
<b class="marquee-item" style="--item-index:4">Bold four</b>
<div class="marquee-item" style="--item-index:5">Item five</div>
<!-- be sure to set the css variable --item-count above to the number of items -->
</div>
</div>
</main>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment