hover-effectHover effect
悬停效果Visual change when the cursor moves over an element.
光标移到元素上方时产生的视觉变化。
Reinforce interactivity on pointer hover while keeping layout stable.
Visual change when the cursor moves over an element.
English definitions are preserved verbatim from Animation Vocabulary; translations and distinctions help you choose precisely.
hover-effectVisual change when the cursor moves over an element.
光标移到元素上方时产生的视觉变化。
Purpose, frequency, trigger, timing, interruptibility, and gesture rules shape the implementation.
Reinforce interactivity on fine-pointer hover while keeping layout and hit targets stable.
Suitable for frequent controls when amplitude and duration remain very small.
Trigger on pointerenter only when hover:hover and pointer:fine match.
Enter the emphasized state on hover and restore quickly on leave, keeping content position stable.
Return from current styles during rapid pointer movement without queuing animations.
Touch devices do not emulate hover, and focus-visible provides equivalent affordance.
Keep static hover and focus color, border, or shadow changes while removing travel and scale.
Current parameters update visual-state CSS, semantic HTML, the required vanilla JS runtime, and an interaction prompt.
.motion-demo.motion-demo--hover-effect {
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--hover-effect *, .motion-demo.motion-demo--hover-effect *::before, .motion-demo.motion-demo--hover-effect *::after {
box-sizing: border-box;
}
.motion-demo.motion-demo--hover-effect .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--hover-effect .motion-line {
display: block;
width: 100%;
height: 0.5rem;
background: #e4e4e7;
border-radius: 999px;
}
.motion-demo.motion-demo--hover-effect .motion-line:last-child { width: 62%; }
.motion-demo.motion-demo--hover-effect .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--hover-effect .motion-button:focus-visible { outline: 3px solid rgb(37 99 235 / 32%); outline-offset: 3px; }
.motion-demo.motion-demo--hover-effect .motion-action-row {
display: flex;
justify-content: center;
gap: 0.5rem;
margin-top: 0.85rem;
}
.motion-demo.motion-demo--hover-effect .motion-replay-scene {
width: min(100%, 22rem);
display: grid;
place-items: center;
}
.motion-demo.motion-demo--hover-effect .motion-pausable-scene {
width: min(100%, 22rem);
display: grid;
place-items: center;
}
.motion-demo.motion-demo--hover-effect button.motion-surface {
color: inherit;
font: inherit;
text-align: start;
cursor: pointer;
}
.motion-demo.motion-demo--hover-effect .motion-replay-button,
.motion-demo.motion-demo--hover-effect .motion-undo-button,
.motion-demo.motion-demo--hover-effect .motion-dismiss-button,
.motion-demo.motion-demo--hover-effect .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--hover-effect .motion-replay-button:focus-visible,
.motion-demo.motion-demo--hover-effect .motion-undo-button:focus-visible,
.motion-demo.motion-demo--hover-effect .motion-dismiss-button:focus-visible,
.motion-demo.motion-demo--hover-effect .motion-pause-button:focus-visible,
.motion-demo.motion-demo--hover-effect [data-reorder-item]:focus-visible,
.motion-demo.motion-demo--hover-effect [data-swipe-target]:focus-visible {
outline: 3px solid rgb(37 99 235 / 32%);
outline-offset: 3px;
}
.motion-demo.motion-demo--hover-effect .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--hover-effect .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--hover-effect .motion-state-stack { position: relative; width: min(100%, 18rem); height: 9rem; }
.motion-demo.motion-demo--hover-effect .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--hover-effect .motion-state--to { background: #18181b; color: white; }
.motion-demo.motion-demo--hover-effect .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--hover-effect .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--hover-effect .motion-text-stack { position: relative; width: min(100%, 18rem); min-height: 4rem; }
.motion-demo.motion-demo--hover-effect svg { width: min(100%, 20rem); height: auto; }
.motion-demo.motion-demo--hover-effect .motion-button { transition: transform 150ms cubic-bezier(0.16, 1, 0.3, 1); }
@media (hover: hover) and (pointer: fine) {
.motion-demo.motion-demo--hover-effect .motion-button:hover { transform: translateY(-4px) scale(1.01); box-shadow: 0 14px 28px rgb(0 0 0 / 16%); }
}
@keyframes motion-hover-effect-reduced-fade {
from { opacity: 0.84; }
to { opacity: 1; }
}
.force-reduced-motion .motion-demo.motion-demo--hover-effect {
animation: motion-hover-effect-reduced-fade 160ms cubic-bezier(0.23, 1, 0.32, 1) both !important;
}
.force-reduced-motion .motion-demo.motion-demo--hover-effect *,
.force-reduced-motion .motion-demo.motion-demo--hover-effect *::before,
.force-reduced-motion .motion-demo.motion-demo--hover-effect *::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--hover-effect .motion-button,
.force-reduced-motion .motion-demo.motion-demo--hover-effect [data-reorder-item],
.force-reduced-motion .motion-demo.motion-demo--hover-effect [data-swipe-target],
.force-reduced-motion .motion-demo.motion-demo--hover-effect [data-spring-target] {
transform: none !important;
}
.force-reduced-motion .motion-demo.motion-demo--hover-effect .motion-path { stroke-dashoffset: 0 !important; }
.force-reduced-motion .motion-demo.motion-demo--hover-effect .motion-word--from { opacity: 0 !important; visibility: hidden; }
.force-reduced-motion .motion-demo.motion-demo--hover-effect .motion-word:not(.motion-word--from) { opacity: 1 !important; filter: none !important; transform: none !important; }
@media (prefers-reduced-motion: reduce) {
.motion-demo.motion-demo--hover-effect {
animation: motion-hover-effect-reduced-fade 160ms cubic-bezier(0.23, 1, 0.32, 1) both !important;
}
.motion-demo.motion-demo--hover-effect *, .motion-demo.motion-demo--hover-effect *::before, .motion-demo.motion-demo--hover-effect *::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--hover-effect .motion-button,
.motion-demo.motion-demo--hover-effect [data-reorder-item],
.motion-demo.motion-demo--hover-effect [data-swipe-target],
.motion-demo.motion-demo--hover-effect [data-spring-target] {
transform: none !important;
}
.motion-demo.motion-demo--hover-effect .motion-path { stroke-dashoffset: 0 !important; }
.motion-demo.motion-demo--hover-effect .motion-word--from { opacity: 0 !important; visibility: hidden; }
.motion-demo.motion-demo--hover-effect .motion-word:not(.motion-word--from) { opacity: 1 !important; filter: none !important; transform: none !important; }
}Keep static hover and focus color, border, or shadow changes while removing travel and scale.
| Parameter | Range / options | Default | Purpose |
|---|---|---|---|
duration | 80ms–1200ms | 150ms | Controls the time required for one motion cycle. |
distance | 0px–16px | 4px | Controls how far the element travels. |
scale | 70%–105% | 101% | Controls the starting size relative to the final state. |
ease | Soft / Snap / Calm / Linear | Snap | Controls how velocity changes over time. |