Command Palette

Search for a command to run...

1.2k
Blog
PreviousNext

Scroll Fade Effect

A React component that adds a fade effect to content as you scroll.

Loading...
import * as React from "react";
 
import { Separator } from "@/components/ui/separator";
import { ScrollFadeEffect } from "@/components/ncdai/scroll-fade-effect";
 
const tags = Array.from({ length: 50 }).map(
  (_, i, a) => `v1.2.0-beta.${a.length - i}`
);
 
export function ScrollFadeEffectDemo() {
  return (
    <div className="rounded-lg border">
      <ScrollFadeEffect className="h-72 w-48">
        <div className="p-4">
          <h4 className="mb-4 text-sm leading-none font-medium">Tags</h4>
          {tags.map((tag) => (
            <React.Fragment key={tag}>
              <div className="text-sm">{tag}</div>
              <Separator className="my-2" />
            </React.Fragment>
          ))}
        </div>
      </ScrollFadeEffect>
    </div>
  );
}

Features

  • Content fades in and out smoothly as you scroll.
  • Supports both vertical and horizontal scrolling.

Browser Compatibility

This component uses CSS animation-timeline: scroll(). Check the latest browser compatibility on MDN before using in production.

Installation

pnpm dlx shadcn add @ncdai/scroll-fade-effect

Usage

import { ScrollFadeEffect } from "@/components/ncdai/scroll-fade-effect";
<div className="rounded-lg border">
  <ScrollFadeEffect className="h-72 w-48">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
    tempor incididunt ut labore et dolore magna aliqua. Turpis egestas pretium
    aenean pharetra. Orci eu lobortis elementum nibh tellus molestie. Vulputate
    dignissim suspendisse in est. Vel pharetra vel turpis nunc. Malesuada nunc
    vel risus commodo. Nisi vitae suscipit tellus mauris. Posuere morbi leo urna
    molestie at elementum eu. Urna duis convallis convallis tellus. Urna
    molestie at elementum eu. Nunc sed blandit libero volutpat.
  </ScrollFadeEffect>
</div>

Examples

Horizontal Scrolling

Loading...
import Image from "next/image";
 
import { ScrollFadeEffect } from "@/components/ncdai/scroll-fade-effect";
 
interface Artwork {
  artist: string;
  art: string;
}
 
const works: Artwork[] = [
  {
    artist: "Ornella Binni",
    art: "https://images.unsplash.com/photo-1465869185982-5a1a7522cbcb?auto=format&fit=crop&w=300&q=80",
  },
  {
    artist: "Tom Byrom",
    art: "https://images.unsplash.com/photo-1548516173-3cabfa4607e9?auto=format&fit=crop&w=300&q=80",
  },
  {
    artist: "Vladimir Malyavko",
    art: "https://images.unsplash.com/photo-1494337480532-3725c85fd2ab?auto=format&fit=crop&w=300&q=80",
  },
];
 
export function ScrollFadeEffectHorizontalDemo() {
  return (
    <div className="rounded-lg border">
      <ScrollFadeEffect className="w-72 sm:w-96" orientation="horizontal">
        <div className="flex w-max gap-4 p-4">
          {works.map((artwork) => (
            <figure key={artwork.artist} className="shrink-0">
              <Image
                src={artwork.art}
                alt={`Photo by ${artwork.artist}`}
                className="aspect-3/4 h-fit w-fit rounded-sm object-cover"
                width={300}
                height={400}
              />
 
              <figcaption className="pt-2 text-xs text-muted-foreground">
                Photo by{" "}
                <span className="font-semibold text-foreground">
                  {artwork.artist}
                </span>
              </figcaption>
            </figure>
          ))}
        </div>
      </ScrollFadeEffect>
    </div>
  );
}

shadcn/ui Scroll Area

Loading...
import * as React from "react";
 
import { ScrollArea } from "@/components/ui/scroll-area";
import { Separator } from "@/components/ui/separator";
import { cn } from "@/lib/utils";
 
const tags = Array.from({ length: 50 }).map(
  (_, i, a) => `v1.2.0-beta.${a.length - i}`
);
 
export function ScrollAreaDemo() {
  return (
    <ScrollArea
      className={cn(
        "h-72 w-48 rounded-lg border",
        "**:data-[slot=scroll-area-viewport]:scroll-fade-effect-y"
        // "**:data-[slot=scroll-area-viewport]:[--mask-offset-top:8px]",
        // "**:data-[slot=scroll-area-viewport]:[--mask-offset-bottom:8px]"
      )}
    >
      <div className="p-4">
        <h4 className="mb-4 text-sm leading-none font-medium">Tags</h4>
        {tags.map((tag) => (
          <React.Fragment key={tag}>
            <div className="text-sm">{tag}</div>
            <Separator className="my-2" />
          </React.Fragment>
        ))}
      </div>
    </ScrollArea>
  );
}

shadcn/ui Scroll Area – Horizontal Scrolling

Loading...
import Image from "next/image";
 
import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area";
import { cn } from "@/lib/utils";
 
interface Artwork {
  artist: string;
  art: string;
}
 
const works: Artwork[] = [
  {
    artist: "Ornella Binni",
    art: "https://images.unsplash.com/photo-1465869185982-5a1a7522cbcb?auto=format&fit=crop&w=300&q=80",
  },
  {
    artist: "Tom Byrom",
    art: "https://images.unsplash.com/photo-1548516173-3cabfa4607e9?auto=format&fit=crop&w=300&q=80",
  },
  {
    artist: "Vladimir Malyavko",
    art: "https://images.unsplash.com/photo-1494337480532-3725c85fd2ab?auto=format&fit=crop&w=300&q=80",
  },
];
 
export function ScrollAreaHorizontalDemo() {
  return (
    <ScrollArea
      className={cn(
        "w-72 rounded-lg border whitespace-nowrap sm:w-96",
        "**:data-[slot=scroll-area-viewport]:scroll-fade-effect-x"
        // "**:data-[slot=scroll-area-viewport]:[--mask-offset-left:8px]",
        // "**:data-[slot=scroll-area-viewport]:[--mask-offset-right:8px]"
      )}
    >
      <div className="flex w-max gap-4 p-4">
        {works.map((artwork) => (
          <figure key={artwork.artist} className="shrink-0">
            <Image
              src={artwork.art}
              alt={`Photo by ${artwork.artist}`}
              className="aspect-3/4 h-fit w-fit rounded-sm object-cover"
              width={300}
              height={400}
            />
 
            <figcaption className="pt-2 text-xs text-muted-foreground">
              Photo by{" "}
              <span className="font-semibold text-foreground">
                {artwork.artist}
              </span>
            </figcaption>
          </figure>
        ))}
      </div>
      <ScrollBar orientation="horizontal" />
    </ScrollArea>
  );
}

References