Text scrolls sideways in an endless, seamless ticker.
export function marquee(el) {
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return () => {}
const text = el.textContent ?? ''
el.setAttribute('aria-label', text)
el.textContent = ''
el.style.overflow = 'hidden'
const track = document.createElement('span')
track.className = 'k-marquee-track'
;[0, 1].forEach(() => {
const seg = document.createElement('span')
seg.textContent = text
seg.className = 'k-marquee-seg'
seg.setAttribute('aria-hidden', 'true')
track.append(seg)
})
el.append(track)
const easing = 'linear'
const anim = track.animate([{ transform: 'translateX(0%)' }, { transform: 'translateX(-50%)' }], {
duration: 3 * 1000,
easing,
iterations: Infinity,
})
return () => {
anim.cancel()
el.textContent = text
el.style.overflow = ''
}
}
/* CSS */
.k-marquee-track {
display: inline-flex;
}
.k-marquee-seg {
padding-inline-end: 3em;
white-space: nowrap;
}