shadimage
knot-ui
componentflip-buttonsource: ok · hit

Flip Button

A button that flips between a light front face and dark back face in 3D on hover.

npx shadcn add "https://knot-ui.trupal.me/r/flip-button.json"
free

Visual style

3ddark-futuristic

Tags auto-generated by rules on 9/24/2026 — empty means no evidence, not lack of support.

Files1 · source cached 10/8/2026, 5:46:33 PM

components/library/flip-button.tsx
import React from "react";
interface FlipButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  children?: React.ReactNode;
  frontClassName?: string;
  backClassName?: string;
}

export const FlipButton = ({
  children = "Button",
  className = "",
  frontClassName = "",
  backClassName = "",
  disabled = false,
  type = "button",
  onClick,
  ...rest
}: FlipButtonProps) => {
  return (
    <button
      type={type}
      disabled={disabled}
      onClick={onClick}
      className={`relative group [perspective:1000px] [transform-style:preserve-3d] rounded-md disabled:opacity-50 disabled:pointer-events-none ${className}`}
      {...rest}
    >
        {/* ghost sizer — invisible, just drives button dimensions */}
        <span className="invisible text-xl font-bold px-5 py-2 block">{children}</span>
        {/* front face */}
        <span className={`absolute inset-0 bg-neutral-100 text-black text-xl font-bold rounded-md flex items-center justify-center scale-100 group-hover:scale-50 [transform:rotateX(0deg)] group-hover:[transform:rotateX(90deg)] group-hover:opacity-0 origin-top transition-all duration-300 ${frontClassName}`}>
            {children}
        </span>
        {/* back face */}
        <span className={`absolute inset-0 bg-neutral-950 text-white text-xl font-bold rounded-md flex items-center justify-center [transform:rotateX(-90deg)] opacity-0 group-hover:[transform:rotateX(0deg)] group-hover:opacity-100 origin-bottom transition-all duration-300 group-hover:scale-100 scale-75 ${backClassName}`}>
            {children}
        </span>
    </button>
  );
};

FlipButton.displayName = "FlipButton";

More from knot-ui

Browse all components in this library →