40+ landing page components for ReactBrowse now

Guides

Animations

trink-ui includes a set of animation wrappers that add smooth entrance effects to your sections. Learn how to use FadeIn, SlideUp, StaggerChildren, ScaleIn, and BlurIn effectively.

Available animation wrappers

Each wrapper is a React component that animates its children when they enter the viewport:

FadeIn

Fades content from transparent to opaque

SlideUp

Slides content upward while fading in

ScaleIn

Scales content from slightly smaller to full size

BlurIn

Transitions from blurred to sharp while fading in

StaggerChildren

Animates a list of children with sequential delay

Basic usage

Wrap any content with an animation component. By default, animations trigger when the element scrolls into view:

import { FadeIn, SlideUp, ScaleIn, BlurIn } from "@trinkui/react";

// Simple fade in on scroll
<FadeIn>
  <h2>This heading fades in</h2>
</FadeIn>

// Slide up with fade
<SlideUp>
  <p>This paragraph slides up into view</p>
</SlideUp>

// Scale from small to full size
<ScaleIn>
  <img src="/hero.png" alt="Hero image" />
</ScaleIn>

// Blur to sharp transition
<BlurIn>
  <div className="card">Content appears from blur</div>
</BlurIn>

Scroll trigger behavior

By default, animations use scrollTrigger={true} to animate when the element enters the viewport, and once={true} so the animation only plays once. You can change this behavior:

// Animate immediately (no scroll trigger)
<FadeIn scrollTrigger={false}>
  <h1>Above-the-fold content</h1>
</FadeIn>

// Re-animate every time the element enters the viewport
<SlideUp once={false}>
  <div>Animates every scroll pass</div>
</SlideUp>

Controlling delay and duration

Fine-tune timing with the delay and duration props (in seconds):

// Fast animation with no delay
<FadeIn duration={0.3} delay={0}>
  <p>Quick fade</p>
</FadeIn>

// Slow, dramatic entrance
<SlideUp duration={1.2} delay={0.5}>
  <h2>Dramatic headline</h2>
</SlideUp>

// Sequenced elements with manual delays
<FadeIn delay={0}>
  <h2>Title appears first</h2>
</FadeIn>
<FadeIn delay={0.2}>
  <p>Subtitle appears second</p>
</FadeIn>
<FadeIn delay={0.4}>
  <button>Button appears third</button>
</FadeIn>

Stagger pattern for lists and grids

Use StaggerChildren to animate a list of items with sequential delay. Each direct child is animated one after another:

import { StaggerChildren } from "@trinkui/react";

<StaggerChildren staggerDelay={0.1}>
  {features.map((feature) => (
    <div key={feature.title} className="rounded-lg border p-6">
      <h3>{feature.title}</h3>
      <p>{feature.description}</p>
    </div>
  ))}
</StaggerChildren>

The staggerDelay prop controls the time between each child's animation start. The default is 0.1 seconds.

Disabling animations

There are three ways to disable animations:

1. Per-section with the animated prop

Every section component accepts animated={false} to render without any animation wrappers.

2. Automatic reduced motion detection

All animation wrappers call useReducedMotion() internally. If the user has enabled "Reduce motion" in their OS settings, animations are automatically replaced with a plain <div>.

3. CSS media query fallback

As an additional safety net, you can add a CSS rule to instantly show all animated elements when reduced motion is preferred.

// Section with no animations
<HeroCentered animated={false} title="Instant render" ... />

// Animation wrapper that auto-detects reduced motion
<FadeIn>
  {/* Renders as plain <div> when user prefers reduced motion */}
  <p>Content here</p>
</FadeIn>

Performance considerations

trink-ui animations are designed for performance:

  • Only opacity and transform are animated — these are GPU-composited properties that do not trigger layout recalculation
  • Intersection Observer is used for scroll triggers instead of scroll event listeners
  • Animations run once by default, so no ongoing computation after the initial render
  • The useReducedMotion hook prevents unnecessary animation setup for users who prefer reduced motion

Combining multiple animation types

Use different animation types for different elements in the same section to create visual hierarchy:

Custom animated section
import { FadeIn, SlideUp, ScaleIn, StaggerChildren } from "@trinkui/react";

function CustomSection() {
  return (
    <section className="py-20">
      <div className="mx-auto max-w-6xl px-4">
        {/* Headline slides up first */}
        <SlideUp delay={0}>
          <h2 className="text-4xl font-bold text-center">Our Features</h2>
        </SlideUp>

        {/* Subtitle fades in after */}
        <FadeIn delay={0.2}>
          <p className="mt-4 text-center text-lg text-gray-600">
            Everything you need to succeed.
          </p>
        </FadeIn>

        {/* Feature cards stagger in */}
        <StaggerChildren staggerDelay={0.15} className="mt-12 grid gap-6 md:grid-cols-3">
          <div className="rounded-xl border p-6">
            <ScaleIn>
              <div className="text-4xl">⚡</div>
            </ScaleIn>
            <h3 className="mt-4 font-semibold">Fast</h3>
            <p className="mt-2 text-sm text-gray-500">Lightning quick performance.</p>
          </div>
          <div className="rounded-xl border p-6">
            <ScaleIn>
              <div className="text-4xl">🎨</div>
            </ScaleIn>
            <h3 className="mt-4 font-semibold">Beautiful</h3>
            <p className="mt-2 text-sm text-gray-500">Polished design system.</p>
          </div>
          <div className="rounded-xl border p-6">
            <ScaleIn>
              <div className="text-4xl">🔒</div>
            </ScaleIn>
            <h3 className="mt-4 font-semibold">Secure</h3>
            <p className="mt-2 text-sm text-gray-500">Enterprise-grade security.</p>
          </div>
        </StaggerChildren>
      </div>
    </section>
  );
}

Next step

Learn how trink-ui handles responsive design across all screen sizes.

Responsive Design Guide