Code
app/page.tsx
1"use client"
2
3import FlipButton from "@/app/components/buttons/flip-button";
4
5const Home = () => {
6 return (
7 <div className="w-screen h-screen bg-black items-center justify-center flex flex-col gap-8">
8 <FlipButton
9 text="Astrae Design"
10 href="https://astrae.design"
11 />
12 </div>
13 );
14}
15
16export default Home;
Installation
Initialized a project and installed the necessary dependencies to use this component.
1. Initialize a new Next.js project:
npx create-next-app@latest my-app
Add Button Component
src/components/flip-button.tsx
1import React from "react";
2
3interface FlipButtonProps {
4 text?: string;
5 href?: string;
6}
7
8const FlipButton: React.FC<FlipButtonProps> = ({ text = "Stack Sorted.", href }) => {
9 const content = (
10 <>
11 {/* First span - visible by default, rotates out on hover */}
12 <span className="flip-span">
13 <em className="flip-text flip-text-1">
14 {text}
15 </em>
16 </span>
17
18 {/* Second span - hidden by default, rotates in on hover */}
19 <span className="flip-span flip-span-2">
20 <em className="flip-text flip-text-2">
21 {text}
22 </em>
23 </span>
24 </>
25 );
26
27 if (href) {
28 return (
29 <a href={href} className="flip-button">
30 {content}
31 </a>
32 );
33 }
34
35 return (
36 <button className="flip-button">
37 {content}
38 </button>
39 );
40};
41
42export default FlipButton;
Add Global Styles
app/globals.css
1/* Flip Button - 3D rotation effects */
2.flip-button {
3 display: flex;
4 flex-direction: column;
5 align-items: center;
6 overflow: hidden;
7 line-height: 1;
8 border-radius: 7rem;
9 padding: 0.815rem 1.232rem;
10 cursor: pointer;
11 border: none;
12 background: white;
13 transition: background 0.4s linear;
14 will-change: background;
15}
16
17.flip-button:hover {
18 background: #6fc1ff;
19}
20
21.flip-button:hover .flip-text-1 {
22 opacity: 0;
23 transform: rotateX(90deg) scaleX(0.9) translate3d(0, -10px, 0);
24}
25
26.flip-button:hover .flip-text-2 {
27 opacity: 1;
28 transform: rotateX(0deg) scaleX(1) translateZ(0);
29 transition: transform 0.75s cubic-bezier(0.645, 0.045, 0.355, 1),
30 opacity 0.35s linear 0.3s;
31}
32
33.flip-span {
34 position: relative;
35 display: block;
36 perspective: 108px;
37}
38
39.flip-span-2 {
40 position: absolute;
41}
42
43.flip-text {
44 font-style: normal;
45 display: inline-block;
46 font-size: 1.125rem;
47 color: black;
48 font-weight: 600;
49 will-change: transform, opacity, transition;
50 transition: transform 0.55s cubic-bezier(0.645, 0.045, 0.355, 1),
51 opacity 0.35s linear 0.2s;
52}
53
54.flip-text-1 {
55 transform-origin: top;
56}
57
58.flip-text-2 {
59 opacity: 0;
60 transform: rotateX(-90deg) scaleX(0.9) translate3d(0, 10px, 0);
61 transform-origin: bottom;
62}
63
64/* Flip Button - 3D rotation effects */