press-tap-feedbackPress / Tap feedback
按压 / 轻触反馈A subtle scale-down when an element is clicked, so it feels physical.
元素被点击时轻微缩小,让操作具有实体触感。
Confirm input immediately with a brief scale and contrast response.
A subtle scale-down when an element is clicked, so it feels physical.
English definitions are preserved verbatim from Animation Vocabulary; translations and distinctions help you choose precisely.
press-tap-feedbackA subtle scale-down when an element is clicked, so it feels physical.
元素被点击时轻微缩小,让操作具有实体触感。
Purpose, frequency, trigger, timing, interruptibility, and gesture rules shape the implementation.
Confirm input at press time and give the control a subtle physical response.
Use for frequent buttons and clickable cards, keeping feedback around 70–140ms.
Trigger on pointerdown, touchstart, or the press phase of Space and Enter.
Scale down slightly and increase contrast on press, restoring immediately on release or cancel.
Pointer cancel, target exit, and repeated key presses restore from the current scale.
Tie feedback to the real pressed state without delaying the action or expanding accidental hit areas.
Remove scaling and keep an immediate color, border, or luminance response.
Current parameters update visual-state CSS, semantic HTML, the required vanilla JS runtime, and an interaction prompt.
.motion-demo.motion-demo--press-tap-feedback {
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--press-tap-feedback *, .motion-demo.motion-demo--press-tap-feedback *::before, .motion-demo.motion-demo--press-tap-feedback *::after {
box-sizing: border-box;
}
.motion-demo.motion-demo--press-tap-feedback .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--press-tap-feedback .motion-line {
display: block;
width: 100%;
height: 0.5rem;
background: #e4e4e7;
border-radius: 999px;
}
.motion-demo.motion-demo--press-tap-feedback .motion-line:last-child { width: 62%; }
.motion-demo.motion-demo--press-tap-feedback .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--press-tap-feedback .motion-button:focus-visible { outline: 3px solid rgb(37 99 235 / 32%); outline-offset: 3px; }
.motion-demo.motion-demo--press-tap-feedback .motion-action-row {
display: flex;
justify-content: center;
gap: 0.5rem;
margin-top: 0.85rem;
}
.motion-demo.motion-demo--press-tap-feedback .motion-replay-scene {
width: min(100%, 22rem);
display: grid;
place-items: center;
}
.motion-demo.motion-demo--press-tap-feedback .motion-pausable-scene {
width: min(100%, 22rem);
display: grid;
place-items: center;
}
.motion-demo.motion-demo--press-tap-feedback button.motion-surface {
color: inherit;
font: inherit;
text-align: start;
cursor: pointer;
}
.motion-demo.motion-demo--press-tap-feedback .motion-replay-button,
.motion-demo.motion-demo--press-tap-feedback .motion-undo-button,
.motion-demo.motion-demo--press-tap-feedback .motion-dismiss-button,
.motion-demo.motion-demo--press-tap-feedback .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--press-tap-feedback .motion-replay-button:focus-visible,
.motion-demo.motion-demo--press-tap-feedback .motion-undo-button:focus-visible,
.motion-demo.motion-demo--press-tap-feedback .motion-dismiss-button:focus-visible,
.motion-demo.motion-demo--press-tap-feedback .motion-pause-button:focus-visible,
.motion-demo.motion-demo--press-tap-feedback [data-reorder-item]:focus-visible,
.motion-demo.motion-demo--press-tap-feedback [data-swipe-target]:focus-visible {
outline: 3px solid rgb(37 99 235 / 32%);
outline-offset: 3px;
}
.motion-demo.motion-demo--press-tap-feedback .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--press-tap-feedback .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--press-tap-feedback .motion-state-stack { position: relative; width: min(100%, 18rem); height: 9rem; }
.motion-demo.motion-demo--press-tap-feedback .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--press-tap-feedback .motion-state--to { background: #18181b; color: white; }
.motion-demo.motion-demo--press-tap-feedback .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--press-tap-feedback .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--press-tap-feedback .motion-text-stack { position: relative; width: min(100%, 18rem); min-height: 4rem; }
.motion-demo.motion-demo--press-tap-feedback svg { width: min(100%, 20rem); height: auto; }
.motion-demo.motion-demo--press-tap-feedback .motion-button { transition: transform 120ms cubic-bezier(0.16, 1, 0.3, 1); }
.motion-demo.motion-demo--press-tap-feedback .motion-button:active { transform: scale(0.96); }
@keyframes motion-press-tap-feedback-reduced-fade {
from { opacity: 0.84; }
to { opacity: 1; }
}
.force-reduced-motion .motion-demo.motion-demo--press-tap-feedback {
animation: motion-press-tap-feedback-reduced-fade 160ms cubic-bezier(0.23, 1, 0.32, 1) both !important;
}
.force-reduced-motion .motion-demo.motion-demo--press-tap-feedback *,
.force-reduced-motion .motion-demo.motion-demo--press-tap-feedback *::before,
.force-reduced-motion .motion-demo.motion-demo--press-tap-feedback *::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--press-tap-feedback .motion-button,
.force-reduced-motion .motion-demo.motion-demo--press-tap-feedback [data-reorder-item],
.force-reduced-motion .motion-demo.motion-demo--press-tap-feedback [data-swipe-target],
.force-reduced-motion .motion-demo.motion-demo--press-tap-feedback [data-spring-target] {
transform: none !important;
}
.force-reduced-motion .motion-demo.motion-demo--press-tap-feedback .motion-path { stroke-dashoffset: 0 !important; }
.force-reduced-motion .motion-demo.motion-demo--press-tap-feedback .motion-word--from { opacity: 0 !important; visibility: hidden; }
.force-reduced-motion .motion-demo.motion-demo--press-tap-feedback .motion-word:not(.motion-word--from) { opacity: 1 !important; filter: none !important; transform: none !important; }
@media (prefers-reduced-motion: reduce) {
.motion-demo.motion-demo--press-tap-feedback {
animation: motion-press-tap-feedback-reduced-fade 160ms cubic-bezier(0.23, 1, 0.32, 1) both !important;
}
.motion-demo.motion-demo--press-tap-feedback *, .motion-demo.motion-demo--press-tap-feedback *::before, .motion-demo.motion-demo--press-tap-feedback *::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--press-tap-feedback .motion-button,
.motion-demo.motion-demo--press-tap-feedback [data-reorder-item],
.motion-demo.motion-demo--press-tap-feedback [data-swipe-target],
.motion-demo.motion-demo--press-tap-feedback [data-spring-target] {
transform: none !important;
}
.motion-demo.motion-demo--press-tap-feedback .motion-path { stroke-dashoffset: 0 !important; }
.motion-demo.motion-demo--press-tap-feedback .motion-word--from { opacity: 0 !important; visibility: hidden; }
.motion-demo.motion-demo--press-tap-feedback .motion-word:not(.motion-word--from) { opacity: 1 !important; filter: none !important; transform: none !important; }
}Remove scaling and keep an immediate color, border, or luminance response.
| Parameter | Range / options | Default | Purpose |
|---|---|---|---|
duration | 80ms–1200ms | 120ms | Controls the time required for one motion cycle. |
scale | 70%–105% | 96% | Controls the starting size relative to the final state. |
ease | Soft / Snap / Calm / Linear | Snap | Controls how velocity changes over time. |