HextaUI

Scroll fade

Bordes de un área de scroll que se desvanecen solo cuando hay más que ver, controlados por la posición del scroll solo con CSS.

  • v2.24.0Released
  • v2.23.0Released
  • v2.22.0Released
  • v2.21.0Released
  • v2.20.0Released
  • v2.19.0Released
  • v2.18.0Released
  • v2.17.0Released
  • v2.16.0Released
  • v2.15.0Released
  • v2.14.0Released
  • v2.13.0Released
  • v2.12.0Released
  • v2.11.0Released
  • v2.10.0Released
  • v2.9.0Released
  • v2.8.0Released
  • v2.7.0Released
  • v2.6.0Released
  • v2.5.0Released
  • v2.4.0Released
  • v2.3.0Released
  • v2.2.0Released
  • v2.1.0Released
const releases = Array.from({ length: 24 }, (_, index) => `v2.${24 - index}.0`)

export function ScrollFadeDemo() {
  return (
    <div className="w-full max-w-xs rounded-xl bg-muted">
      <ul
        tabIndex={0}
        aria-label="Releases"
        className="h-64 scroll-fade overflow-y-auto rounded-xl p-2 text-sm outline-none focus-visible:ring-3 focus-visible:ring-focus-ring focus-visible:outline-hidden"
      >
        {releases.map((release) => (
          <li
            key={release}
            className="flex h-9 items-center justify-between rounded-md px-3"
          >
            <span className="font-mono">{release}</span>
            <span className="text-muted-foreground">Released</span>
          </li>
        ))}
      </ul>
    </div>
  )
}

Scroll fade es un conjunto de utilidades de Tailwind del tailwind.css de shadcn. El tema de HextaUI ya lo importa, así que si has añadido el tema o cualquier componente, ya lo tienes.

pnpm dlx shadcn@latest add https://hextaui.com/r/theme.json

Sin el tema, instala shadcn e importa su CSS después de Tailwind.

pnpm add shadcn
app/globals.css
@import "tailwindcss";
@import "shadcn/tailwind.css";
<div className="scroll-fade h-64 overflow-y-auto">…</div>
<div className="flex scroll-fade-x overflow-x-auto">…</div>

Añádelo a cualquier elemento que haga scroll. Un borde se desvanece solo mientras hay más contenido más allá, así que una fila cortada indica "sigue desplazando" y una lista en reposo conserva bordes nítidos.

El degradado es un mask-image, así que el contenido se disuelve en lo que haya detrás. No hay un degradado superpuesto que ajustar al fondo, y funciona sobre imágenes, superficies teñidas y cristal. Una animación CSS controlada por scroll hace crecer el degradado de cada borde durante los primeros y últimos 96px de scroll. No se ejecuta JavaScript y nunca se vuelve a renderizar.

  • Cada degradado es el 12% del contenedor, con un máximo de 40px.
  • Los navegadores sin animaciones controladas por scroll muestran ambos degradados todo el tiempo. Es un poco menos preciso, pero sigue indicando que se puede desplazar.
  • scroll-fade-x, scroll-fade-s y scroll-fade-e siguen la dirección de escritura, así que el degradado de inicio queda a la derecha en diseños de derecha a izquierda.

Horizontal

Una fila de filtros que se desplaza lateralmente. Combínala con no-scrollbar, también del CSS de shadcn, cuando el degradado por sí solo muestra que hay más.

const topics = [
  "All",
  "Design",
  "Engineering",
  "Product",
  "Research",
  "Marketing",
  "Sales",
  "Support",
  "Operations",
  "Finance",
]

export function ScrollFadeHorizontal() {
  return (
    <div
      tabIndex={0}
      role="region"
      aria-label="Topics"
      className="no-scrollbar flex w-full max-w-sm scroll-fade-x gap-2 overflow-x-auto rounded-md outline-none focus-visible:ring-3 focus-visible:ring-focus-ring focus-visible:outline-hidden"
    >
      {topics.map((topic) => (
        <span
          key={topic}
          className="shrink-0 rounded-full bg-muted px-3 py-1.5 text-sm"
        >
          {topic}
        </span>
      ))}
    </div>
  )
}

Un borde

Un chat empieza abajo, así que solo los mensajes antiguos de arriba necesitan una pista. scroll-fade-t desvanece solo la parte superior, y scroll-fade-t-16 la hace más alta.

"use client"

const messages = Array.from({ length: 16 }, (_, index) => ({
  id: index,
  text: index % 3 === 0 ? "Sounds good, ship it." : "Pushed the fix to main.",
}))

export function ScrollFadeEdge() {
  return (
    <div className="w-full max-w-xs rounded-xl bg-muted">
      <ul
        ref={(node) => {
          if (node) {
            node.scrollTop = node.scrollHeight
          }
        }}
        tabIndex={0}
        aria-label="Messages"
        className="flex h-64 scroll-fade-t flex-col gap-2 overflow-y-auto rounded-xl p-3 text-sm outline-none scroll-fade-t-16 focus-visible:ring-3 focus-visible:ring-focus-ring focus-visible:outline-hidden"
      >
        {messages.map((message) => (
          <li
            key={message.id}
            className="w-fit max-w-[80%] shrink-0 rounded-2xl bg-background px-3 py-2 even:self-end even:bg-primary even:text-primary-foreground"
          >
            {message.text}
          </li>
        ))}
      </ul>
    </div>
  )
}
<div className="scroll-fade scroll-fade-16 overflow-y-auto">…</div>
<div className="scroll-fade scroll-fade-[20%] overflow-y-auto">…</div>
<div className="scroll-fade [--scroll-fade-reveal:12rem] overflow-y-auto">…</div>

Los tamaños aceptan la escala de espaciado o cualquier longitud o porcentaje. --scroll-fade-reveal define cuánto hay que desplazar para que un borde alcance su degradado completo.

  • La máscara también desvanece el fondo y el borde del propio elemento. Pon la superficie en un contenedor y el degradado en el hijo que hace scroll, como hacen los ejemplos.
  • Una máscara oculta todo lo que está cerca del borde, incluidos los anillos de foco. Dale algo de relleno al elemento que se desplaza para que los elementos enfocados no queden desvanecidos.
  • Usa Scroll area en su lugar cuando también quieras barras de scroll personalizadas. Tiene sus propios degradados, medidos con JavaScript, que funcionan en todos los navegadores.
ClaseDescripción
scroll-fade, scroll-fade-yDesvanece los bordes superior e inferior.
scroll-fade-xDesvanece los bordes de inicio y fin, según la dirección.
scroll-fade-t, scroll-fade-bDesvanece solo el borde superior o el inferior.
scroll-fade-s, scroll-fade-eDesvanece solo el borde de inicio o el de fin.
scroll-fade-l, scroll-fade-rDesvanece solo el borde izquierdo o el derecho, ignorando la dirección.
scroll-fade-<size>Tamaño de todos los degradados.
scroll-fade-{t,b,s,e}-<size>Tamaño del degradado de un borde.
scroll-fade-noneDesactiva el degradado, por ejemplo en un breakpoint.
--scroll-fade-revealDistancia de scroll en la que un borde aparece gradualmente. Por defecto es 96px.