docsLogo Slider

Logo Slider

A smooth, infinite marquee component for showcasing logos with progressive blur edge effects.

Loading Preview...

Install using CLI

npx shadcn@latest add "https://www.vengenceui.com/r/logo-slider.json"

Install Manually

1

Add util file

lib/utils.ts

import { ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
2

Add styles to global CSS

Add the following styles to your app/globals.css file

/* LogoSlider - CSS Variables & Animations */
.logo-slider {
--speed: 60;
--count: 8;
--blurs: 8;
--blur: 1;
}
.logo-slider__container {
mask: linear-gradient(90deg, transparent, black 15% 85%, transparent);
-webkit-mask: linear-gradient(90deg, transparent, black 15% 85%, transparent);
}
.logo-slider__blur > div {
z-index: var(--blur-index);
mask: linear-gradient(90deg,
transparent calc(var(--blur-index) * calc((100 / var(--blurs)) * 1%)),
black calc((var(--blur-index) + 1) * calc((100 / var(--blurs)) * 1%)),
black calc((var(--blur-index) + 2) * calc((100 / var(--blurs)) * 1%)),
transparent calc((var(--blur-index) + 3) * calc((100 / var(--blurs)) * 1%)));
backdrop-filter: blur(calc((var(--blur-index, 0) * var(--blur, 0)) * 1px));
-webkit-backdrop-filter: blur(calc((var(--blur-index, 0) * var(--blur, 0)) * 1px));
}
@media (prefers-reduced-motion: no-preference) {
.logo-slider__track { gap: 0; }
.logo-slider__item {
--duration: calc(var(--speed) * 1s);
--delay: calc((var(--duration) / var(--count)) * (var(--item-index, 0) * -1));
--origin-x: calc(((var(--count) - var(--item-index)) + var(--inset, 0)) * 100%);
--destination-x: calc((var(--item-index) + 1 + var(--outset, 0)) * -100%);
animation: logo-slider-slide var(--duration) var(--delay) infinite linear;
translate: var(--origin-x) 0;
}
@keyframes logo-slider-slide {
100% { translate: var(--destination-x) 0; }
}
}
.logo-slider__container[data-direction="right"] .logo-slider__item {
animation-direction: reverse;
}
.logo-slider__container[data-pause-on-hover="true"]:hover .logo-slider__item {
animation-play-state: paused;
}
3

Copy the source code

Copy the code below and paste it into components/ui/logo-slider.tsx

"use client";
import * as React from "react";
import { cn } from "@/lib/utils";
export interface LogoSliderProps {
logos: React.ReactNode[];
speed?: number;
direction?: "left" | "right";
showBlur?: boolean;
blurLayers?: number;
blurIntensity?: number;
className?: string;
pauseOnHover?: boolean;
}
export const LogoSlider = ({
logos,
speed = 60,
direction = "left",
showBlur = true,
blurLayers = 8,
blurIntensity = 1,
className,
pauseOnHover = false,
}: LogoSliderProps) => {
return (
<div
className={cn("logo-slider w-full overflow-hidden", className)}
style={{
"--speed": speed,
"--count": logos.length,
"--blurs": blurLayers,
"--blur": blurIntensity,
} as React.CSSProperties}
>
<div
className={cn("logo-slider__container", "relative w-full min-h-[80px] grid")}
data-direction={direction}
data-pause-on-hover={pauseOnHover}
>
{showBlur && (
<div className="logo-slider__blur logo-slider__blur--left absolute top-0 bottom-0 left-0 w-1/4 z-10 pointer-events-none rotate-180">
{Array.from({ length: blurLayers }).map((_, i) => (
<div key={i} className="absolute inset-0" style={{ "--blur-index": i } as React.CSSProperties} />
))}
</div>
)}
{showBlur && (
<div className="logo-slider__blur logo-slider__blur--right absolute top-0 bottom-0 right-0 w-1/4 z-10 pointer-events-none">
{Array.from({ length: blurLayers }).map((_, i) => (
<div key={i} className="absolute inset-0" style={{ "--blur-index": i } as React.CSSProperties} />
))}
</div>
)}
<ul className="logo-slider__track flex items-center h-full w-fit m-0 p-0 list-none">
{logos.map((logo, index) => (
<li
key={index}
className="logo-slider__item h-4/5 w-[120px] sm:w-[140px] lg:w-[160px] aspect-video grid place-items-center shrink-0"
style={{ "--item-index": index } as React.CSSProperties}
>
<div className="w-full h-full flex items-center justify-center [&>svg]:h-[65%] [&>svg]:w-auto [&>svg]:fill-zinc-800 dark:[&>svg]:fill-zinc-200 [&>img]:h-[65%] [&>img]:w-auto [&>img]:object-contain [&>img]:grayscale [&>img]:brightness-50 dark:[&>img]:brightness-125">
{logo}
</div>
</li>
))}
</ul>
</div>
</div>
);
};
LogoSlider.displayName = "LogoSlider";
export default LogoSlider;

Usage

1import { LogoSlider } from "@/components/ui/logo-slider"
2
3const logos = [<Logo1 />, <Logo2 />, <Logo3 />, <Logo4 />]
4
5export function TrustedBy() {
6return (
7 <LogoSlider
8 logos={logos}
9 speed={60}
10 direction="left"
11 />
12)
13}

Right Direction

Loading Preview...

Fast Speed

Loading Preview...

Pause on Hover

Loading Preview...

Without Blur

Loading Preview...

Double Row

Loading Preview...

Props

Prop NameTypeDefaultDescription
logosReact.ReactNode[]-Array of logo elements to display.
speednumber60Animation speed. Higher = slower.
direction"left" | "right""left"Scroll direction.
showBlurbooleantrueShow edge blur overlays.
blurLayersnumber8Number of blur layers.
blurIntensitynumber1Blur intensity multiplier.
pauseOnHoverbooleanfalsePause on hover.
classNamestring-Additional classes.