Ripple Button

A button that sends a ripple out from where it is clicked.

"use client"

import {
  RippleButton,
  RippleButtonRipples,
} from "@animate-ui/react/primitives/buttons/ripple"

export default function RippleButtonDemo({
  tapScale = 0.97,
}: {
  tapScale?: number
}) {
  return (
    <RippleButton
      tapScale={tapScale}
      className="bg-primary text-primary-foreground h-10 rounded-lg px-4 text-sm font-medium [--ripple-button-ripple-color:var(--primary-foreground)]"
    >
      Ripple Button
      <RippleButtonRipples />
    </RippleButton>
  )
}

Installation

npm install @animate-ui/react motion
pnpm add @animate-ui/react motion
yarn add @animate-ui/react motion
bun add @animate-ui/react motion

Usage

import {
  RippleButton,
  RippleButtonRipples,
} from '@animate-ui/react/primitives/buttons/ripple';

export function Send() {
  return (
    <RippleButton className="[--ripple-button-ripple-color:white]">
      Send
      <RippleButtonRipples />
    </RippleButton>
  );
}

Animation

  • Each click sends a ripple from the pointer: it grows to scale while fading out over 0.6s, then is removed. Rapid clicks each get their own ripple.
  • Pressing scales the button to tapScale (0.97), on Motion's spring for scale (stiffness: 550, damping: 30). It doesn't scale on hover, unless you set hoverScale.
  • <AnimateUIProvider tempo> paces the default spring and ripple.
  • Under reduced motion, the ripple fades in place without growing, and the button doesn't scale.

API Reference

RippleButton

PropTypeDefault
hoverScale?
number1
tapScale?
number0.97
transition?
Transition{ type: 'spring', stiffness: 550, damping: 30, restSpeed: 10 }
asChild?
booleanfalse
...props?
HTMLMotionProps<'button'>-

RippleButtonRipples

PropTypeDefault
color?
string'var(--ripple-button-ripple-color)'
scale?
number10
transition?
Transition{ duration: 0.6, ease: 'easeOut' }
asChild?
booleanfalse
...props?
HTMLMotionProps<'span'>-

CSS variables

PropTypeDefault
--ripple-button-ripple-color?
color-

Built by Skyleen. The source code is available on GitHub.

Last updated: 10/18/2026

On this page