Tarjeta que gira
Gira en 3D para mostrar el reverso, con puntero, teclado o toque.
Diseño
Pasa el puntero o toca
Desarrollo
Pasa el puntero o toca
Código completo
Es exactamente el archivo que se descarga. Cópialo a tu proyecto y úsalo.
"use client";
/**
* Tarjeta que gira en 3D para mostrar el reverso. Con ratón gira al pasar el puntero o al enfocarla con el teclado;
* en pantallas táctiles gira al tocarla. Enter o Espacio también la voltean.
*
* <FlipCard front={<h3>Diseño</h3>} back={<p>Interfaces claras y rápidas.</p>} />
*/
import { useState, type CSSProperties, type KeyboardEvent, type ReactNode } from "react";
export type FlipCardProps = {
front: ReactNode;
back: ReactNode;
/** Colores de las dos caras. */
frontColor?: string;
backColor?: string;
/** Nombre accesible de la tarjeta. */
label?: string;
className?: string;
style?: CSSProperties;
};
const CSS = `
.gcx-scene { display: inline-block; width: 280px; height: 360px; perspective: 1100px; font-family: inherit; }
.gcx-card { position: relative; width: 100%; height: 100%; border-radius: 26px; outline: none; cursor: pointer; transform-style: preserve-3d; transition: transform .85s cubic-bezier(.34, 1.25, .5, 1); }
.gcx-card[data-flipped="true"] { transform: rotateY(180deg); }
@media (hover: hover) { .gcx-card:hover { transform: rotateY(180deg); } .gcx-card[data-flipped="true"]:hover { transform: rotateY(180deg); } }
.gcx-card:focus-visible { box-shadow: 0 0 0 3px #fff, 0 0 0 6px #111; }
.gcx-face { position: absolute; inset: 0; display: grid; align-content: end; gap: 10px; box-sizing: border-box; padding: 26px; overflow: hidden; border-radius: inherit; color: #fff; -webkit-backface-visibility: hidden; backface-visibility: hidden; }
.gcx-front { background: var(--gcx-front, #ff6b4a); }
.gcx-back { background: var(--gcx-back, #0f766e); transform: rotateY(180deg); align-content: center; }
.gcx-front::before { content: ""; position: absolute; top: -50px; right: -50px; width: 190px; height: 190px; border-radius: 50%; background: rgba(255, 255, 255, .22); }
.gcx-front::after { content: ""; position: absolute; top: 70px; left: -34px; width: 110px; height: 110px; border-radius: 28px; background: rgba(0, 0, 0, .13); transform: rotate(18deg); }
.gcx-face h3 { position: relative; margin: 0; font-size: 28px; font-weight: 800; line-height: 1.1; letter-spacing: -.02em; }
.gcx-face p { position: relative; margin: 0; font-size: 16px; line-height: 1.55; }
@media (prefers-reduced-motion: reduce) { .gcx-card { transition: none; } }
`;
export function FlipCard({ front, back, frontColor, backColor, label = "Tarjeta con reverso", className, style }: FlipCardProps) {
const [flipped, setFlipped] = useState(false);
function onKeyDown(event: KeyboardEvent<HTMLDivElement>) {
if (event.key === "Enter" || event.key === " ") {
event.preventDefault();
setFlipped((value) => !value);
}
}
return (
<>
<style>{CSS}</style>
<div className={["gcx-scene", className].filter(Boolean).join(" ")} style={{ ["--gcx-front" as string]: frontColor, ["--gcx-back" as string]: backColor, ...style } as CSSProperties}>
<div className="gcx-card" role="button" tabIndex={0} aria-label={label} aria-pressed={flipped} data-flipped={flipped} onClick={() => setFlipped((value) => !value)} onKeyDown={onKeyDown}>
<div className="gcx-face gcx-front" aria-hidden={flipped}>{front}</div>
<div className="gcx-face gcx-back" aria-hidden={!flipped}>{back}</div>
</div>
</div>
</>
);
}
Úsalo en tu proyecto
Instálalo con la CLI de shadcn.
npx shadcn@latest add https://www.gassierconsulting.com/r/tarjeta-volteoEjemplo de uso de Tarjeta que gira
Después de copiar flip-card.tsx a tu proyecto, impórtalo y colócalo donde lo necesites.
import { FlipCard } from "./flip-card";
export default function Ejemplo() {
return <FlipCard frontColor="Ejemplo" />;
}Propiedades de FlipCard
FlipCard acepta 7 propiedades; 2 son obligatorias.
| Propiedad | Tipo | Descripción |
|---|---|---|
front | ReactNode | Obligatoria. |
back | ReactNode | Obligatoria. |
frontColor? | string | Colores de las dos caras. |
backColor? | string | Opcional. |
label? | string | Nombre accesible de la tarjeta. |
className? | string | Opcional. |
style? | CSSProperties | Opcional. |
Personaliza Tarjeta que gira con variables CSS
Define estas variables en el contenedor o en tu hoja de estilos para cambiar los colores sin tocar el componente. Si no las defines, se usa el valor por defecto.
| Variable | Valor por defecto |
|---|---|
--gcx-front | #ff6b4a |
--gcx-back | #0f766e |
Accesibilidad y rendimiento
El archivo tiene 62 líneas (3 KB) y no necesita @keyframes. Esto es lo que hace Tarjeta que gira por quien lo usa:
- Detecta prefers-reduced-motion y baja o quita el movimiento cuando la persona lo pide.
- Muestra un anillo de foco visible al navegar con teclado (:focus-visible).
- Declara roles ARIA para lectores de pantalla: button.
- Responde al teclado, no solo al ratón.
- Es un componente de cliente de Next.js: incluye la directiva "use client".
Acerca del producto
Una tarjeta de dos caras que gira en 3D con un pequeño rebote. Con ratón gira al pasar el puntero; en pantallas táctiles, al tocar; y con teclado, con Enter o Espacio. El texto de la cara oculta se oculta a lectores de pantalla.
Incluye
Un solo archivo React + TypeScript, con los estilos dentro. No usa Tailwind ni bibliotecas externas.
- Colores de las dos caras configurables
- Teclado y táctil además del puntero
- Cara oculta con aria-hidden
- Frente y reverso con cualquier contenido
Cómo usarlo
Pasa front y back como contenido. Cambia frontColor y backColor y el tamaño desde CSS (.gcx-scene).