Direction-aware transition

Match enter and exit directions to navigation order and preserve context.

Preview

Live preview

Content slides one way going forward and the opposite way going back, so navigation has a sense of direction.

Preview
Previous
Direction-aware transition
Authoritative vocabulary

Definition and close-term distinctions

English definitions are preserved verbatim from Animation Vocabulary; translations and distinctions help you choose precisely.

Canonical termdirection-aware-transition

Direction-aware transition

方向感过渡
Authoritative definition

Content slides one way going forward and the opposite way going back, so navigation has a sense of direction.

Chinese translation

前进时内容沿一个方向滑动,返回时沿相反方向滑动,让导航具备方向感。

Browse all 91 terms
Design contract

Decide before this motion ships

Purpose, frequency, trigger, timing, interruptibility, and gesture rules shape the implementation.

Purpose

Use opposite directions for forward and back navigation to preserve sequence and hierarchy.

Frequency

Use for medium-frequency step flows, pagination, and history navigation; apply to peer tabs only when direction is meaningful.

Trigger

Trigger from next, previous, browser back, or ordered-index changes.

Enter / exit

On forward navigation, new content enters from ahead as old content exits behind; reverse the mapping on back.

Interruptibility

Rapid navigation takes over at current progress and renders only the current and latest target.

Gesture and keyboard

Swipe pagination follows gesture direction; buttons and keyboard navigation use the same spatial rule.

Reduced-motion strategy

Use a short crossfade while preserving forward/back labels and focus position.

Output

Copy into your interface

Current parameters update visual-state CSS, semantic HTML, the required vanilla JS runtime, and an interaction prompt.

Updates with parameters
motion.css
.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; }
}
Review notes

Pre-delivery review

  • Test forward direction under RTL layouts.
  • Align visual order, DOM order, and navigation history.
Accessibility

Keep information accessible

Reduced motion

Use a short crossfade while preserving forward/back labels and focus position.

Parameters

Parameter reference

ParameterRange / optionsDefaultPurpose
duration80ms–1200ms240msControls the time required for one motion cycle.
distance0px–120px40pxControls how far the element travels.
directionUp / Down / Left / Right / ExitLeftSelects direction.
easeSoft / Snap / Calm / LinearSoftControls how velocity changes over time.