springSpring
弹簧Motion driven by physics (tension, mass, damping) rather than a set duration.
由张力、质量和阻尼等物理参数驱动的运动,不依赖固定时长。
Tune a physical spring response with stiffness, damping, mass, and initial velocity.
Motion driven by physics (tension, mass, damping) rather than a set duration.
English definitions are preserved verbatim from Animation Vocabulary; translations and distinctions help you choose precisely.
springMotion driven by physics (tension, mass, damping) rather than a set duration.
由张力、质量和阻尼等物理参数驱动的运动,不依赖固定时长。
stiffness-tensionHow strongly the spring pulls toward its target. Higher feels snappier.
弹簧拉向目标的力度,数值越高,响应越干脆。
Stiffness / Tension controls how strongly a spring pulls toward its target; it is a spring-model parameter.
dampingHow quickly a spring settles. Lower damping means more bounce and oscillation.
弹簧稳定下来的速度;阻尼越低,回弹和振荡越明显。
Damping controls how quickly oscillation settles; Spring is the full physical model that includes damping.
massHow heavy the animated element feels. More mass makes it slower and more sluggish.
动画元素呈现出的重量;质量越大,运动越慢、越沉。
Mass controls perceived weight and inertia; it works with stiffness and damping to shape a spring response.
bounceA spring that overshoots and settles, adding playfulness.
弹簧越过目标后再稳定下来,为动作增加活泼感。
Bounce is a spring overshooting and settling, commonly produced by lower damping with suitable stiffness.
perceptual-durationHow long a spring feels finished, even though it keeps micro-settling underneath.
弹簧在感知上完成所需的时长,尽管底层仍在进行微小的收敛。
Perceptual duration describes when a spring feels finished to the user; it differs from a fixed CSS duration.
momentumMotion that carries velocity, especially after a drag or interruption.
保留速度并继续前进的运动,常见于拖拽释放或动画中断之后。
Momentum preserves velocity after release or interruption; a spring can receive and carry that velocity.
velocityHow fast and in which direction an element is moving. A spring carries it into the next animation when interrupted, so a flicked element keeps its speed.
元素移动的快慢与方向;弹簧会在中断时把它带入下一段动画,使被快速甩动的元素保留速度。
Velocity records speed and direction; a spring can use it as the initial condition for the next response.
interruptible-animationAn animation that can be smoothly redirected mid-flight instead of finishing first.
动画可以在运行途中平滑地改变目标,无需等待当前动作完成。
Interruptible animation names the ability to retarget motion smoothly in flight; a spring is one way to implement it.
Purpose, frequency, trigger, timing, interruptibility, and gesture rules shape the implementation.
Shape interruptible, velocity-preserving physical response through stiffness, damping, mass, and initial velocity.
Use for medium-frequency gesture settling and object following; frequent micro-feedback needs high damping and short perceptual duration.
Trigger on drag release, target-position changes, or state transitions, passing current velocity.
Settle from current value toward the target, limiting exit overshoot so content stays within safe bounds.
A new target immediately inherits current position and velocity, which is central to the spring experience.
Pass gesture velocity in the same coordinate space, settle to the nearest safe target on cancel, and use discrete keyboard targets.
Use high damping or immediate arrival, removing bounce and prolonged micro-oscillation.
Current parameters update visual-state CSS, semantic HTML, the required vanilla JS runtime, and an interaction prompt.
.motion-demo.motion-demo--spring {
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--spring *, .motion-demo.motion-demo--spring *::before, .motion-demo.motion-demo--spring *::after {
box-sizing: border-box;
}
.motion-demo.motion-demo--spring .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--spring .motion-line {
display: block;
width: 100%;
height: 0.5rem;
background: #e4e4e7;
border-radius: 999px;
}
.motion-demo.motion-demo--spring .motion-line:last-child { width: 62%; }
.motion-demo.motion-demo--spring .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--spring .motion-button:focus-visible { outline: 3px solid rgb(37 99 235 / 32%); outline-offset: 3px; }
.motion-demo.motion-demo--spring .motion-action-row {
display: flex;
justify-content: center;
gap: 0.5rem;
margin-top: 0.85rem;
}
.motion-demo.motion-demo--spring .motion-replay-scene {
width: min(100%, 22rem);
display: grid;
place-items: center;
}
.motion-demo.motion-demo--spring .motion-pausable-scene {
width: min(100%, 22rem);
display: grid;
place-items: center;
}
.motion-demo.motion-demo--spring button.motion-surface {
color: inherit;
font: inherit;
text-align: start;
cursor: pointer;
}
.motion-demo.motion-demo--spring .motion-replay-button,
.motion-demo.motion-demo--spring .motion-undo-button,
.motion-demo.motion-demo--spring .motion-dismiss-button,
.motion-demo.motion-demo--spring .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--spring .motion-replay-button:focus-visible,
.motion-demo.motion-demo--spring .motion-undo-button:focus-visible,
.motion-demo.motion-demo--spring .motion-dismiss-button:focus-visible,
.motion-demo.motion-demo--spring .motion-pause-button:focus-visible,
.motion-demo.motion-demo--spring [data-reorder-item]:focus-visible,
.motion-demo.motion-demo--spring [data-swipe-target]:focus-visible {
outline: 3px solid rgb(37 99 235 / 32%);
outline-offset: 3px;
}
.motion-demo.motion-demo--spring .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--spring .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--spring .motion-state-stack { position: relative; width: min(100%, 18rem); height: 9rem; }
.motion-demo.motion-demo--spring .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--spring .motion-state--to { background: #18181b; color: white; }
.motion-demo.motion-demo--spring .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--spring .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--spring .motion-text-stack { position: relative; width: min(100%, 18rem); min-height: 4rem; }
.motion-demo.motion-demo--spring svg { width: min(100%, 20rem); height: auto; }
.motion-demo.motion-demo--spring .motion-surface[data-spring-target] { cursor: pointer; will-change: transform, opacity; }
.motion-demo.motion-demo--spring .motion-surface[data-spring-target]:focus-visible { outline: 3px solid rgb(37 99 235 / 32%); outline-offset: 3px; }
@keyframes motion-spring-reduced-fade {
from { opacity: 0.84; }
to { opacity: 1; }
}
.force-reduced-motion .motion-demo.motion-demo--spring {
animation: motion-spring-reduced-fade 160ms cubic-bezier(0.23, 1, 0.32, 1) both !important;
}
.force-reduced-motion .motion-demo.motion-demo--spring *,
.force-reduced-motion .motion-demo.motion-demo--spring *::before,
.force-reduced-motion .motion-demo.motion-demo--spring *::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--spring .motion-button,
.force-reduced-motion .motion-demo.motion-demo--spring [data-reorder-item],
.force-reduced-motion .motion-demo.motion-demo--spring [data-swipe-target],
.force-reduced-motion .motion-demo.motion-demo--spring [data-spring-target] {
transform: none !important;
}
.force-reduced-motion .motion-demo.motion-demo--spring .motion-path { stroke-dashoffset: 0 !important; }
.force-reduced-motion .motion-demo.motion-demo--spring .motion-word--from { opacity: 0 !important; visibility: hidden; }
.force-reduced-motion .motion-demo.motion-demo--spring .motion-word:not(.motion-word--from) { opacity: 1 !important; filter: none !important; transform: none !important; }
@media (prefers-reduced-motion: reduce) {
.motion-demo.motion-demo--spring {
animation: motion-spring-reduced-fade 160ms cubic-bezier(0.23, 1, 0.32, 1) both !important;
}
.motion-demo.motion-demo--spring *, .motion-demo.motion-demo--spring *::before, .motion-demo.motion-demo--spring *::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--spring .motion-button,
.motion-demo.motion-demo--spring [data-reorder-item],
.motion-demo.motion-demo--spring [data-swipe-target],
.motion-demo.motion-demo--spring [data-spring-target] {
transform: none !important;
}
.motion-demo.motion-demo--spring .motion-path { stroke-dashoffset: 0 !important; }
.motion-demo.motion-demo--spring .motion-word--from { opacity: 0 !important; visibility: hidden; }
.motion-demo.motion-demo--spring .motion-word:not(.motion-word--from) { opacity: 1 !important; filter: none !important; transform: none !important; }
}Use high damping or immediate arrival, removing bounce and prolonged micro-oscillation.
| Parameter | Range / options | Default | Purpose |
|---|---|---|---|
stiffness | 60–500 | 220 | Adjusts stiffness. |
damping | 5–60 | 24 | Adjusts damping. |
mass | 0.5x–3x | 1x | Adjusts mass. |
velocity | -20–20 | 0 | Adjusts initial velocity. |
distance | 0px–160px | 48px | Controls how far the element travels. |