Compositing

Compare compositor-friendly properties, hardware-acceleration hints, and layout-triggering properties.

Preview

Live preview

Letting the GPU move or fade an element on its own layer without redoing layout or paint.

Preview
Compositing
Authoritative vocabulary

Definition and close-term distinctions

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

Canonical termcompositing

Compositing

合成
Authoritative definition

Letting the GPU move or fade an element on its own layer without redoing layout or paint.

Chinese translation

让 GPU 在独立图层上移动元素或改变其透明度,无需重新执行布局或绘制。

Browse all 91 terms
Design contract

Decide before this motion ships

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

Purpose

Compare compositor-friendly properties with layout- or paint-triggering properties to choose a stable rendering path.

Frequency

Review during new motion implementation, performance regressions, and integration into complex pages.

Trigger

Trigger from property selection or a performance experiment while recording main-thread, layout, paint, and compositing activity.

Enter / exit

Switch property strategies directly and keep metric changes readable without extra transitions affecting results.

Interruptibility

Allow tests to stop and reset layer state, enabling will-change only shortly before it is needed.

Gesture and keyboard

Drive compared strategies with identical gesture distance and speed.

Reduced-motion strategy

Reduced-motion mode still favors transform and opacity while limiting persistent layer allocation.

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--compositing {
  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--compositing *, .motion-demo.motion-demo--compositing *::before, .motion-demo.motion-demo--compositing *::after {
  box-sizing: border-box;
}

.motion-demo.motion-demo--compositing .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--compositing .motion-line {
  display: block;
  width: 100%;
  height: 0.5rem;
  background: #e4e4e7;
  border-radius: 999px;
}

.motion-demo.motion-demo--compositing .motion-line:last-child { width: 62%; }

.motion-demo.motion-demo--compositing .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--compositing .motion-button:focus-visible { outline: 3px solid rgb(37 99 235 / 32%); outline-offset: 3px; }

.motion-demo.motion-demo--compositing .motion-action-row {
  display: flex;
  justify-content: center;
  gap: 0.5rem;
  margin-top: 0.85rem;
}

.motion-demo.motion-demo--compositing .motion-replay-scene {
  width: min(100%, 22rem);
  display: grid;
  place-items: center;
}

.motion-demo.motion-demo--compositing .motion-pausable-scene {
  width: min(100%, 22rem);
  display: grid;
  place-items: center;
}

.motion-demo.motion-demo--compositing button.motion-surface {
  color: inherit;
  font: inherit;
  text-align: start;
  cursor: pointer;
}

.motion-demo.motion-demo--compositing .motion-replay-button,
.motion-demo.motion-demo--compositing .motion-undo-button,
.motion-demo.motion-demo--compositing .motion-dismiss-button,
.motion-demo.motion-demo--compositing .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--compositing .motion-replay-button:focus-visible,
.motion-demo.motion-demo--compositing .motion-undo-button:focus-visible,
.motion-demo.motion-demo--compositing .motion-dismiss-button:focus-visible,
.motion-demo.motion-demo--compositing .motion-pause-button:focus-visible,
.motion-demo.motion-demo--compositing [data-reorder-item]:focus-visible,
.motion-demo.motion-demo--compositing [data-swipe-target]:focus-visible {
  outline: 3px solid rgb(37 99 235 / 32%);
  outline-offset: 3px;
}

.motion-demo.motion-demo--compositing .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--compositing .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--compositing .motion-state-stack { position: relative; width: min(100%, 18rem); height: 9rem; }
.motion-demo.motion-demo--compositing .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--compositing .motion-state--to { background: #18181b; color: white; }

.motion-demo.motion-demo--compositing .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--compositing .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--compositing .motion-text-stack { position: relative; width: min(100%, 18rem); min-height: 4rem; }
.motion-demo.motion-demo--compositing svg { width: min(100%, 20rem); height: auto; }

.motion-demo.motion-demo--compositing .motion-surface { position: relative; animation: motion-compositing 520ms linear infinite alternate; }
@keyframes motion-compositing { from { transform: translateX(-80px); } to { transform: translateX(80px); } }

@keyframes motion-compositing-reduced-fade {
  from { opacity: 0.84; }
  to { opacity: 1; }
}

.force-reduced-motion .motion-demo.motion-demo--compositing {
  animation: motion-compositing-reduced-fade 160ms cubic-bezier(0.23, 1, 0.32, 1) both !important;
}

.force-reduced-motion .motion-demo.motion-demo--compositing *,
.force-reduced-motion .motion-demo.motion-demo--compositing *::before,
.force-reduced-motion .motion-demo.motion-demo--compositing *::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--compositing .motion-button,
.force-reduced-motion .motion-demo.motion-demo--compositing [data-reorder-item],
.force-reduced-motion .motion-demo.motion-demo--compositing [data-swipe-target],
.force-reduced-motion .motion-demo.motion-demo--compositing [data-spring-target] {
  transform: none !important;
}

.force-reduced-motion .motion-demo.motion-demo--compositing .motion-path { stroke-dashoffset: 0 !important; }
.force-reduced-motion .motion-demo.motion-demo--compositing .motion-word--from { opacity: 0 !important; visibility: hidden; }
.force-reduced-motion .motion-demo.motion-demo--compositing .motion-word:not(.motion-word--from) { opacity: 1 !important; filter: none !important; transform: none !important; }

@media (prefers-reduced-motion: reduce) {
  .motion-demo.motion-demo--compositing {
    animation: motion-compositing-reduced-fade 160ms cubic-bezier(0.23, 1, 0.32, 1) both !important;
  }

  .motion-demo.motion-demo--compositing *, .motion-demo.motion-demo--compositing *::before, .motion-demo.motion-demo--compositing *::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--compositing .motion-button,
  .motion-demo.motion-demo--compositing [data-reorder-item],
  .motion-demo.motion-demo--compositing [data-swipe-target],
  .motion-demo.motion-demo--compositing [data-spring-target] {
    transform: none !important;
  }

  .motion-demo.motion-demo--compositing .motion-path { stroke-dashoffset: 0 !important; }
  .motion-demo.motion-demo--compositing .motion-word--from { opacity: 0 !important; visibility: hidden; }
  .motion-demo.motion-demo--compositing .motion-word:not(.motion-word--from) { opacity: 1 !important; filter: none !important; transform: none !important; }
}
Review notes

Pre-delivery review

  • Distinguish Compositing, will-change, and Layout thrashing.
  • Inspect layer count, memory use, and cleanup after completion.
Accessibility

Keep information accessible

Reduced motion

Reduced-motion mode still favors transform and opacity while limiting persistent layer allocation.

Parameters

Parameter reference

ParameterRange / optionsDefaultPurpose
duration300ms–1200ms520msUses a longer demo duration so the full change stays observable; immediate production UI feedback should stay under 300ms.
distance0px–180px80pxControls how far the element travels.
propertyTransform / Left / OpacityTransformSelects compared property.
easeSoft / Snap / Calm / LinearLinearControls how velocity changes over time.