Liquid Button

A button that fills with color from the bottom on hover.

"use client"

import { LiquidButton } from "@/components/animate-ui/buttons/liquid"

export default function LiquidButtonDemo({
  delay = 0.3,
  fillHeight = 3,
  tapScale = 0.97,
}: {
  delay?: number
  fillHeight?: number
  tapScale?: number
}) {
  return (
    <LiquidButton
      delay={`${delay}s`}
      fillHeight={`${fillHeight}px`}
      tapScale={tapScale}
    >
      Liquid Button
    </LiquidButton>
  )
}

Installation

npx shadcn@latest add @animate-ui/buttons-liquid
pnpm dlx shadcn@latest add @animate-ui/buttons-liquid
yarn dlx shadcn@latest add @animate-ui/buttons-liquid
bun x shadcn@latest add @animate-ui/buttons-liquid

Usage

It fills with --primary over --muted by default. Change the two colors with CSS variables:

import { LiquidButton } from '@/components/animate-ui/buttons/liquid';

export function Start() {
  return (
    <LiquidButton className="[--liquid-button-background-color:var(--muted)] [--liquid-button-color:var(--primary)] hover:text-primary-foreground">
      Get started
    </LiquidButton>
  );
}

Animation

  • On hover, a fillHeight line of --liquid-button-color slides in along the bottom, then rises to fill the button, each step taking delay (a CSS transition). Leaving, the fill variables ease back over 0.3s, then the text color and the liquid drain in reverse.
  • Pressing scales the button to tapScale (0.97), and releasing springs it back (Animate UI's press spring, stiffness: 550, damping: 30). Hovering fills it without scaling it, unless you set hoverScale (then a 0.3s ease-out).
  • transition replaces the press, release and leave transitions.
  • <AnimateUIProvider tempo> paces the Motion transitions (not the CSS delay).
  • Under reduced motion, the button fills without scaling when pressed.

API Reference

LiquidButton

PropTypeDefault
delay?
string'0.3s'
fillHeight?
string'3px'
hoverScale?
number1
tapScale?
number0.97
transition?
Transition{ transform: { type: 'spring', stiffness: 550, damping: 30, restSpeed: 10 }, default: { duration: 0.3, ease: [0.25, 0.1, 0.35, 1] } }
asChild?
booleanfalse
...props?
HTMLMotionProps<'button'>-

CSS variables

PropTypeDefault
--liquid-button-color?
color-
--liquid-button-background-color?
color-

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

Last updated: 10/18/2026

On this page