🌊 Aqua Button

A modern button with aqua-inspired 3D press effects and smooth scaling animations. Features realistic depth shadows and tactile feedback.

Install dependencies

npm i clsx tailwind-merge

Add Utilities

//lib/utils.ts

import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}

Code

AquaButton.tsx


"use client";
import Link from "next/link";
import { useState } from "react";
import { cn } from "@/lib/utils";


interface btnProps{
  className?:string;
  btnText:string;
  onClick?: () => void;
  href?:string
}

export default function AquaButton({className,btnText = "Splash",onClick,href}:btnProps) {
  const [pressed, setPressed] = useState(false);

  const handlePress = () => {
    setPressed(true);
    setTimeout(() => setPressed(false), 250); 
    onClick?.();
  };

  return (
    <div>
      <Link
        href={href || "#"}
        onClick={handlePress}
        className={cn(
          "relative py-4 px-10 flex items-center justify-center [border-radius:50px]",
          "transition-all duration-400 ease-[cubic-bezier(0.22,1,0.36,1)]",
          "will-change-transform",
          pressed
            ? "scale-[0.92] [box-shadow:inset_0_3px_4px_rgba(0,_0,_0,_0.2),inset_0_-3px_3px_rgba(255,_255,_255,_0.6)]"
            : "scale-100 [box-shadow:inset_0_10px_5px_rgba(0,_0,_0,_0.05),_0_25px_8px_rgba(0,_0,_0,_0.05),_0_20px_15px_rgba(0,_0,_0,_0.05),inset_0_-10px_15px_rgba(255,_255,_255,_0.9)]",className
        )}
      >
        <span className="text-black/50 text-2xl">{btnText}</span>
      </Link>
    </div>
  );
}

Props

PropTypeDefaultDescription
classNamestring—Additional CSS classes for custom styling.
btnTextstring"Click"Text to display inside the button.
onClick() => void—Function to run when the button is clicked.
hrefstring"#"The link URL to navigate to when clicked.
Aqua Button16