← каталог
Skeleton Shimmer
Скелетон-карточка с бегущим бликом: одна keyframes-анимация синхронно ведёт shimmer по всем «костям».
cssautobasic0reduced-motion ✓
Установка
npx shadcn@latest add https://motiva.pages.dev/r/skeleton-shimmer.jsonЧто нужно в проекте до установки
components.jsonв корне — с алиасами в форме"components": "@/components". Нет файла — CLI не поймёт, куда класть.- Алиас
@объявлен дважды:"paths": {"@/*": ["./src/*"]}в корневомtsconfig.json(в Vite он часто содержит толькоreferences— тогда CLI создаёт папку@) иresolve.aliasв конфиге сборщика. - Токены подключены один раз на приложение:
import "@/styles/motiva-tokens.css"— они приезжают вместе с записью. Без них секция потеряет цвета, ритм и тему. - Своя типографика не должна спорить: если у вас на обёртке
text-align: center, он протечёт внутрь блоков. - Проект без TypeScript? Всё равно нужен минимальный
tsconfig.jsonсpathsи"tsx": trueвcomponents.json: CLI грузит tsconfig безусловно, а с"tsx": falseидёт заjsconfig.jsonи падает так же. Приехавший рядом.tsxможно не трогать — вам нужен.vanilla.js.
Экспорт
Код
import type { CSSProperties } from "react";
const bone = (extra: CSSProperties): CSSProperties => ({
borderRadius: 8,
background: "oklch(0.24 0.015 270)",
position: "relative",
overflow: "hidden",
...extra,
});
/**
* Скелетон-карточка с бегущим бликом (shimmer): градиентная полоса едет по «костям»
* синхронно (общая keyframes-анимация). Чистый CSS. Reduced-motion/data-shot — блик статичен.
*/
export function SkeletonShimmer() {
return (
<div
className="sk-card"
style={{
width: "min(320px, 84vw)",
padding: "1.2rem",
borderRadius: 16,
border: "1px solid oklch(0.3 0.02 270)",
background: "oklch(0.18 0.02 270)",
display: "grid",
gap: 12,
}}
aria-busy="true"
aria-label="Загрузка контента"
>
<style>{`
.sk-card [data-bone]::after {
content: "";
position: absolute;
inset: 0;
transform: translateX(-100%);
background: linear-gradient(100deg, transparent 30%, oklch(0.5 0.02 270 / 0.35) 50%, transparent 70%);
animation: sk-sweep 1.6s ease-in-out infinite;
}
@keyframes sk-sweep { to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) {
.sk-card [data-bone]::after { animation: none; }
}
`}</style>
<div style={{ display: "flex", gap: 12, alignItems: "center" }}>
<div data-bone style={bone({ width: 44, height: 44, borderRadius: "50%" })} />
<div style={{ display: "grid", gap: 8, flex: 1 }}>
<div data-bone style={bone({ height: 12, width: "70%" })} />
<div data-bone style={bone({ height: 10, width: "45%" })} />
</div>
</div>
<div data-bone style={bone({ height: 130, borderRadius: 12 })} />
<div style={{ display: "grid", gap: 8 }}>
<div data-bone style={bone({ height: 10 })} />
<div data-bone style={bone({ height: 10, width: "85%" })} />
<div data-bone style={bone({ height: 10, width: "60%" })} />
</div>
</div>
);
}
Похожие эффекты
лицензия: MITавтор: Motivaисточник: оригинал (Motiva)v1.0.0