読み込み中の灰色の形をCSSで|スケルトンスクリーンの作り方と使いどころ4種類

読み込み中の灰色の形(スケルトンスクリーン)の見本とコード

ページを開いたとき、文字や写真の場所に灰色の形だけが先に出て、少しあとで中身に置きかわる。この表示を「スケルトンスクリーン」といいます。スケルトンは「骨組み」のことです。ぐるぐる回る印の代わりに、これから出てくるものの形を先に見せます。

使いどころは、1秒より長く待たせる場所で、中身の形が前もって決まっている一覧やカードです。一瞬で表示されるページには出しません。ふつうのWordPressのページは、最初から中身が入った状態で届くので、多くの場合いりません。

この記事の要点

  • 灰色の箱と opacity や transform の動きで、読み込み中の「形」をCSSで作れる(本物への切りかえだけ短いJSを使う)
  • 使いどころは、1秒より長く待たせる場所で、形が決まっている一覧やカード。一瞬で表示されるなら出さない。10秒を超える処理には進み具合のバーを使う
  • 灰色の形と本物の大きさをそろえて、画面がずれないようにする。動きを減らす設定の人には止める。表示を速くする代わりにはならない
トミー

連載「WEBの技術」の51回目です。
1回目のローディングの続きのような話ですが、今回は「形を見せる」待たせ方です。作るのは簡単なので、「いらない場面」もはっきり書きます。

完成見本:灰色の形4種類

見本は自動で動いています。3は、あえて動かさない形です。4は、読み込み中と読み込み後を自動でくり返します。

PULSE1. ふわっと点滅カードが数枚のときに。いちばん落ち着いた動き
SHINE2. 光が流れる一覧のように行が並ぶ場所に
STATIC3. 動かさない形待ち時間が短いページや、文章が中心の場所に
SWAP4. 本物に切りかえるJSであとから中身を入れる場所に

※ 見本は読み上げソフトでは読まれないようにしています。動きを減らす設定にしている方には、止まって見えます。

コピペ用のコード

CSSは、サイトのCSSファイルや、WordPressならテーマの「追加CSS」などに入れます。クラス名の頭の kd-sk は、サイトのほかのデザインと名前がぶつからないようにするための目印です。1のCSSの前半(灰色の形とカードの形)は、2〜4でも使います。4は、2の光る動きのCSSも使います。

1. ふわっと点滅

写真の場所と文字の場所を灰色の箱で描いて、opacity(不透明度)を1と0.45の間で行き来させます。写真は aspect-ratio(縦横の割合)で本物と同じ形にします。

HTML
<div class="kd-sk-card kd-sk-pulse" aria-hidden="true">
  <div class="kd-sk kd-sk-img"></div>
  <div class="kd-sk kd-sk-line"></div>
  <div class="kd-sk kd-sk-line kd-sk-w60"></div>
</div>
CSS
/* 1〜4で使う:灰色の形 */
.kd-sk {
  box-sizing: border-box;
  border: 1px solid transparent; /* 強制カラーのとき、形を線で残す */
  border-radius: 6px;
  background-color: #E2EBF2;
  background-clip: padding-box; /* 透明な枠線の下に色を敷かない */
}
.kd-sk-line {
  height: 14px;
  margin-top: 10px;
}
.kd-sk-w90 { width: 90%; }
.kd-sk-w60 { width: 60%; }
/* 1と4で使う:カードの形 */
.kd-sk-card {
  display: block;
  box-sizing: border-box;
  width: 260px;
  max-width: 100%;
  padding: 14px;
  border-radius: 14px;
  background-color: #FFFFFF;
  box-shadow: 0 2px 6px rgba(16, 40, 58, 0.12);
}
.kd-sk-img {
  aspect-ratio: 16 / 10; /* 本物の画像と同じ縦横の割合 */
  border-radius: 8px;
}
/* 点滅する動き */
.kd-sk-pulse .kd-sk {
  animation: kd-sk-pulse 1.6s ease-in-out infinite;
}
@keyframes kd-sk-pulse {
  50% { opacity: 0.45; }
}
@media (prefers-reduced-motion: reduce) {
  .kd-sk-pulse .kd-sk { animation: none; }
}

2. 光が流れる

灰色の箱の上に、白く光る帯を ::after(箱の中に作る飾りの要素)で重ね、translateX で左から右へ動かします。はみ出した帯は overflow: hidden で隠します。

HTML
<div class="kd-sk-list kd-sk-shine" aria-hidden="true">
  <div class="kd-sk-row">
    <div class="kd-sk kd-sk-circle"></div>
    <div class="kd-sk-col">
      <div class="kd-sk kd-sk-line kd-sk-w60"></div>
      <div class="kd-sk kd-sk-line"></div>
    </div>
  </div>
  <div class="kd-sk-row">
    <div class="kd-sk kd-sk-circle"></div>
    <div class="kd-sk-col">
      <div class="kd-sk kd-sk-line kd-sk-w60"></div>
      <div class="kd-sk kd-sk-line"></div>
    </div>
  </div>
  <div class="kd-sk-row">
    <div class="kd-sk kd-sk-circle"></div>
    <div class="kd-sk-col">
      <div class="kd-sk kd-sk-line kd-sk-w60"></div>
      <div class="kd-sk kd-sk-line"></div>
    </div>
  </div>
</div>
CSS
/* 2と4で使う:光が流れる動き */
.kd-sk-shine .kd-sk {
  position: relative;
  overflow: hidden;
}
.kd-sk-shine .kd-sk::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.75), transparent);
  transform: translateX(-100%);
  animation: kd-sk-shine 1.6s linear infinite;
}
@keyframes kd-sk-shine {
  to { transform: translateX(100%); }
}
@media (prefers-reduced-motion: reduce) {
  .kd-sk-shine .kd-sk::after { animation: none; }
}
/* 一覧の並び */
.kd-sk-list { max-width: 320px; }
.kd-sk-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 18px;
}
.kd-sk-circle {
  flex: none;
  width: 48px;
  height: 48px;
  border-radius: 50%;
}
.kd-sk-col { flex: 1; }
.kd-sk-col .kd-sk-line:first-child { margin-top: 0; }

3. 動かさない形

CSSアニメーションは使いません。見出しを太く、最後の行を短くするだけで、文章が入る場所だと伝わります。動きがないので、見ている人の目を引っぱりません。

HTML
<div class="kd-sk-text" aria-hidden="true">
  <div class="kd-sk kd-sk-head"></div>
  <div class="kd-sk kd-sk-line"></div>
  <div class="kd-sk kd-sk-line"></div>
  <div class="kd-sk kd-sk-line kd-sk-w90"></div>
  <div class="kd-sk kd-sk-line kd-sk-w60"></div>
</div>
CSS
.kd-sk-text { max-width: 320px; }
.kd-sk-head {
  width: 70%;
  height: 22px;
  margin-bottom: 18px;
}

4. 本物に切りかえる

灰色のカードと本物のカードを grid-area: 1 / 1 で同じ場所に重ねます。aria-busy(更新中かどうかを伝える属性)を false に変えると、本物に切りかわります。同じマスに入っているので、切りかわっても高さがずれません。読み込みが終わったことは、空の role="status" に文を入れて知らせます。

HTML
<div class="kd-sk-wrap" aria-busy="true">
  <div class="kd-sk-card kd-sk-shine kd-sk-ghost" aria-hidden="true">
    <div class="kd-sk kd-sk-img"></div>
    <div class="kd-sk kd-sk-line"></div>
    <div class="kd-sk kd-sk-line kd-sk-w60"></div>
  </div>
  <a class="kd-sk-card kd-sk-real" href="/news/1/">
    <img src="photo.jpg" alt="" width="520" height="325">
    <span class="kd-sk-title">新しいお知らせの題名</span>
    <span class="kd-sk-date">2026.11.09</span>
  </a>
</div>
<div id="kd-sk-status" class="kd-sk-vh" role="status"></div>
CSS
.kd-sk-wrap {
  display: grid;
  width: 260px;
  max-width: 100%;
}
.kd-sk-wrap > .kd-sk-card { grid-area: 1 / 1; }
.kd-sk-real {
  color: #10283A;
  text-decoration: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s ease;
}
.kd-sk-real img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 8px;
}
.kd-sk-title {
  display: block;
  margin-top: 10px;
  font-size: 16px;
  font-weight: 700;
  line-height: 1.4;
}
.kd-sk-date {
  display: block;
  margin-top: 2px;
  font-size: 13px;
  color: #4A5F70;
}
.kd-sk-wrap[aria-busy="false"] .kd-sk-real {
  opacity: 1;
  visibility: visible;
}
.kd-sk-wrap[aria-busy="false"] .kd-sk-ghost {
  visibility: hidden;
}
.kd-sk-wrap[aria-busy="false"] .kd-sk-ghost .kd-sk::after {
  animation: none;
}
/* 画面には出さず、読み上げには残す */
.kd-sk-vh {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
@media (prefers-reduced-motion: reduce) {
  .kd-sk-real { transition: none; }
}
JavaScript
// 中身の読み込みが終わったら呼ぶ
function kdSkLoaded(box, message) {
  box.setAttribute('aria-busy', 'false');
  document.getElementById('kd-sk-status').textContent = message;
}
// 動作の確認用:2秒後に、読み込みが終わったことにする
setTimeout(function () {
  kdSkLoaded(document.querySelector('.kd-sk-wrap'), 'お知らせを読み込みました');
}, 2000);

4のJSの後半は、動きを確かめるための2秒待ちです。実際には、データの読み込みが終わったところで kdSkLoaded() を呼びます。

仕組み:何を先に見せているのか

形を見せると、次に出るものが分かる

回る印は「待ってください」としか伝えません。スケルトンは「ここに写真、ここに題名が出ます」まで伝えます。Nielsen Norman Group(画面の使いやすさを調べている会社)も、ページの形を先に示せる点をこの表示の利点に挙げています。ただし、同じ記事で、表示を速くする作業の代わりにはならないとも書かれています。実際に待つ時間は短くなりません。

動かすのは opacity と transform

web.devの解説では、動かすなら transform と opacity が向いているとされています。文字や箱の配置を計算し直したり、絵を描き直したりする作業を避けられるためです。1は opacity、2は transform だけを動かしています。

2の光る帯は、最初 translateX(-100%) で箱の左の外にいます。箱に overflow: hidden が付いているので見えません。右の外まで動かすと、箱の中を光が横切ったように見えます。

4で高さがずれない理由

読み込みが終わって中身が入るときに下の要素が押し下げられると、読んでいた場所がずれます。web.devの「CLS」という指標は、このずれを測るものです。4では、灰色のカードと本物のカードを grid-area: 1 / 1 で同じマスに置いています。マスの高さは大きいほうに合わせて決まるので、切りかわっても高さは変わりません。

1枚ずつ灰色から本物に入れかえる作りにすると、大きさの差がそのままずれになります。入れかえる場合は、写真の aspect-ratio と文字の行数を本物に合わせます。

aria-busy と role=”status” の役割

aria-busy="true" は、MDNによると「この部分は更新中」と支援技術に伝える属性です。灰色の形そのものは意味を持たないので、aria-hidden="true" で読み上げから外しています。

role="status" は、付けただけでは読み上げられません。中身が変わったときに読み上げられるものです。そのため4では、最初は空にしておき、読み込みが終わったところで文を入れています。

数値を変えるとどうなるか

動きの速さ

1の点滅の時間だけを変えました。この3つは動いています。

0.6秒:せわしない
1.6秒:今回の見本
4秒:止まって見える

0.6秒では画面がちらついて見え、4秒では変化に気づきにくくなります。1.2〜2秒くらいが目安です。

灰色の濃さ

#F4F7FA:台に溶ける
#E2EBF2:今回の見本
#94A3B8:重たい

うすすぎると背景に溶けて、まだ何もないページに見えます。濃すぎると、中身より灰色のほうが目立ちます。背景より少し濃いくらいにします。今回の #E2EBF2 は、白い背景でもうっすらと形が分かる濃さです。

形の細かさ

本物
形が合っている
大きな箱が1つ

大きな箱が1つだけだと、どこに何が出るのかが伝わりません。逆に、本物の文字を1文字ずつ再現する必要もありません。写真・題名・短い行、くらいの大きなまとまりで十分です。

文字の行の長さ

全部同じ長さ:帯に見える
最後を短く:文章に見える

全部同じ長さだと、ただの帯に見えます。最後の行を60%くらいに短くすると、文章らしく見えます。

スマホと、見る人への配慮

動きを減らす設定の人には止める

1・2のCSSには prefers-reduced-motion: reduce(動きを減らす設定)のときに animation: none にする指定を入れています。止めても灰色の形は残るので、読み込み中であることは伝わります。Nielsen Norman Groupも、動きのある形は気が散る人がいる点を注意しています。

長く動き続けないようにする

W3Cの基準(2.2.2)では、ほかの内容と並んで自動で5秒より長く動くものには、止める手段が求められています。読み込み中の動きが例外になる条件も書かれていますが、ページの一部だけが読み込み中で、ほかの部分は読める、という形は条件が変わります。読み込みに失敗したまま灰色の形が動き続けないように、エラーのときは「読み込めませんでした」の文に置きかえます。

強制カラーでは、線で形を残す

Windowsのコントラスト設定などの「強制カラー」では、背景の色が使われず、灰色の形が消えます。そこで .kd-sk に透明な枠線(1px solid transparent)を付けています。ふだんは見えない線ですが、強制カラーでは色が付いて、形が残ります。Chromeの強制カラーの再現で確かめました。

スマホでは、並びを本物に合わせる

パソコンで3列、スマホで1列になる一覧なら、灰色の形も同じ並びにします。灰色の形を本物と同じ外側の箱に入れておくと、並びの指定をそのまま使えます。枚数は、スマホの1画面に入るくらいにしぼります。

やりすぎ注意

画面の全部を光らせる、読み込みが一瞬なのに必ず出す、わざと遅らせて出す。どれも見る人の待ち時間を増やすだけです。一瞬で終わる読み込みでは、灰色の形がちらっと見えるだけになります。

AIに頼むなら

Claudeなどの生成AIに頼むときは、本物の形と、読み込みが終わったあとの動きまで伝えると、手直しが減ります。

このカード(HTMLを貼る)の読み込み中に出す灰色の形をCSSで作って。
写真は16:10、題名の行と日付の行。本物と同じ大きさで、切りかえても高さがずれないように。
灰色の部分は aria-hidden、外側に aria-busy。prefers-reduced-motion: reduce では動きを止めて。

AIが出したコードは、そのまま使う前に、次の3つを確かめます。

  • 切りかえたときに下の要素が動かないか。灰色の形と本物の高さの差を、通信を遅くする設定で見ます
  • background-position を動かす作りになっていないか。よく出てくる書き方ですが、絵の描き直しが起きます。形の数が多いページでは、transform の形を選びます
  • 読み込みに失敗したときの表示があるか。成功の流れだけのコードだと、灰色の形が動き続けます

KAKERUならこう使う/使わない

最後に、作り手としての判断です。

使う場面

  • ログイン後の画面や、管理画面の一覧。データを取りに行く間、1秒以上待つことがあり、一覧の形は決まっています
  • JSであとから読み込むお知らせや商品の一覧。形が決まっていて、下に続く内容をずらしたくない場所です
  • 絞り込みで一覧が入れかわる場所。4の形を使います

使わない場面

  • ふつうのWordPressの記事や会社案内。最初から中身が入った状態で届くので、灰色の形を出す場面がありません。表示が遅いなら、画像の圧縮やサーバーの見直しが先です
  • 画像が遅れて出るだけの場所。img に width と height を書いて場所を確保すれば足ります
  • 送信ボタンを押したあとの待ち時間。次に出る形が決まっていないので、1回目のローディングの回転やボタンの中の表示が合います
  • ファイルのアップロードなど、10秒を超える処理。進み具合のバーで、あとどれくらいかを見せます
トミー

KAKERUなら、まず「待たせない」ことを考えます。
それでも待ち時間が残って、形が決まっている場所にだけ、灰色の形を使います。

まとめ

  • スケルトンスクリーンは、これから出てくるものの形を先に見せる表示
  • 1秒より長く待たせる、形が決まった一覧やカードに使う。10秒を超える処理には進み具合のバー
  • 動かすのは opacity か transform。1.2〜2秒くらいで、動きを減らす設定では止める
  • 本物と同じ場所に重ねて、画面をずらさない
  • 表示を速くする代わりにはならない。ふつうのWordPressのページには、多くの場合いらない

まずは1のコードをコピーして、自分のカードの大きさに合わせてみてください。形が合っているだけで、切りかわりが自然に見えます。

参考にした資料

いずれも2026年11月9日に確認しました。内容は変わることがあります。最新の情報は各ページでご確認ください。

ふだんの制作の話や、作ったものの裏側は Instagram と X でも出しています。

関連記事

CSSだけで作るローディングアニメーション コピペで使える5種類と、見る人への配慮
動きが苦手な人への配慮をCSSで。ふつうの見え方と動きを減らす設定の見え方を並べた見本とコード
dialog要素で作るモーダルウィンドウの見本とコード
読み込み中の灰色の形(スケルトンスクリーン)の見本とコード

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です

CAPTCHA


ABOUTこの記事をかいた人

25歳からWEBの世界に携わり、WEBデザインから始めて、今はWEBシステムまで一貫して制作しています。問題点を洗い出し、改善を提案する中で、WEB・グラフィック・動画・システムを縦断して提案するのが得意です。