@use 'sprucecss/scss/spruce' as *;
.skeleton-card {
display: flex;
gap: spacer('m');
&__lines {
flex-grow: 1;
@include layout-stack('xs');
}
}
.skeleton {
--skeleton-base: #{color-alpha('heading', 0.08)};
--skeleton-shine: #{color-alpha('heading', 0.16)};
background-color: var(--skeleton-base);
border-radius: radius('sm');
@include motion-safe {
animation: skeleton-shine 1.4s ease-in-out infinite;
background-image: linear-gradient(90deg, transparent, var(--skeleton-shine), transparent);
background-repeat: no-repeat;
background-size: 50% 100%;
}
&--avatar {
block-size: 3.5rem;
border-radius: 50%;
flex-shrink: 0;
inline-size: 3.5rem;
}
&--title {
block-size: 1.5rem;
inline-size: 60%;
}
&--text {
block-size: 0.875rem;
}
&--short {
inline-size: 40%;
}
&--media {
aspect-ratio: 16 / 9;
border-radius: radius('lg');
}
}
@keyframes skeleton-shine {
from {
background-position: -100% 0;
}
to {
background-position: 200% 0;
}
}
<div class="skeleton-card" aria-busy="true" aria-live="polite">
<span class="sr-only">Loading content…</span>
<div class="skeleton skeleton--avatar" aria-hidden="true"></div>
<div class="skeleton-card__lines" aria-hidden="true">
<div class="skeleton skeleton--title"></div>
<div class="skeleton skeleton--text"></div>
<div class="skeleton skeleton--text"></div>
<div class="skeleton skeleton--text skeleton--short"></div>
</div>
</div>
<div class="skeleton skeleton--media" aria-hidden="true"></div>