skeleton-shimmerSkeleton / Shimmer
骨架屏 / 微光A placeholder with a moving sheen shown while content loads.
内容加载期间显示的占位结构,表面带有移动的微光。
Communicate loading progress with a low-contrast shimmer across placeholders.
A placeholder with a moving sheen shown while content loads.
English definitions are preserved verbatim from Animation Vocabulary; translations and distinctions help you choose precisely.
skeleton-shimmerA placeholder with a moving sheen shown while content loads.
内容加载期间显示的占位结构,表面带有移动的微光。
Purpose, frequency, trigger, timing, interruptibility, and gesture rules shape the implementation.
Preserve layout during loading and communicate ongoing work through a low-contrast shimmer.
Show only when expected waiting exceeds a brief threshold, rendering fast results directly.
Trigger after a loading-delay threshold and stop as soon as real content is ready.
Show static placeholders first, loop a slow shimmer, and crossfade briefly into real content.
Update state on cancel or retry without stacking shimmer timers.
Skeletons are noninteractive while cancel, back, or retry controls remain available.
Disable shimmer and keep a static skeleton with explicit loading text.
Current parameters update visual-state CSS, semantic HTML, the required vanilla JS runtime, and an interaction prompt.
.motion-demo.motion-demo--skeleton-shimmer {
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--skeleton-shimmer *, .motion-demo.motion-demo--skeleton-shimmer *::before, .motion-demo.motion-demo--skeleton-shimmer *::after {
box-sizing: border-box;
}
.motion-demo.motion-demo--skeleton-shimmer .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--skeleton-shimmer .motion-line {
display: block;
width: 100%;
height: 0.5rem;
background: #e4e4e7;
border-radius: 999px;
}
.motion-demo.motion-demo--skeleton-shimmer .motion-line:last-child { width: 62%; }
.motion-demo.motion-demo--skeleton-shimmer .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--skeleton-shimmer .motion-button:focus-visible { outline: 3px solid rgb(37 99 235 / 32%); outline-offset: 3px; }
.motion-demo.motion-demo--skeleton-shimmer .motion-action-row {
display: flex;
justify-content: center;
gap: 0.5rem;
margin-top: 0.85rem;
}
.motion-demo.motion-demo--skeleton-shimmer .motion-replay-scene {
width: min(100%, 22rem);
display: grid;
place-items: center;
}
.motion-demo.motion-demo--skeleton-shimmer .motion-pausable-scene {
width: min(100%, 22rem);
display: grid;
place-items: center;
}
.motion-demo.motion-demo--skeleton-shimmer button.motion-surface {
color: inherit;
font: inherit;
text-align: start;
cursor: pointer;
}
.motion-demo.motion-demo--skeleton-shimmer .motion-replay-button,
.motion-demo.motion-demo--skeleton-shimmer .motion-undo-button,
.motion-demo.motion-demo--skeleton-shimmer .motion-dismiss-button,
.motion-demo.motion-demo--skeleton-shimmer .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--skeleton-shimmer .motion-replay-button:focus-visible,
.motion-demo.motion-demo--skeleton-shimmer .motion-undo-button:focus-visible,
.motion-demo.motion-demo--skeleton-shimmer .motion-dismiss-button:focus-visible,
.motion-demo.motion-demo--skeleton-shimmer .motion-pause-button:focus-visible,
.motion-demo.motion-demo--skeleton-shimmer [data-reorder-item]:focus-visible,
.motion-demo.motion-demo--skeleton-shimmer [data-swipe-target]:focus-visible {
outline: 3px solid rgb(37 99 235 / 32%);
outline-offset: 3px;
}
.motion-demo.motion-demo--skeleton-shimmer .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--skeleton-shimmer .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--skeleton-shimmer .motion-state-stack { position: relative; width: min(100%, 18rem); height: 9rem; }
.motion-demo.motion-demo--skeleton-shimmer .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--skeleton-shimmer .motion-state--to { background: #18181b; color: white; }
.motion-demo.motion-demo--skeleton-shimmer .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--skeleton-shimmer .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--skeleton-shimmer .motion-text-stack { position: relative; width: min(100%, 18rem); min-height: 4rem; }
.motion-demo.motion-demo--skeleton-shimmer svg { width: min(100%, 20rem); height: auto; }
.motion-demo.motion-demo--skeleton-shimmer .motion-skeleton { display: grid; gap: 0.7rem; width: min(100%, 18rem); }
.motion-demo.motion-demo--skeleton-shimmer .motion-skeleton-line { height: 0.8rem; overflow: hidden; background: #e4e4e7; border-radius: 999px; }
.motion-demo.motion-demo--skeleton-shimmer .motion-skeleton-line::after { content: ""; display: block; width: 45%; height: 100%; background: linear-gradient(90deg, transparent, rgb(255 255 255 / 0.14), transparent); animation: motion-skeleton-shimmer 1400ms linear infinite; }
@keyframes motion-skeleton-shimmer { from { transform: translateX(-120%); } to { transform: translateX(280%); } }
@keyframes motion-skeleton-shimmer-reduced-fade {
from { opacity: 0.84; }
to { opacity: 1; }
}
.force-reduced-motion .motion-demo.motion-demo--skeleton-shimmer {
animation: motion-skeleton-shimmer-reduced-fade 160ms cubic-bezier(0.23, 1, 0.32, 1) both !important;
}
.force-reduced-motion .motion-demo.motion-demo--skeleton-shimmer *,
.force-reduced-motion .motion-demo.motion-demo--skeleton-shimmer *::before,
.force-reduced-motion .motion-demo.motion-demo--skeleton-shimmer *::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--skeleton-shimmer .motion-button,
.force-reduced-motion .motion-demo.motion-demo--skeleton-shimmer [data-reorder-item],
.force-reduced-motion .motion-demo.motion-demo--skeleton-shimmer [data-swipe-target],
.force-reduced-motion .motion-demo.motion-demo--skeleton-shimmer [data-spring-target] {
transform: none !important;
}
.force-reduced-motion .motion-demo.motion-demo--skeleton-shimmer .motion-path { stroke-dashoffset: 0 !important; }
.force-reduced-motion .motion-demo.motion-demo--skeleton-shimmer .motion-word--from { opacity: 0 !important; visibility: hidden; }
.force-reduced-motion .motion-demo.motion-demo--skeleton-shimmer .motion-word:not(.motion-word--from) { opacity: 1 !important; filter: none !important; transform: none !important; }
@media (prefers-reduced-motion: reduce) {
.motion-demo.motion-demo--skeleton-shimmer {
animation: motion-skeleton-shimmer-reduced-fade 160ms cubic-bezier(0.23, 1, 0.32, 1) both !important;
}
.motion-demo.motion-demo--skeleton-shimmer *, .motion-demo.motion-demo--skeleton-shimmer *::before, .motion-demo.motion-demo--skeleton-shimmer *::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--skeleton-shimmer .motion-button,
.motion-demo.motion-demo--skeleton-shimmer [data-reorder-item],
.motion-demo.motion-demo--skeleton-shimmer [data-swipe-target],
.motion-demo.motion-demo--skeleton-shimmer [data-spring-target] {
transform: none !important;
}
.motion-demo.motion-demo--skeleton-shimmer .motion-path { stroke-dashoffset: 0 !important; }
.motion-demo.motion-demo--skeleton-shimmer .motion-word--from { opacity: 0 !important; visibility: hidden; }
.motion-demo.motion-demo--skeleton-shimmer .motion-word:not(.motion-word--from) { opacity: 1 !important; filter: none !important; transform: none !important; }
}Disable shimmer and keep a static skeleton with explicit loading text.
| Parameter | Range / options | Default | Purpose |
|---|---|---|---|
duration | 800ms–3000ms | 1400ms | Controls the rhythm of one full cycle; continuous motion should stay pausable and low-distraction. |
intensity | 5%–30% | 14% | Adjusts shimmer intensity. |