3D tilt / Flip
Use controlled perspective and rotation for card flips or hover depth.
Live preview
Rotate in 3D space (rotateX / rotateY) to add depth.
Definition and close-term distinctions
English definitions are preserved verbatim from Animation Vocabulary; translations and distinctions help you choose precisely.
3d-tilt-flip3D tilt / Flip
3D 倾斜 / 翻转Rotate in 3D space (rotateX / rotateY) to add depth.
在三维空间中通过 rotateX 或 rotateY 旋转,增加纵深感。
Decide before this motion ships
Purpose, frequency, trigger, timing, interruptibility, and gesture rules shape the implementation.
Use controlled perspective for card faces or subtle pointer-driven depth.
Reserve for low-frequency exploration and featured cards; avoid continuous tilt across dense lists.
Trigger from an explicit flip action or fine-pointer hover, with tap toggling on touch devices.
Switch the visible face near 90° during the flip and return along the shortest angle on exit.
Retarget from the current angle and keep face visibility synchronized when operated again.
Cap pointer tilt and recenter on leave; keyboard interaction triggers a discrete flip.
Use an immediate face switch or short crossfade with 3D rotation and perspective travel removed.
Copy into your interface
Current parameters update visual-state CSS, semantic HTML, the required vanilla JS runtime, and an interaction prompt.
.motion-demo.motion-demo--3d-tilt-flip {
position: relative;
display: grid;
place-items: center;
width: min(100%, 34rem);
min-height: 15rem;
padding: 2rem;
overflow: hidden;
color: #18181b;
background: #fafafa;
border: 1px solid #e4e4e7;
border-radius: 12px;
isolation: isolate;
}
.motion-demo.motion-demo--3d-tilt-flip *, .motion-demo.motion-demo--3d-tilt-flip *::before, .motion-demo.motion-demo--3d-tilt-flip *::after {
box-sizing: border-box;
}
.motion-demo.motion-demo--3d-tilt-flip .motion-surface {
position: relative;
display: grid;
gap: 0.65rem;
width: min(100%, 18rem);
padding: 1.25rem;
background: #ffffff;
border: 1px solid #e4e4e7;
border-radius: 8px;
box-shadow: 0 1px 2px rgb(0 0 0 / 6%), 0 10px 28px rgb(0 0 0 / 7%);
}
.motion-demo.motion-demo--3d-tilt-flip .motion-line {
display: block;
width: 100%;
height: 0.5rem;
background: #e4e4e7;
border-radius: 999px;
}
.motion-demo.motion-demo--3d-tilt-flip .motion-line:last-child { width: 62%; }
.motion-demo.motion-demo--3d-tilt-flip .motion-button {
position: relative;
min-height: 2.75rem;
padding: 0.75rem 1.1rem;
color: white;
font: inherit;
font-weight: 700;
background: #18181b;
border: 0;
border-radius: 7px;
cursor: pointer;
}
.motion-demo.motion-demo--3d-tilt-flip .motion-button:focus-visible { outline: 3px solid rgb(37 99 235 / 32%); outline-offset: 3px; }
.motion-demo.motion-demo--3d-tilt-flip .motion-action-row {
display: flex;
justify-content: center;
gap: 0.5rem;
margin-top: 0.85rem;
}
.motion-demo.motion-demo--3d-tilt-flip .motion-replay-scene {
width: min(100%, 22rem);
display: grid;
place-items: center;
}
.motion-demo.motion-demo--3d-tilt-flip .motion-pausable-scene {
width: min(100%, 22rem);
display: grid;
place-items: center;
}
.motion-demo.motion-demo--3d-tilt-flip button.motion-surface {
color: inherit;
font: inherit;
text-align: start;
cursor: pointer;
}
.motion-demo.motion-demo--3d-tilt-flip .motion-replay-button,
.motion-demo.motion-demo--3d-tilt-flip .motion-undo-button,
.motion-demo.motion-demo--3d-tilt-flip .motion-dismiss-button,
.motion-demo.motion-demo--3d-tilt-flip .motion-pause-button {
min-height: 2.75rem;
padding: 0.65rem 0.9rem;
color: #18181b;
font: 650 0.78rem/1 ui-sans-serif, system-ui, sans-serif;
background: #ffffff;
border: 1px solid #d4d4d8;
border-radius: 7px;
cursor: pointer;
}
.motion-demo.motion-demo--3d-tilt-flip .motion-replay-button:focus-visible,
.motion-demo.motion-demo--3d-tilt-flip .motion-undo-button:focus-visible,
.motion-demo.motion-demo--3d-tilt-flip .motion-dismiss-button:focus-visible,
.motion-demo.motion-demo--3d-tilt-flip .motion-pause-button:focus-visible,
.motion-demo.motion-demo--3d-tilt-flip [data-reorder-item]:focus-visible,
.motion-demo.motion-demo--3d-tilt-flip [data-swipe-target]:focus-visible {
outline: 3px solid rgb(37 99 235 / 32%);
outline-offset: 3px;
}
.motion-demo.motion-demo--3d-tilt-flip .motion-status {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
.motion-demo.motion-demo--3d-tilt-flip .motion-ripple-ink {
position: absolute;
width: 12px;
height: 12px;
pointer-events: none;
background: rgb(255 255 255 / 72%);
border-radius: 50%;
transform: translate(-50%, -50%) scale(0.95);
opacity: 0;
}
.motion-demo.motion-demo--3d-tilt-flip .motion-state-stack { position: relative; width: min(100%, 18rem); height: 9rem; }
.motion-demo.motion-demo--3d-tilt-flip .motion-state { position: absolute; inset: 0; display: grid; place-items: center; padding: 1rem; background: #ffffff; border: 1px solid #e4e4e7; border-radius: 8px; }
.motion-demo.motion-demo--3d-tilt-flip .motion-state--to { background: #18181b; color: white; }
.motion-demo.motion-demo--3d-tilt-flip .motion-scroll-track > span { color: #71717a; font: 600 0.72rem/1.2 ui-monospace, monospace; letter-spacing: 0.08em; text-transform: uppercase; }
.motion-demo.motion-demo--3d-tilt-flip .motion-orbit-item { display: grid; place-items: center; width: 2.5rem; height: 2.5rem; color: white; background: #2563eb; border-radius: 50%; }
.motion-demo.motion-demo--3d-tilt-flip .motion-text-stack { position: relative; width: min(100%, 18rem); min-height: 4rem; }
.motion-demo.motion-demo--3d-tilt-flip svg { width: min(100%, 20rem); height: auto; }
.motion-demo.motion-demo--3d-tilt-flip { perspective: 800px; }
.motion-demo.motion-demo--3d-tilt-flip .motion-flip { position: relative; width: 14rem; height: 9rem; transform-style: preserve-3d; animation: motion-3d-tilt-flip 280ms cubic-bezier(0.23, 1, 0.32, 1) both; }
.motion-demo.motion-demo--3d-tilt-flip .motion-face { position: absolute; inset: 0; display: grid; place-items: center; backface-visibility: hidden; background: #ffffff; border: 1px solid #e4e4e7; border-radius: 8px; }
.motion-demo.motion-demo--3d-tilt-flip .motion-face--back { transform: rotateY(180deg); background: #18181b; color: white; }
@keyframes motion-3d-tilt-flip { from { transform: rotateY(0); } to { transform: rotateY(180deg); } }
@keyframes motion-3d-tilt-flip-reduced-fade {
from { opacity: 0.84; }
to { opacity: 1; }
}
.force-reduced-motion .motion-demo.motion-demo--3d-tilt-flip {
animation: motion-3d-tilt-flip-reduced-fade 160ms cubic-bezier(0.23, 1, 0.32, 1) both !important;
}
.force-reduced-motion .motion-demo.motion-demo--3d-tilt-flip *,
.force-reduced-motion .motion-demo.motion-demo--3d-tilt-flip *::before,
.force-reduced-motion .motion-demo.motion-demo--3d-tilt-flip *::after {
animation: none !important;
animation-delay: 0ms !important;
animation-iteration-count: 1 !important;
transition-property: opacity, color, background-color, border-color !important;
transition-duration: 160ms !important;
transition-delay: 0ms !important;
scroll-behavior: auto !important;
}
.force-reduced-motion .motion-demo.motion-demo--3d-tilt-flip .motion-button,
.force-reduced-motion .motion-demo.motion-demo--3d-tilt-flip [data-reorder-item],
.force-reduced-motion .motion-demo.motion-demo--3d-tilt-flip [data-swipe-target],
.force-reduced-motion .motion-demo.motion-demo--3d-tilt-flip [data-spring-target] {
transform: none !important;
}
.force-reduced-motion .motion-demo.motion-demo--3d-tilt-flip .motion-path { stroke-dashoffset: 0 !important; }
.force-reduced-motion .motion-demo.motion-demo--3d-tilt-flip .motion-word--from { opacity: 0 !important; visibility: hidden; }
.force-reduced-motion .motion-demo.motion-demo--3d-tilt-flip .motion-word:not(.motion-word--from) { opacity: 1 !important; filter: none !important; transform: none !important; }
@media (prefers-reduced-motion: reduce) {
.motion-demo.motion-demo--3d-tilt-flip {
animation: motion-3d-tilt-flip-reduced-fade 160ms cubic-bezier(0.23, 1, 0.32, 1) both !important;
}
.motion-demo.motion-demo--3d-tilt-flip *, .motion-demo.motion-demo--3d-tilt-flip *::before, .motion-demo.motion-demo--3d-tilt-flip *::after {
animation: none !important;
animation-delay: 0ms !important;
animation-iteration-count: 1 !important;
transition-property: opacity, color, background-color, border-color !important;
transition-duration: 160ms !important;
transition-delay: 0ms !important;
scroll-behavior: auto !important;
}
.motion-demo.motion-demo--3d-tilt-flip .motion-button,
.motion-demo.motion-demo--3d-tilt-flip [data-reorder-item],
.motion-demo.motion-demo--3d-tilt-flip [data-swipe-target],
.motion-demo.motion-demo--3d-tilt-flip [data-spring-target] {
transform: none !important;
}
.motion-demo.motion-demo--3d-tilt-flip .motion-path { stroke-dashoffset: 0 !important; }
.motion-demo.motion-demo--3d-tilt-flip .motion-word--from { opacity: 0 !important; visibility: hidden; }
.motion-demo.motion-demo--3d-tilt-flip .motion-word:not(.motion-word--from) { opacity: 1 !important; filter: none !important; transform: none !important; }
}Pre-delivery review
- Check backface-visibility and reading order.
- Keep button hit targets stable during hover tilt.
Keep information accessible
Use an immediate face switch or short crossfade with 3D rotation and perspective travel removed.
Parameter reference
| Parameter | Range / options | Default | Purpose |
|---|---|---|---|
duration | 80ms–1200ms | 280ms | Controls the time required for one motion cycle. |
angle | 45deg–180deg | 180deg | Adjusts flip angle. |
perspective | 320px–1400px | 800px | Adjusts perspective. |
ease | Soft / Snap / Calm / Linear | Soft | Controls how velocity changes over time. |