Installation
pnpm dlx shadcn@latest add https://dithercn.dev/r/logo-marquee.jsonUsage
import { LogoMarquee } from "@/components/dithercn/logo-marquee";
const logos = [
{ src: "/logos/acme.svg", alt: "Acme", ratio: 4 },
{
src: "/logos/globex.svg",
alt: "Globex",
ratio: 3.5,
href: "/customers/globex",
},
];
export function Customers() {
return <LogoMarquee logos={logos} label="Customers" />;
}Every logo is a Dithered logo with the same fill, cell and colour, so logos from different brands read as one set. The row repeats as many times as it needs to fill the width and loops without a seam.
Hover or focus the row and it coasts to a stop instead of halting; let go and it picks up speed again. A small pause button appears at the right end on hover and keyboard focus. The ends fade out through a mask, so the fade works on any background: soft is a smooth ramp, dither steps through Bayer levels.
ratio on each logo reserves its width before it loads, so the row does not shift. Give a logo an href to make it a link.
Examples
Wall
variant="wall" lays the logos out in a still grid with hairline dividers, two columns, or four once its container is 672px wide. Each logo links to a case study, and the shimmer passes through them in turn.
Two rows
Two marquees moving in opposite directions with dithered edges, the second hatched in grey.
Props
Also takes the drawing props of Dithered logo: color, tone, fill, outline, floor, matrix, cell, effect and period.
| Prop | Type | Default |
|---|---|---|
| logos* The logos, in order. | Type: { src: string; alt: string; ratio?: number; href?: string; color?: DitherColor }[] | Default – |
| label Names the list for screen readers. | Type: string | Default "Logos" |
| variant A scrolling row or a still grid. | Type: "marquee" | "wall" | Default "marquee" |
| speed Marquee only: scroll speed in CSS pixels per second. | Type: number | Default 32 |
| direction Marquee only: which way the row moves. | Type: "left" | "right" | Default "left" |
| fade Marquee only: how the ends fade out. | Type: "soft" | "dither" | "none" | Default "soft" |
| fadeWidth Marquee only: width of each end's fade in CSS pixels. | Type: number | Default 96 |
| pauseButton Marquee only: show a pause button on hover and focus. | Type: boolean | Default true |
| logoHeight Logo height in CSS pixels. | Type: number | Default 28 |
| gap Space between logos in the row, in CSS pixels. | Type: number | Default 64 |
Notes
- The first copy of the row is a list labelled by
label; the copies that fill the loop are hidden from assistive technology and their links are out of the tab order. - The row stops while it is offscreen. Under reduced motion it becomes a still, centred row that wraps.
- The motion is a single Web Animation on a transform, so it runs off the main thread.