Marquee
Scroll content continuously in a seamless horizontal loop using a CSS animation.
Marquee is a client component that scrolls its children in a seamless horizontal loop. Use it for logo strips, announcements and testimonials. It repeats the children inside a track and moves the track with a CSS keyframe animation, with no JavaScript animation loop.
Import#
import { Marquee } from "@reactberry/system/blocks";
Usage#
import { Marquee } from "@reactberry/system/blocks";
import { Box, Text } from "@reactberry/system/elements";
const partners = ["Acme", "Globex", "Initech", "Umbrella", "Hooli"];
export default function PartnerStrip() {
return (
<Marquee speed={40} gap="2rem" pauseOnHover>
{partners.map((name) => (
<Box key={name} px="m" py="s" skin="surface" shape="pill">
<Text>{name}</Text>
</Box>
))}
</Marquee>
);
}
Examples#
Short announcement#
Set repeat higher when the content is narrower than the marquee. Here direction="right" reverses the scroll and fadeEdges={false} removes the edge fade.
Pause on hover#
Use pauseOnHover and a lower speed for content people need to read, such as quotes.
API#
Marquee#
| Prop | Type | Default | Description |
|---|---|---|---|
children* | ReactNode | — | Content to repeat. Rendered once per copy inside a flex row. |
speed | number | 50 | Relative speed. One loop lasts |
direction | "left""right" | "left" | Scroll direction. |
pauseOnHover | boolean | false | Pauses the animation while the pointer is over the marquee. |
gap | string | number | 1rem | Space between items, also applied as right padding on each copy so the loop seam matches. |
repeat | number | 2 | Number of copies rendered. Values below 2 are raised to 2. |
fadeEdges | boolean | true | Fades the content out over the outer 10% on each side with a mask. |
className | string | — | Class name applied to the root element. |
No other props are accepted and nothing is spread.
Accessibility#
- Every copy after the first has
aria-hiddenset, so screen readers encounter the content once. - The animation runs indefinitely and has no
prefers-reduced-motionhandling. UsepauseOnHover, or render static content where motion should be avoided.
Notes#
- With the default
speedof50, one loop lasts 40 seconds. - Each copy of the content must be at least as wide as the marquee for the loop to appear seamless. Increase
repeatwhen the content is short. - The root is
position: relative,width: 100%, and clips overflow.