12 examples Responsive beginner

12 CSS Skeleton Loaders

Every skeleton is hand-coded with only CSS — no libraries, no JavaScript, no dependencies. Drop any snippet straight into your project to replace spinners with content-shaped placeholders.

12 unique skeletons 0 dependencies 100% pure CSS customisable
01 / 12
Classic Shimmer
Pure CSS
A diagonal gradient slides left-to-right across each placeholder bar — the most-recognised skeleton style, used by LinkedIn, Facebook, and Slack.
.sk-classic { width: 220px; display: flex; flex-direction: column; gap: 10px; }
.sk-bar {
  height: 12px; border-radius: 6px;
  background: linear-gradient(90deg, #1f1f28 0%, #2a2a36 50%, #1f1f28 100%);
  background-size: 200% 100%;
  animation: skClassic 1.4s linear infinite;
}
@keyframes skClassic {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
<div class="sk-classic">
  <div class="sk-bar" style="width: 70%"></div>
  <div class="sk-bar" style="width: 90%"></div>
  <div class="sk-bar" style="width: 60%"></div>
</div>
02 / 12
Pulse Block
Pure CSS
A simple opacity pulse — minimal, GPU-friendly, and the default style used by the Tailwind animate-pulse utility class.
.sk-pulse { width: 220px; display: flex; flex-direction: column; gap: 10px; }
.sk-pulse-bar {
  height: 12px; border-radius: 6px;
  background: #2a2a36;
  animation: skPulse 1.5s ease-in-out infinite;
}
@keyframes skPulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.45; }
}
<div class="sk-pulse">
  <div class="sk-pulse-bar" style="width: 80%"></div>
  <div class="sk-pulse-bar" style="width: 60%"></div>
  <div class="sk-pulse-bar" style="width: 70%"></div>
</div>
03 / 12
Avatar Card
Pure CSS
A circular avatar plus two text lines — the canonical user-profile placeholder. Combines a round shimmer with two narrower bars.
.sk-avatar {
  display: flex; align-items: center; gap: 14px;
  width: 220px;
}
.sk-avatar-circle {
  width: 44px; height: 44px; border-radius: 50%;
  background: linear-gradient(90deg, #1f1f28 0%, #2a2a36 50%, #1f1f28 100%);
  background-size: 200% 100%;
  animation: skShimmer 1.5s linear infinite;
  flex-shrink: 0;
}
.sk-avatar-lines { display: flex; flex-direction: column; gap: 8px; }
.sk-avatar-bar {
  height: 11px; border-radius: 5px;
  background: linear-gradient(90deg, #1f1f28 0%, #2a2a36 50%, #1f1f28 100%);
  background-size: 200% 100%;
  animation: skShimmer 1.5s linear infinite;
}
@keyframes skShimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
<div class="sk-avatar">
  <div class="sk-avatar-circle"></div>
  <div class="sk-avatar-lines">
    <div class="sk-avatar-bar" style="width: 110px"></div>
    <div class="sk-avatar-bar" style="width: 70px; height: 8px"></div>
  </div>
</div>
04 / 12
Image Card
Pure CSS
A 16:9 image placeholder topped with a title and two body lines — the "feed item" template every social and blog UI ships with.
.sk-card {
  width: 220px; display: flex; flex-direction: column; gap: 10px;
  padding: 12px; border-radius: 10px;
  background: #15151b;
}
.sk-card-img,
.sk-card-title,
.sk-card-line {
  background: linear-gradient(90deg, #1f1f28 0%, #2a2a36 50%, #1f1f28 100%);
  background-size: 200% 100%;
  animation: skShimmer 1.6s linear infinite;
  border-radius: 6px;
}
.sk-card-img { aspect-ratio: 16 / 9; margin-bottom: 4px; }
.sk-card-title { height: 14px; width: 70%; }
.sk-card-line  { height: 9px; }
@keyframes skShimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
<div class="sk-card">
  <div class="sk-card-img"></div>
  <div class="sk-card-title"></div>
  <div class="sk-card-line" style="width: 95%"></div>
  <div class="sk-card-line" style="width: 75%"></div>
</div>
05 / 12
Wave Sweep
Pure CSS
A bright highlight strip travels across the placeholder using a CSS mask — adds a glassy "light passing over" feel without changing the base colour.
.sk-wave { width: 220px; display: flex; flex-direction: column; gap: 10px; }
.sk-wave-bar {
  height: 12px; border-radius: 6px;
  background: #2a2a36;
  position: relative;
  overflow: hidden;
}
.sk-wave-bar::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(90deg,
    transparent 0%,
    rgba(255,255,255,0.15) 50%,
    transparent 100%);
  transform: translateX(-100%);
  animation: skWave 1.6s linear infinite;
}
@keyframes skWave {
  100% { transform: translateX(100%); }
}
<div class="sk-wave">
  <div class="sk-wave-bar" style="width: 80%"></div>
  <div class="sk-wave-bar" style="width: 95%"></div>
  <div class="sk-wave-bar" style="width: 65%"></div>
</div>
06 / 12
Comment Thread
Pure CSS
Three stacked rows, each a small avatar + two text lines — perfect for chat windows, comment lists, and message inbox loading states.
.sk-thread { width: 220px; display: flex; flex-direction: column; gap: 14px; }
.sk-thread-row { display: flex; gap: 10px; align-items: flex-start; }
.sk-thread-dot {
  width: 26px; height: 26px; border-radius: 50%;
  background: linear-gradient(90deg, #1f1f28 0%, #2a2a36 50%, #1f1f28 100%);
  background-size: 200% 100%;
  animation: skShimmer 1.4s linear infinite;
  flex-shrink: 0;
}
.sk-thread-lines { display: flex; flex-direction: column; gap: 5px; flex: 1; }
.sk-thread-bar {
  height: 11px; border-radius: 5px;
  background: linear-gradient(90deg, #1f1f28 0%, #2a2a36 50%, #1f1f28 100%);
  background-size: 200% 100%;
  animation: skShimmer 1.4s linear infinite;
}
@keyframes skShimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
<div class="sk-thread">
  <div class="sk-thread-row">
    <div class="sk-thread-dot"></div>
    <div class="sk-thread-lines">
      <div class="sk-thread-bar" style="width: 80px; height: 9px"></div>
      <div class="sk-thread-bar" style="width: 140px"></div>
    </div>
  </div>
  <div class="sk-thread-row">
    <div class="sk-thread-dot"></div>
    <div class="sk-thread-lines">
      <div class="sk-thread-bar" style="width: 60px; height: 9px"></div>
      <div class="sk-thread-bar" style="width: 130px"></div>
    </div>
  </div>
  <div class="sk-thread-row">
    <div class="sk-thread-dot"></div>
    <div class="sk-thread-lines">
      <div class="sk-thread-bar" style="width: 70px; height: 9px"></div>
      <div class="sk-thread-bar" style="width: 110px"></div>
    </div>
  </div>
</div>
07 / 12
Article Page
Pure CSS
A page-level skeleton: hero image, headline, byline, and four paragraph lines. The full reading-page placeholder for blog and news templates.
.sk-article { width: 220px; display: flex; flex-direction: column; gap: 7px; }
.sk-article-hero,
.sk-article-h1,
.sk-article-by,
.sk-article-line {
  background: linear-gradient(90deg, #1f1f28 0%, #2a2a36 50%, #1f1f28 100%);
  background-size: 200% 100%;
  animation: skShimmer 1.6s linear infinite;
  border-radius: 5px;
}
.sk-article-hero { height: 60px; border-radius: 8px; margin-bottom: 6px; }
.sk-article-h1   { height: 14px; width: 80%; margin-bottom: 2px; }
.sk-article-by   { height: 9px;  width: 45%; margin-bottom: 6px; }
.sk-article-line { height: 8px; }
@keyframes skShimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
<div class="sk-article">
  <div class="sk-article-hero"></div>
  <div class="sk-article-h1"></div>
  <div class="sk-article-by"></div>
  <div class="sk-article-line" style="width: 100%"></div>
  <div class="sk-article-line" style="width: 95%"></div>
  <div class="sk-article-line" style="width: 90%"></div>
  <div class="sk-article-line" style="width: 60%"></div>
</div>
08 / 12
Table Rows
Pure CSS
Three table rows of three cells each, with a header row above. Each cell shimmers — the canonical placeholder for data tables and dashboards.
.sk-table { width: 220px; display: flex; flex-direction: column; gap: 6px; }
.sk-table-row {
  display: grid; gap: 6px;
  grid-template-columns: 1.5fr 1fr 1fr;
}
.sk-table-cell {
  height: 12px; border-radius: 4px;
  background: linear-gradient(90deg, #1f1f28 0%, #2a2a36 50%, #1f1f28 100%);
  background-size: 200% 100%;
  animation: skShimmer 1.5s linear infinite;
}
.sk-table-head .sk-table-cell {
  background: linear-gradient(90deg, #2a2a36 0%, #353543 50%, #2a2a36 100%);
  background-size: 200% 100%;
  height: 14px;
}
@keyframes skShimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
<div class="sk-table">
  <div class="sk-table-row sk-table-head">
    <div class="sk-table-cell"></div>
    <div class="sk-table-cell"></div>
    <div class="sk-table-cell"></div>
  </div>
  <div class="sk-table-row">
    <div class="sk-table-cell"></div>
    <div class="sk-table-cell"></div>
    <div class="sk-table-cell"></div>
  </div>
  <div class="sk-table-row">
    <div class="sk-table-cell"></div>
    <div class="sk-table-cell"></div>
    <div class="sk-table-cell"></div>
  </div>
  <div class="sk-table-row">
    <div class="sk-table-cell"></div>
    <div class="sk-table-cell"></div>
    <div class="sk-table-cell"></div>
  </div>
</div>
09 / 12
Stat Tiles
Pure CSS
Three KPI tiles in a row, each with a small label and a big number placeholder — the dashboard / analytics loading state.
.sk-stats {
  width: 220px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
}
.sk-stat {
  background: #15151b;
  padding: 10px 8px;
  border-radius: 8px;
  display: flex; flex-direction: column; gap: 6px;
}
.sk-stat-label,
.sk-stat-num {
  background: linear-gradient(90deg, #1f1f28 0%, #2a2a36 50%, #1f1f28 100%);
  background-size: 200% 100%;
  animation: skShimmer 1.5s linear infinite;
  border-radius: 4px;
}
.sk-stat-label { height: 8px;  width: 70%; }
.sk-stat-num   { height: 16px; width: 60%; }
@keyframes skShimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
<div class="sk-stats">
  <div class="sk-stat">
    <div class="sk-stat-label"></div>
    <div class="sk-stat-num"></div>
  </div>
  <div class="sk-stat">
    <div class="sk-stat-label"></div>
    <div class="sk-stat-num"></div>
  </div>
  <div class="sk-stat">
    <div class="sk-stat-label"></div>
    <div class="sk-stat-num"></div>
  </div>
</div>
10 / 12
Gradient Glow
Pure CSS
A soft brand-coloured gradient sweeps through each bar — a more decorative shimmer that fits hero sections and marketing pages.
.sk-glow { width: 220px; display: flex; flex-direction: column; gap: 10px; }
.sk-glow-bar {
  height: 14px; border-radius: 7px;
  background: linear-gradient(90deg,
    #1a1a22 0%,
    rgba(124,108,255,0.35) 30%,
    rgba(255,108,138,0.35) 60%,
    #1a1a22 100%);
  background-size: 200% 100%;
  animation: skGlow 1.8s linear infinite;
}
@keyframes skGlow {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
<div class="sk-glow">
  <div class="sk-glow-bar" style="width: 90%"></div>
  <div class="sk-glow-bar" style="width: 70%"></div>
  <div class="sk-glow-bar" style="width: 80%"></div>
</div>
11 / 12
List with Thumbnails
Pure CSS
A search-result / file-browser layout: square thumbnail beside two text lines, repeated three times. Mirrors media library and admin list views.
.sk-list { width: 220px; display: flex; flex-direction: column; gap: 12px; }
.sk-list-row { display: flex; gap: 10px; align-items: center; }
.sk-list-thumb {
  width: 40px; height: 40px; border-radius: 7px;
  background: linear-gradient(90deg, #1f1f28 0%, #2a2a36 50%, #1f1f28 100%);
  background-size: 200% 100%;
  animation: skShimmer 1.5s linear infinite;
  flex-shrink: 0;
}
.sk-list-text { display: flex; flex-direction: column; gap: 6px; flex: 1; }
.sk-list-bar {
  height: 11px; border-radius: 5px;
  background: linear-gradient(90deg, #1f1f28 0%, #2a2a36 50%, #1f1f28 100%);
  background-size: 200% 100%;
  animation: skShimmer 1.5s linear infinite;
}
@keyframes skShimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
<div class="sk-list">
  <div class="sk-list-row">
    <div class="sk-list-thumb"></div>
    <div class="sk-list-text">
      <div class="sk-list-bar" style="width: 70%"></div>
      <div class="sk-list-bar" style="width: 50%; height: 8px"></div>
    </div>
  </div>
  <div class="sk-list-row">
    <div class="sk-list-thumb"></div>
    <div class="sk-list-text">
      <div class="sk-list-bar" style="width: 85%"></div>
      <div class="sk-list-bar" style="width: 40%; height: 8px"></div>
    </div>
  </div>
  <div class="sk-list-row">
    <div class="sk-list-thumb"></div>
    <div class="sk-list-text">
      <div class="sk-list-bar" style="width: 60%"></div>
      <div class="sk-list-bar" style="width: 65%; height: 8px"></div>
    </div>
  </div>
</div>
12 / 12
Chip Cluster
Pure CSS
Pill-shaped chips of varying widths shimmer in a flex-wrap layout — the right placeholder for tag filters, category lists, and search facets.
.sk-chips {
  width: 220px;
  display: flex; flex-wrap: wrap; gap: 8px;
}
.sk-chip {
  height: 22px; border-radius: 11px;
  background: linear-gradient(90deg, #1f1f28 0%, #2a2a36 50%, #1f1f28 100%);
  background-size: 200% 100%;
  animation: skShimmer 1.5s linear infinite;
}
@keyframes skShimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
<div class="sk-chips">
  <div class="sk-chip" style="width: 56px"></div>
  <div class="sk-chip" style="width: 80px"></div>
  <div class="sk-chip" style="width: 48px"></div>
  <div class="sk-chip" style="width: 72px"></div>
  <div class="sk-chip" style="width: 60px"></div>
  <div class="sk-chip" style="width: 90px"></div>
  <div class="sk-chip" style="width: 50px"></div>
</div>

Related collections