Skip to main content

Apply visual shadows to indicate scrollable content overflow with automatic detection of scroll position

Import

import { ScrollShadow } from "heroui-solid";

Usage

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

import { ScrollShadow } from "heroui-solid"
import { For } from "solid-js"

export function Default() {
  return (
    <div class="w-full p-0 sm:max-w-sm">
      <ScrollShadow initialShadow class="max-h-[240px] p-4">
        <div class="space-y-4">
          <For each={Array.from({ length: 10 })}>
            {() => (
              <p>
                Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam
                pulvinar risus non risus hendrerit venenatis. Pellentesque sit
                amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus
                enim, sed ultricies sapien.
              </p>
            )}
          </For>
        </div>
      </ScrollShadow>
    </div>
  )
}

Orientation

Vertical

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Horizontal

Lorem Card

Bridging the Future

Today, 6:30 PM

Lorem Card

Bridging the Future

Today, 6:30 PM

Lorem Card

Bridging the Future

Today, 6:30 PM

Lorem Card

Bridging the Future

Today, 6:30 PM

Lorem Card

Bridging the Future

Today, 6:30 PM

Lorem Card

Bridging the Future

Today, 6:30 PM

Lorem Card

Bridging the Future

Today, 6:30 PM

Lorem Card

Bridging the Future

Today, 6:30 PM

Lorem Card

Bridging the Future

Today, 6:30 PM

Lorem Card

Bridging the Future

Today, 6:30 PM

import { Card, ScrollShadow } from "heroui-solid"
import { For } from "solid-js"

const images = [
  "https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/robot1.jpeg",
  "https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/avocado.jpeg",
  "https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/oranges.jpeg"
]

export function Orientation() {
  const getRandomImage = (idx: number) => {
    return images[idx % images.length]
  }

  return (
    <div class="w-full sm:max-w-sm">
      <div class="mb-8 w-full">
        <h4 class="mb-2 text-sm font-semibold">Vertical</h4>
        <Card class="w-full p-0">
          <ScrollShadow
            initialShadow
            class="max-h-[240px] p-4"
            orientation="vertical"
          >
            <div class="space-y-4">
              <For each={Array.from({ length: 10 })}>
                {() => (
                  <p>
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit.
                    Nullam pulvinar risus non risus hendrerit venenatis.
                    Pellentesque sit amet hendrerit risus, sed porttitor quam.
                    Morbi accumsan cursus enim, sed ultricies sapien.
                  </p>
                )}
              </For>
            </div>
          </ScrollShadow>
        </Card>
      </div>

      <div class="w-full">
        <h4 class="mb-2 text-sm font-semibold">Horizontal</h4>
        <Card class="w-full p-0">
          <ScrollShadow initialShadow class="p-4" orientation="horizontal">
            <div class="flex flex-row gap-4">
              <For each={Array.from({ length: 10 })}>
                {(_, idx) => (
                  <Card
                    class="flex min-w-[200px] flex-row gap-3 p-1"
                    variant="transparent"
                  >
                    <img
                      alt="Lorem Card"
                      class="aspect-square h-16 w-16 shrink-0 rounded-xl object-cover select-none sm:h-20 sm:w-20"
                      loading="lazy"
                      src={getRandomImage(idx())}
                    />
                    <div class="flex flex-1 flex-col justify-center gap-1">
                      <Card.Title class="text-sm">
                        Bridging the Future
                      </Card.Title>
                      <Card.Description class="text-xs">
                        Today, 6:30 PM
                      </Card.Description>
                    </div>
                  </Card>
                )}
              </For>
            </div>
          </ScrollShadow>
        </Card>
      </div>
    </div>
  )
}

Hide Scroll Bar

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

import { ScrollShadow } from "heroui-solid"
import { For } from "solid-js"

export function HideScrollBar() {
  return (
    <div class="w-full p-0 sm:max-w-sm">
      <ScrollShadow hideScrollBar initialShadow class="max-h-[240px] p-4">
        <div class="space-y-4">
          <For each={Array.from({ length: 10 })}>
            {() => (
              <p>
                Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam
                pulvinar risus non risus hendrerit venenatis. Pellentesque sit
                amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus
                enim, sed ultricies sapien.
              </p>
            )}
          </For>
        </div>
      </ScrollShadow>
    </div>
  )
}

Custom Shadow Size

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

import { ScrollShadow } from "heroui-solid"
import { For } from "solid-js"

export function CustomSize() {
  return (
    <div class="w-full p-0 sm:max-w-sm">
      <ScrollShadow initialShadow class="max-h-[240px] p-4" size={80}>
        <div class="space-y-4">
          <For each={Array.from({ length: 10 })}>
            {() => (
              <p>
                Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam
                pulvinar risus non risus hendrerit venenatis. Pellentesque sit
                amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus
                enim, sed ultricies sapien.
              </p>
            )}
          </For>
        </div>
      </ScrollShadow>
    </div>
  )
}

Visibility Change

Vertical Shadow State: none

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Horizontal Shadow State: none

Lorem Card

Bridging the Future

Today, 6:30 PM

Lorem Card

Bridging the Future

Today, 6:30 PM

Lorem Card

Bridging the Future

Today, 6:30 PM

Lorem Card

Bridging the Future

Today, 6:30 PM

Lorem Card

Bridging the Future

Today, 6:30 PM

Lorem Card

Bridging the Future

Today, 6:30 PM

Lorem Card

Bridging the Future

Today, 6:30 PM

Lorem Card

Bridging the Future

Today, 6:30 PM

Lorem Card

Bridging the Future

Today, 6:30 PM

Lorem Card

Bridging the Future

Today, 6:30 PM

import { Card, ScrollShadow, type ScrollShadowVisibility } from "heroui-solid"
import { createSignal, For } from "solid-js"

const images = [
  "https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/robot1.jpeg",
  "https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/avocado.jpeg",
  "https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/oranges.jpeg"
]

export function VisibilityChange() {
  const [verticalState, setVerticalState] =
    createSignal<ScrollShadowVisibility>("none")
  const [horizontalState, setHorizontalState] =
    createSignal<ScrollShadowVisibility>("none")

  const getRandomImage = (idx: number) => {
    return images[idx % images.length]
  }

  return (
    <div class="w-full sm:max-w-sm">
      <div class="mb-8 flex flex-col gap-2">
        <div class="rounded bg-default p-4">
          <p class="text-sm font-semibold">
            Vertical Shadow State: {verticalState()}
          </p>
        </div>
        <div class="w-full">
          <ScrollShadow
            initialShadow
            class="max-h-[240px] p-4"
            orientation="vertical"
            onVisibilityChange={(visibility) => setVerticalState(visibility)}
          >
            <div class="space-y-4">
              <For each={Array.from({ length: 10 })}>
                {() => (
                  <p>
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit.
                    Nullam pulvinar risus non risus hendrerit venenatis.
                    Pellentesque sit amet hendrerit risus, sed porttitor quam.
                    Morbi accumsan cursus enim, sed ultricies sapien.
                  </p>
                )}
              </For>
            </div>
          </ScrollShadow>
        </div>
      </div>

      <div class="flex flex-col gap-2">
        <div class="rounded bg-default p-4">
          <p class="text-sm font-semibold">
            Horizontal Shadow State: {horizontalState()}
          </p>
        </div>
        <div class="w-full">
          <ScrollShadow
            initialShadow
            class="p-4"
            orientation="horizontal"
            onVisibilityChange={(visibility) => setHorizontalState(visibility)}
          >
            <div class="flex flex-row gap-4">
              <For each={Array.from({ length: 10 })}>
                {(_, idx) => (
                  <Card
                    class="flex min-w-[200px] flex-row gap-3 p-1"
                    variant="transparent"
                  >
                    <img
                      alt="Lorem Card"
                      class="aspect-square h-16 w-16 shrink-0 rounded-xl object-cover select-none sm:h-20 sm:w-20"
                      loading="lazy"
                      src={getRandomImage(idx())}
                    />
                    <div class="flex flex-1 flex-col justify-center gap-1">
                      <Card.Title class="text-sm">
                        Bridging the Future
                      </Card.Title>
                      <Card.Description class="text-xs">
                        Today, 6:30 PM
                      </Card.Description>
                    </div>
                  </Card>
                )}
              </For>
            </div>
          </ScrollShadow>
        </div>
      </div>
    </div>
  )
}

With Card

Terms and Conditions

Please review before proceeding

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam pulvinar risus non risus hendrerit venenatis. Pellentesque sit amet hendrerit risus, sed porttitor quam. Morbi accumsan cursus enim, sed ultricies sapien.

import { Button, Card, ScrollShadow } from "heroui-solid"
import { For } from "solid-js"

export function WithCard() {
  return (
    <Card class="max-w-[400px]">
      <Card.Header>
        <Card.Title>Terms and Conditions</Card.Title>
        <Card.Description>Please review before proceeding</Card.Description>
      </Card.Header>
      <Card.Content class="p-0">
        <ScrollShadow initialShadow class="h-[300px] px-4" size={80}>
          <div class="space-y-4">
            <For each={Array.from({ length: 10 })}>
              {() => (
                <p>
                  Lorem ipsum dolor sit amet, consectetur adipiscing elit.
                  Nullam pulvinar risus non risus hendrerit venenatis.
                  Pellentesque sit amet hendrerit risus, sed porttitor quam.
                  Morbi accumsan cursus enim, sed ultricies sapien.
                </p>
              )}
            </For>
          </div>
        </ScrollShadow>
      </Card.Content>
      <Card.Footer class="mt-4 flex flex-row gap-2">
        <Button class="w-full" variant="secondary">
          Cancel
        </Button>
        <Button class="w-full">Accept</Button>
      </Card.Footer>
    </Card>
  )
}

Styling

Passing Tailwind CSS classes

import { ScrollShadow, Card } from "heroui-solid";

function CustomScrollShadow() {
  return (
    <Card class="w-full p-0 sm:max-w-md">
      <ScrollShadow class="max-h-[300px] p-6 bg-gradient-to-b from-purple-50 to-pink-50">
        ...
      </ScrollShadow>
    </Card>
  );
}

Customizing the component classes

To customize the ScrollShadow component classes, you can use the @layer components directive. Learn more.

@layer components {
  .scroll-shadow {
    @apply rounded-xl border border-default-200;
  }

  .scroll-shadow--vertical {
    @apply pr-2; /* Add padding for custom scrollbar styling */
  }

  .scroll-shadow--horizontal {
    @apply pb-2;
  }
}

HeroUI follows the BEM methodology to ensure component variants and states are reusable and easy to customize.

CSS Classes

The ScrollShadow component uses these CSS classes (View source styles):

Base Classes

  • .scroll-shadow - Root container element

Orientation Variants

  • .scroll-shadow--vertical - Vertical scrolling (default)
  • .scroll-shadow--horizontal - Horizontal scrolling

State Modifiers

  • .scroll-shadow--hide-scrollbar - Hides native scrollbar

CSS Variables

The ScrollShadow component uses CSS variables to size the fade mask and reserve space for visible native scrollbars:

VariableDefaultDescription
--scroll-shadow-size40pxControls the fade gradient size. This is set from the size prop.
--scroll-shadow-scrollbar-size10px (0px when hideScrollBar)Reserves a solid mask gutter for the native scrollbar.

Data Attributes

The component uses data attributes to control shadow visibility:

  • Scroll States: [data-top-scroll], [data-bottom-scroll], [data-left-scroll], [data-right-scroll] - Applied when content can be scrolled in that direction
  • Combined States: [data-top-bottom-scroll], [data-left-right-scroll] - Applied when content can be scrolled in both directions
  • Orientation: [data-orientation="vertical"] or [data-orientation="horizontal"] - Indicates scroll direction
  • Size: [data-scroll-shadow-size] - Contains the shadow gradient size value

API Reference

ScrollShadow

PropTypeDefaultDescription
orientation"vertical" | "horizontal""vertical"The scroll direction
variant"fade""fade"The visual shadow effect style
sizenumber40The shadow gradient size in pixels
offsetnumber0The scroll offset before showing shadows (in pixels)
hideScrollBarbooleanfalseWhether to hide the native scrollbar
isEnabledbooleantrueWhether scroll shadow detection is enabled
initialShadowbooleanfalseRender the end-edge shadow before scroll measurement (SSR / first frame). Opt in when the content is known to overflow at render time, so the shadow doesn't blink in after hydration.
visibility"auto" | "both" | "top" | "bottom" | "left" | "right" | "none""auto"Controlled shadow visibility state
onVisibilityChange(visibility: ScrollShadowVisibility) => void-Callback invoked when shadow visibility changes
classstring-Additional CSS classes to apply to the root element
childrenJSX.Element-The scrollable content

Last updated: 7/19/26, 3:27 AM

HeroUI SolidUnofficial SolidJS port of HeroUI v3, built on Kobalte and @heroui/styles