Marquee
Content scrolling sideways without end, in CSS alone: seamless, paused on hover, still when motion is reduced.
Demo
FastAccessibleNo build stepOne fileDark modeKeyboard firstForms that post
111222333444555666777888999111012211332
The first pauses under the pointer; the second runs right and never stops.
Get it
It needs theme.qwe, as every component does; or take the whole kit, quillo-ui.qwe. Each component brings its own styles to the pages that show it.
$ curl -O https://quillolang.org/components/ui/theme.qwe$ curl -O https://quillolang.org/components/ui/marquee.qwemain.qwe
import ui/theme.qwe use theme_cssuse ui/marquee.qweroute GET / = <html><head><style>{theme_css}</style></head><body class="ui-root">...</body></html>Example
The code of the preview above.
demos/marquee.qwe
let marquee_demo_words = ["Fast", "Accessible", "No build step", "One file", "Dark mode", "Keyboard first", "Forms that post"]view MarqueeDemo() = <div.demo-stack> <Marquee speed={18} label="What people say"> {for w in marquee_demo_words => <span style="padding: 6px 14px; border: 1px solid var(--ui-border); border-radius: 999px; background: var(--ui-subtle)">{w}</span>} </Marquee> <Marquee direction="right" speed={30} gap={24} pause={false} label="Numbers"> {for n in range(1, 13) => <span style="font: 600 22px var(--ui-mono); color: var(--ui-muted)">{n * 111}</span>} </Marquee> <p.demo-note>The first pauses under the pointer; the second runs right and never stops.</p> </div>Source
ui/marquee.qwe
// Marquee: content that scrolls sideways without end: logos, headlines, a line// of tags. Pure CSS: the content is drawn twice and slid by its own width, so// the loop has no seam. It pauses while the pointer or the focus is on it, and// for people who ask their system for less motion it does not move at all (it// can be scrolled by hand instead).//// <Marquee speed={25}>// {for l in logos => <img src={l.src} alt={l.name} height="32"/>}// </Marquee>// <Marquee direction="right" gap={64} label="Partners">...</Marquee>//// children: what scrolls (any elements; they are laid in a row).// speed: seconds for one full loop (20); less is faster. direction: "left"// (default) or "right". gap: the space between items, and between the end and// the start again, in pixels (48). pause: stops while hovered or focused (true).// label: what screen readers call it ("Scrolling content"); they read the// content once, as the copy is hidden from them.import ui/theme.qwe use ui_clslet marquee_css = css`.ui-marquee { position: relative; overflow: hidden; width: 100%; font: 14px/1.4 var(--ui-font); color: var(--ui-fg); mask-image: linear-gradient(to right, transparent, #000 6%, #000 94%, transparent); -webkit-mask-image: linear-gradient(to right, transparent, #000 6%, #000 94%, transparent);}.ui-marquee-track { display: flex; width: max-content; animation: ui-marquee var(--t, 20s) linear infinite; }.ui-marquee-right .ui-marquee-track { animation-direction: reverse; }.ui-marquee-pause:hover .ui-marquee-track, .ui-marquee-pause:focus-within .ui-marquee-track { animation-play-state: paused; }.ui-marquee-group { display: flex; flex: none; align-items: center; gap: var(--g, 48px); padding-right: var(--g, 48px); }.ui-marquee-group > * { flex: none; }@keyframes ui-marquee { to { transform: translateX(-50%); } }@media (prefers-reduced-motion: reduce) { .ui-marquee { overflow-x: auto; mask-image: none; -webkit-mask-image: none; } .ui-marquee-track { animation: none; } .ui-marquee-group[aria-hidden] { display: none; }}`view Marquee(speed: num = 20, direction: str = "left", gap: int = 48, pause: bool = true, label: str = "Scrolling content", class: str? = null, children) { style global marquee_css <div class={ui_cls(["ui-marquee", direction == "right" && "ui-marquee-right", pause && "ui-marquee-pause", class])} role="marquee" aria-label={label} style={`--t: ${speed}s; --g: ${gap}px`}> <div.ui-marquee-track> <div.ui-marquee-group>{children}</div> <div.ui-marquee-group aria-hidden="true">{children}</div> </div> </div>}Related
CoverImageA wide picture with a title, subtitle and actions over a gradient, in three heights.7 views · 7 downloadsLogoCloudA row of logos, grey until hovered, with a line saying what they are; each can be a link.6 views · 5 downloadsTickerA news ticker: a labelled strip of headlines sliding past, each a link when it has one, in CSS alone.6 views · 9 downloadsBrowserFrameA mock browser window around its content, with the address in its bar, for screenshots and demos.7 views · 6 downloadsAudioPlayerAn audio clip with play, a seek bar that says the time, and a button cycling through playback speeds.6 views · 7 downloadsCameraCaptureTakes a photo with the camera into a hidden input as a data URL, with retake, and says so when there is no camera.6 views · 6 downloads
Thread
Thread 0 posts
On Marquee: questions, tips, corrections, and code that uses it.
No posts yet. The first one opens the thread.