Crossfade
Crossfade overlapping, similarly sized states to reduce visual jumps.
Live preview
One element fades out as another fades in, in the same spot.
Definition and close-term distinctions
English definitions are preserved verbatim from Animation Vocabulary; translations and distinctions help you choose precisely.
crossfadeCrossfade
交叉淡入淡出One element fades out as another fades in, in the same spot.
一个元素淡出的同时,另一个元素在同一位置淡入。
Decide before this motion ships
Purpose, frequency, trigger, timing, interruptibility, and gesture rules shape the implementation.
Switch similarly sized states in the same location while reducing abrupt replacement.
Use for medium- to high-frequency labels, icons, and media states; shorten overlap during continuous input.
Trigger from selection, content version, or media-state changes, with both states sharing one layout slot.
Partially overlap old-state fade-out and new-state fade-in, removing the old element after it is hidden.
On rapid changes, continue from the current blend ratio and retain only the latest target.
No gesture is required; slider-driven comparison uses Before / after slider.
Shorten to 80–120ms or switch immediately while preserving stable dimensions.
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--crossfade {
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--crossfade *, .motion-demo.motion-demo--crossfade *::before, .motion-demo.motion-demo--crossfade *::after {
box-sizing: border-box;
}
.motion-demo.motion-demo--crossfade .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--crossfade .motion-line {
display: block;
width: 100%;
height: 0.5rem;
background: #e4e4e7;
border-radius: 999px;
}
.motion-demo.motion-demo--crossfade .motion-line:last-child { width: 62%; }
.motion-demo.motion-demo--crossfade .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--crossfade .motion-button:focus-visible { outline: 3px solid rgb(37 99 235 / 32%); outline-offset: 3px; }
.motion-demo.motion-demo--crossfade .motion-action-row {
display: flex;
justify-content: center;
gap: 0.5rem;
margin-top: 0.85rem;
}
.motion-demo.motion-demo--crossfade .motion-replay-scene {
width: min(100%, 22rem);
display: grid;
place-items: center;
}
.motion-demo.motion-demo--crossfade .motion-pausable-scene {
width: min(100%, 22rem);
display: grid;
place-items: center;
}
.motion-demo.motion-demo--crossfade button.motion-surface {
color: inherit;
font: inherit;
text-align: start;
cursor: pointer;
}
.motion-demo.motion-demo--crossfade .motion-replay-button,
.motion-demo.motion-demo--crossfade .motion-undo-button,
.motion-demo.motion-demo--crossfade .motion-dismiss-button,
.motion-demo.motion-demo--crossfade .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--crossfade .motion-replay-button:focus-visible,
.motion-demo.motion-demo--crossfade .motion-undo-button:focus-visible,
.motion-demo.motion-demo--crossfade .motion-dismiss-button:focus-visible,
.motion-demo.motion-demo--crossfade .motion-pause-button:focus-visible,
.motion-demo.motion-demo--crossfade [data-reorder-item]:focus-visible,
.motion-demo.motion-demo--crossfade [data-swipe-target]:focus-visible {
outline: 3px solid rgb(37 99 235 / 32%);
outline-offset: 3px;
}
.motion-demo.motion-demo--crossfade .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--crossfade .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--crossfade .motion-state-stack { position: relative; width: min(100%, 18rem); height: 9rem; }
.motion-demo.motion-demo--crossfade .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--crossfade .motion-state--to { background: #18181b; color: white; }
.motion-demo.motion-demo--crossfade .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--crossfade .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--crossfade .motion-text-stack { position: relative; width: min(100%, 18rem); min-height: 4rem; }
.motion-demo.motion-demo--crossfade svg { width: min(100%, 20rem); height: auto; }
.motion-demo.motion-demo--crossfade .motion-state-stack { position: relative; width: min(100%, 18rem); height: 9rem; }
.motion-demo.motion-demo--crossfade .motion-state { position: absolute; inset: 0; display: grid; place-items: center; background: #ffffff; border: 1px solid #e4e4e7; border-radius: 8px; }
.motion-demo.motion-demo--crossfade .motion-state--from { animation: motion-crossfade-out 200ms linear both; }
.motion-demo.motion-demo--crossfade .motion-state--to { animation: motion-crossfade-in 200ms linear 100ms both; }
@keyframes motion-crossfade-out { to { opacity: 0; } }
@keyframes motion-crossfade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes motion-crossfade-reduced-fade {
from { opacity: 0.84; }
to { opacity: 1; }
}
.force-reduced-motion .motion-demo.motion-demo--crossfade {
animation: motion-crossfade-reduced-fade 160ms cubic-bezier(0.23, 1, 0.32, 1) both !important;
}
.force-reduced-motion .motion-demo.motion-demo--crossfade *,
.force-reduced-motion .motion-demo.motion-demo--crossfade *::before,
.force-reduced-motion .motion-demo.motion-demo--crossfade *::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--crossfade .motion-button,
.force-reduced-motion .motion-demo.motion-demo--crossfade [data-reorder-item],
.force-reduced-motion .motion-demo.motion-demo--crossfade [data-swipe-target],
.force-reduced-motion .motion-demo.motion-demo--crossfade [data-spring-target] {
transform: none !important;
}
.force-reduced-motion .motion-demo.motion-demo--crossfade .motion-path { stroke-dashoffset: 0 !important; }
.force-reduced-motion .motion-demo.motion-demo--crossfade .motion-word--from { opacity: 0 !important; visibility: hidden; }
.force-reduced-motion .motion-demo.motion-demo--crossfade .motion-word:not(.motion-word--from) { opacity: 1 !important; filter: none !important; transform: none !important; }
@media (prefers-reduced-motion: reduce) {
.motion-demo.motion-demo--crossfade {
animation: motion-crossfade-reduced-fade 160ms cubic-bezier(0.23, 1, 0.32, 1) both !important;
}
.motion-demo.motion-demo--crossfade *, .motion-demo.motion-demo--crossfade *::before, .motion-demo.motion-demo--crossfade *::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--crossfade .motion-button,
.motion-demo.motion-demo--crossfade [data-reorder-item],
.motion-demo.motion-demo--crossfade [data-swipe-target],
.motion-demo.motion-demo--crossfade [data-spring-target] {
transform: none !important;
}
.motion-demo.motion-demo--crossfade .motion-path { stroke-dashoffset: 0 !important; }
.motion-demo.motion-demo--crossfade .motion-word--from { opacity: 0 !important; visibility: hidden; }
.motion-demo.motion-demo--crossfade .motion-word:not(.motion-word--from) { opacity: 1 !important; filter: none !important; transform: none !important; }
}Pre-delivery review
- Prevent overlapping text from being announced twice by assistive technology.
- Keep both states from changing the shared container size.
Keep information accessible
Shorten to 80–120ms or switch immediately while preserving stable dimensions.
Parameter reference
| Parameter | Range / options | Default | Purpose |
|---|---|---|---|
duration | 80ms–1200ms | 200ms | Controls the time required for one motion cycle. |
overlap | 0%–100% | 50% | Adjusts overlap. |
ease | Soft / Snap / Calm / Linear | Calm | Controls how velocity changes over time. |