Direction-aware transition
Match enter and exit directions to navigation order and preserve context.
Live preview
Content slides one way going forward and the opposite way going back, so navigation has a sense of direction.
Definition and close-term distinctions
English definitions are preserved verbatim from Animation Vocabulary; translations and distinctions help you choose precisely.
direction-aware-transitionDirection-aware transition
方向感过渡Content slides one way going forward and the opposite way going back, so navigation has a sense of direction.
前进时内容沿一个方向滑动,返回时沿相反方向滑动,让导航具备方向感。
Decide before this motion ships
Purpose, frequency, trigger, timing, interruptibility, and gesture rules shape the implementation.
Use opposite directions for forward and back navigation to preserve sequence and hierarchy.
Use for medium-frequency step flows, pagination, and history navigation; apply to peer tabs only when direction is meaningful.
Trigger from next, previous, browser back, or ordered-index changes.
On forward navigation, new content enters from ahead as old content exits behind; reverse the mapping on back.
Rapid navigation takes over at current progress and renders only the current and latest target.
Swipe pagination follows gesture direction; buttons and keyboard navigation use the same spatial rule.
Use a short crossfade while preserving forward/back labels and focus position.
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--direction-aware-transition {
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--direction-aware-transition *, .motion-demo.motion-demo--direction-aware-transition *::before, .motion-demo.motion-demo--direction-aware-transition *::after {
box-sizing: border-box;
}
.motion-demo.motion-demo--direction-aware-transition .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--direction-aware-transition .motion-line {
display: block;
width: 100%;
height: 0.5rem;
background: #e4e4e7;
border-radius: 999px;
}
.motion-demo.motion-demo--direction-aware-transition .motion-line:last-child { width: 62%; }
.motion-demo.motion-demo--direction-aware-transition .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--direction-aware-transition .motion-button:focus-visible { outline: 3px solid rgb(37 99 235 / 32%); outline-offset: 3px; }
.motion-demo.motion-demo--direction-aware-transition .motion-action-row {
display: flex;
justify-content: center;
gap: 0.5rem;
margin-top: 0.85rem;
}
.motion-demo.motion-demo--direction-aware-transition .motion-replay-scene {
width: min(100%, 22rem);
display: grid;
place-items: center;
}
.motion-demo.motion-demo--direction-aware-transition .motion-pausable-scene {
width: min(100%, 22rem);
display: grid;
place-items: center;
}
.motion-demo.motion-demo--direction-aware-transition button.motion-surface {
color: inherit;
font: inherit;
text-align: start;
cursor: pointer;
}
.motion-demo.motion-demo--direction-aware-transition .motion-replay-button,
.motion-demo.motion-demo--direction-aware-transition .motion-undo-button,
.motion-demo.motion-demo--direction-aware-transition .motion-dismiss-button,
.motion-demo.motion-demo--direction-aware-transition .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--direction-aware-transition .motion-replay-button:focus-visible,
.motion-demo.motion-demo--direction-aware-transition .motion-undo-button:focus-visible,
.motion-demo.motion-demo--direction-aware-transition .motion-dismiss-button:focus-visible,
.motion-demo.motion-demo--direction-aware-transition .motion-pause-button:focus-visible,
.motion-demo.motion-demo--direction-aware-transition [data-reorder-item]:focus-visible,
.motion-demo.motion-demo--direction-aware-transition [data-swipe-target]:focus-visible {
outline: 3px solid rgb(37 99 235 / 32%);
outline-offset: 3px;
}
.motion-demo.motion-demo--direction-aware-transition .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--direction-aware-transition .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--direction-aware-transition .motion-state-stack { position: relative; width: min(100%, 18rem); height: 9rem; }
.motion-demo.motion-demo--direction-aware-transition .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--direction-aware-transition .motion-state--to { background: #18181b; color: white; }
.motion-demo.motion-demo--direction-aware-transition .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--direction-aware-transition .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--direction-aware-transition .motion-text-stack { position: relative; width: min(100%, 18rem); min-height: 4rem; }
.motion-demo.motion-demo--direction-aware-transition svg { width: min(100%, 20rem); height: auto; }
.motion-demo.motion-demo--direction-aware-transition .motion-state--from { animation: motion-direction-aware-transition-out 240ms cubic-bezier(0.23, 1, 0.32, 1) both; }
.motion-demo.motion-demo--direction-aware-transition .motion-state--to { animation: motion-direction-aware-transition-in 240ms cubic-bezier(0.23, 1, 0.32, 1) both; }
@keyframes motion-direction-aware-transition-out { to { opacity: 0; transform: translateX(40px); } }
@keyframes motion-direction-aware-transition-in { from { opacity: 0; transform: translateX(-40px); } to { opacity: 1; transform: none; } }
@keyframes motion-direction-aware-transition-reduced-fade {
from { opacity: 0.84; }
to { opacity: 1; }
}
.force-reduced-motion .motion-demo.motion-demo--direction-aware-transition {
animation: motion-direction-aware-transition-reduced-fade 160ms cubic-bezier(0.23, 1, 0.32, 1) both !important;
}
.force-reduced-motion .motion-demo.motion-demo--direction-aware-transition *,
.force-reduced-motion .motion-demo.motion-demo--direction-aware-transition *::before,
.force-reduced-motion .motion-demo.motion-demo--direction-aware-transition *::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--direction-aware-transition .motion-button,
.force-reduced-motion .motion-demo.motion-demo--direction-aware-transition [data-reorder-item],
.force-reduced-motion .motion-demo.motion-demo--direction-aware-transition [data-swipe-target],
.force-reduced-motion .motion-demo.motion-demo--direction-aware-transition [data-spring-target] {
transform: none !important;
}
.force-reduced-motion .motion-demo.motion-demo--direction-aware-transition .motion-path { stroke-dashoffset: 0 !important; }
.force-reduced-motion .motion-demo.motion-demo--direction-aware-transition .motion-word--from { opacity: 0 !important; visibility: hidden; }
.force-reduced-motion .motion-demo.motion-demo--direction-aware-transition .motion-word:not(.motion-word--from) { opacity: 1 !important; filter: none !important; transform: none !important; }
@media (prefers-reduced-motion: reduce) {
.motion-demo.motion-demo--direction-aware-transition {
animation: motion-direction-aware-transition-reduced-fade 160ms cubic-bezier(0.23, 1, 0.32, 1) both !important;
}
.motion-demo.motion-demo--direction-aware-transition *, .motion-demo.motion-demo--direction-aware-transition *::before, .motion-demo.motion-demo--direction-aware-transition *::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--direction-aware-transition .motion-button,
.motion-demo.motion-demo--direction-aware-transition [data-reorder-item],
.motion-demo.motion-demo--direction-aware-transition [data-swipe-target],
.motion-demo.motion-demo--direction-aware-transition [data-spring-target] {
transform: none !important;
}
.motion-demo.motion-demo--direction-aware-transition .motion-path { stroke-dashoffset: 0 !important; }
.motion-demo.motion-demo--direction-aware-transition .motion-word--from { opacity: 0 !important; visibility: hidden; }
.motion-demo.motion-demo--direction-aware-transition .motion-word:not(.motion-word--from) { opacity: 1 !important; filter: none !important; transform: none !important; }
}Pre-delivery review
- Test forward direction under RTL layouts.
- Align visual order, DOM order, and navigation history.
Keep information accessible
Use a short crossfade while preserving forward/back labels and focus position.
Parameter reference
| Parameter | Range / options | Default | Purpose |
|---|---|---|---|
duration | 80ms–1200ms | 240ms | Controls the time required for one motion cycle. |
distance | 0px–120px | 40px | Controls how far the element travels. |
direction | Up / Down / Left / Right / Exit | Left | Selects direction. |
ease | Soft / Snap / Calm / Linear | Soft | Controls how velocity changes over time. |