スケルトンシマーとは?UXを高める設計・実装方法とコード例
Webサイトやアプリケーションでは、データを取得して画面へ表示するまでに、わずかな待ち時間が発生します。通信環境や端末性能によっては、その待ち時間が数秒に延びることもあります。何も表示されない空白画面が続くと、利用者は「操作が止まった」「ページの読み込みに失敗した」と感じやすくなり、離脱や再読み込みにつながります。
こうした待ち時間の体験を改善する手法として広く使われているのが、スケルトンシマーです。実際のコンテンツに近い形のプレースホルダーを先に表示し、その表面に光が流れるようなアニメーションを加えることで、画面が正常に読み込まれていることを視覚的に伝えます。
本記事では、スケルトンシマーの意味や役割だけでなく、スケルトンスクリーン、スピナー、プログレスバーとの違い、デザイン設計、CSSやJavaScriptによる実装、Reactなどの環境で利用する方法まで詳しく解説します。アクセシビリティや表示性能、効果測定についても取り上げるため、実務で導入を検討している担当者や開発者にも役立つ内容です。
1. スケルトンシマーとは
スケルトンシマーは、コンテンツの読み込み中に仮のレイアウトを表示し、その表面を光が移動するように見せるローディング表現です。利用者に待機状態を伝えるだけでなく、これから表示される情報の位置や構造を事前に示せる点に特徴があります。
1.1 スケルトンシマーの意味
スケルトンシマーとは、テキスト、画像、カード、ボタンなどの配置を灰色や淡い色の図形で表現し、その上に明るい帯を移動させる表示方法です。「スケルトン」はコンテンツの骨組みを表し、「シマー」は表面がきらめくように動く視覚効果を意味します。
静止したプレースホルダーだけでも読み込み中であることは示せますが、動きがない場合は画面が停止しているように見える可能性があります。シマーアニメーションを加えることで、データ取得や画面描画が継続しているという印象を与えやすくなります。
1.2 スケルトン表示に動きを加える理由
読み込み画面に動きを加える目的は、単に見た目を華やかにすることではありません。利用者は画面内に継続的な変化があると、処理が進行していると認識しやすくなります。シマーは一定方向に流れるため、処理中であることを直感的に伝えられます。
ただし、動きを強くしすぎるとコンテンツよりもアニメーションが目立ち、視覚的な疲労を引き起こします。適切な速度、明度差、表示時間を設定し、あくまで待ち時間を補助する要素として設計することが重要です。
1.3 実際のコンテンツ構造を模倣する仕組み
スケルトンシマーでは、読み込み後に表示されるコンテンツの形を可能な範囲で再現します。記事一覧であれば画像領域、タイトル行、概要文、日付を表す図形を配置し、商品一覧であれば商品画像、価格、商品名、評価欄などを表現します。
実際のレイアウトと仮表示の形が近いほど、読み込み完了時の位置移動を抑えられます。一方で、内容を正確に予測できない場合は、複雑な形を再現しすぎず、主要な情報領域だけを示すほうが安定した表示になります。
| コンテンツ | スケルトンで表す主な要素 |
|---|---|
| 記事一覧 | サムネイル、タイトル、概要文、日付 |
| 商品一覧 | 商品画像、商品名、価格、評価 |
| 利用者情報 | アイコン、氏名、所属、紹介文 |
| 動画一覧 | 動画画像、再生時間、タイトル |
| コメント欄 | 利用者アイコン、名前、本文 |
1.4 利用される主な画面
スケルトンシマーは、記事一覧、商品一覧、検索結果、管理画面、利用者プロフィール、タイムラインなど、複数の情報を非同期で取得する画面に適しています。特にカード形式のレイアウトは表示構造を予測しやすいため、スケルトンとの相性が良い傾向があります。
一方で、保存処理や決済処理のように進行状況を具体的に示す必要がある場面では、スケルトンシマーだけでは状態を十分に説明できません。用途に応じて、進捗率、処理メッセージ、ボタンの無効化などと組み合わせる必要があります。
1.5 スケルトンシマーが注目される背景
Webサービスでは画像、広告、外部サービスの情報、利用者ごとのデータなど、複数の情報を読み込む場面が増えています。すべての通信が完了するまで画面を空白にすると、体感的な待ち時間が長くなり、操作可能になるまでの不安も大きくなります。
スケルトンシマーは、コンテンツの枠組みを早い段階で表示することで、待ち時間を画面構築の途中段階として見せられます。通信時間そのものを短縮する技術ではありませんが、利用者が感じる待ち時間を軽減するUX施策として採用されています。
2. スケルトンシマーが待ち時間の体験を改善する仕組み
スケルトンシマーの役割は、読み込み中であることを伝えるだけではありません。利用者の視線を適切に誘導し、表示される情報の位置を予測させることで、読み込み後の操作を始めやすくします。
2.1 体感待ち時間を短く見せる効果
同じ2秒間の読み込みであっても、空白画面とスケルトン画面では利用者の受ける印象が異なります。空白画面では処理状況が分からないため、実際の時間以上に長く感じることがあります。スケルトンが表示されると、画面構築が始まっていると認識できます。
利用者は表示予定の領域を見ながら次の操作を予測できるため、待機だけに意識を集中しにくくなります。この心理的な効果によって、通信時間を変更せずに体感速度を改善できる可能性があります。
2.2 情報配置を事前に伝える効果
商品画像や記事タイトルの位置が事前に示されていれば、読み込み完了後にどこを確認すればよいかを予測できます。特に一覧画面では、カードの大きさや並び方が分かるだけでも、利用者は画面構造を理解しやすくなります。
ただし、スケルトンの形と実際の情報配置が大きく異なると、かえって混乱を招きます。仮表示では存在していた要素が読み込み後に消えたり、大幅に高さが変わったりすると、表示の信頼性が低下します。
2.3 読み込み失敗との誤解を減らす効果
空白画面や静止した画面が続くと、利用者は通信エラーやアプリケーションの停止を疑います。シマーアニメーションが継続していれば、少なくとも処理が進行中であることを視覚的に判断できます。
ただし、長時間シマーだけを表示し続ける設計は避ける必要があります。一定時間を超えてもデータが取得できない場合は、エラーメッセージ、再試行ボタン、代替情報などを表示し、利用者が次の行動を選べるようにします。
2.4 読み込み後の視線移動を抑える効果
スケルトンと完成後のコンテンツの位置が一致していれば、利用者の視線は大きく移動しません。タイトルが表示される位置、画像が配置される場所、操作ボタンの位置を先に示すことで、読み込み完了後の情報探索を短縮できます。
反対に、スケルトンと実際のコンテンツで高さや余白が異なると、読み込み完了時に画面全体が動きます。表示位置の変化は誤操作の原因になるため、実際のコンポーネントと同じ寸法を利用する設計が望まれます。
2.5 読み込み中の画面に一貫性を持たせる効果
ページごとに異なるローディング表現を使うと、利用者は処理状態を判断しにくくなります。ある画面ではスピナー、別の画面では空白、さらに別の画面ではシマーという状態では、サービス全体の操作感も不統一になります。
共通の色、角丸、アニメーション速度を定義し、コンポーネントとして再利用できるようにすると、一貫した体験を提供できます。ただし、すべての処理をスケルトンに統一するのではなく、処理内容に合った表示を選ぶことが前提です。
3. スケルトンシマーとスケルトンスクリーンの違い
スケルトンシマーとスケルトンスクリーンは同じ意味で使われることもありますが、厳密には指している範囲が異なります。スケルトンスクリーンは画面上の仮レイアウト全体を指し、スケルトンシマーはその仮レイアウトに光の動きを加えた表現を指します。
3.1 表示方法の違い
スケルトンスクリーンは、読み込み後の構造を灰色の図形などで示す表示全体です。アニメーションを含まない静止型もスケルトンスクリーンに含まれます。スケルトンシマーは、その表面に明るい帯が流れるアニメーションを追加した形式です。
処理時間が極めて短い場合は、静止型でも十分なことがあります。待ち時間がある程度発生する画面では、シマーを付けることで処理継続中であることを示しやすくなります。
| 比較項目 | スケルトンスクリーン | スケルトンシマー |
|---|---|---|
| 仮レイアウト | 表示する | 表示する |
| 光のアニメーション | 必須ではない | 表示する |
| 動作中の印象 | 弱い場合がある | 伝わりやすい |
| 描画負荷 | 比較的低い | 設計によって増える |
| 動きへの配慮 | 少ない | 必要になる |
3.2 アニメーションの有無による違い
静止型のスケルトンスクリーンは、CSSで背景色と寸法を設定するだけでも実装できます。動きがないため描画負荷を抑えやすく、動きに敏感な利用者にも提供しやすい点が利点です。
スケルトンシマーでは、背景位置や疑似要素を一定方向に動かします。処理中であることは伝えやすくなりますが、多数の要素を同時に動かすと端末への負荷が高くなる可能性があります。
| 状況 | 静止型 | シマー型 |
|---|---|---|
| 読み込みが1秒未満 | 適している | 表示しない選択も可能 |
| 読み込みが1~3秒 | 利用可能 | 適している |
| 大量のカードを表示 | 負荷が低い | 要素数の調整が必要 |
| 省電力を優先 | 適している | 停止条件が必要 |
| 処理中を強調 | 弱い | 強い |
3.3 利用目的の違い
スケルトンスクリーンの主な目的は、読み込み後のレイアウトを事前に示すことです。利用者は画像やテキストの配置を把握し、完成後の画面を予測できます。静止型でも、この目的は達成できます。
スケルトンシマーは、レイアウト予告に加えて、処理が現在も進行していることを伝える役割を持ちます。待ち時間が長く見えやすい画面や、通信状況によって表示時間が変動する画面で有効です。
| 目的 | スケルトンスクリーン | スケルトンシマー |
|---|---|---|
| レイアウトを予告する | 強い | 強い |
| 処理の継続を伝える | 中程度 | 強い |
| 視線を誘導する | 中程度 | 強い |
| 描画負荷を抑える | 強い | 設計次第 |
| 動きを減らす | 強い | 弱い |
3.4 適した画面の違い
静止型は、管理画面や社内システムなど、機能性と安定性を重視する画面で利用しやすい方法です。表示項目が多くても、アニメーションによる視覚的な騒がしさを抑えられます。
シマー型は、商品一覧、記事一覧、SNSのタイムラインなど、画像やカードが中心となる画面に適しています。利用者の注意を自然に画面へ向けながら、読み込み状態を伝えられます。
| 画面 | 推奨形式 | 理由 |
|---|---|---|
| 商品一覧 | シマー型 | 画像と価格の配置を予告しやすい |
| 記事詳細 | 静止型またはシマー型 | 読み込み時間に応じて選べる |
| 管理画面 | 静止型 | 情報量が多く動きが目立ちやすい |
| SNSタイムライン | シマー型 | カードの連続表示と相性が良い |
| 設定画面 | 静止型 | 複雑な動きが不要 |
3.5 選択時に確認すべき違い
どちらを選ぶかは、平均読み込み時間、同時に表示する要素数、対象端末、利用者層によって判断します。動きを追加すれば必ずUXが改善するわけではなく、短時間しか表示されない場合は点滅のように見える可能性があります。
シマーを採用する場合は、動きを減らす端末設定への対応も必要です。静止型を標準とし、条件に応じてシマーを付ける方法も選択肢になります。
| 判断基準 | 静止型が向く条件 | シマー型が向く条件 |
|---|---|---|
| 読み込み時間 | 短い | 中程度 |
| 要素数 | 多い | 適度 |
| 端末性能 | 幅広い | 一定以上を想定 |
| 視覚的な演出 | 控えめ | 必要 |
| アクセシビリティ | 優先度が高い | 停止対応が可能 |
4. スケルトンシマーとほかのローディング表示の違い
ローディング表示には、スピナー、プログレスバー、プレースホルダー、ぼかし画像など複数の方法があります。処理の種類や完了までの見通しによって、適した表示方法は異なります。
4.1 スピナーとの違い
スピナーは円形などの図形を回転させ、処理中であることを示す方法です。実装が簡単で小さな領域にも配置できますが、どのようなコンテンツが表示されるかは伝えられません。
スケルトンシマーは画面構造を示せるため、一覧画面や詳細画面に適しています。一方で、ボタンの送信処理や小規模な部品の更新では、スピナーのほうが簡潔です。
| 比較項目 | スケルトンシマー | スピナー |
|---|---|---|
| 画面構造の予告 | 可能 | 不可能 |
| 小領域への配置 | 不向きな場合がある | 適している |
| 実装量 | 多い | 少ない |
| 待ち時間の印象 | 短く感じやすい | 長く感じる場合がある |
| 主な用途 | コンテンツ取得 | 送信・更新処理 |
4.2 プログレスバーとの違い
プログレスバーは、処理の完了割合や進行方向を棒状の表示で示します。ファイルのアップロードや大規模な処理など、完了までの割合を計算できる場面に適しています。
スケルトンシマーは完了割合を示すものではありません。データ取得時間を正確に予測できない場合や、複数要素が順番に表示される場合に利用しやすい方法です。
| 比較項目 | スケルトンシマー | プログレスバー |
|---|---|---|
| 進捗率 | 表示しない | 表示できる |
| 完了予測 | 難しい | 比較的しやすい |
| コンテンツ配置 | 予告できる | 予告できない |
| 適した処理 | データ取得 | アップロードや変換 |
| 数値表示 | 通常は不要 | 場合により必要 |
4.3 単色プレースホルダーとの違い
単色プレースホルダーは、画像やテキストの領域を静止した図形で示します。実装負荷が低く、多数の要素を表示しても端末への影響を抑えやすい方法です。
スケルトンシマーは動きを加えることで処理中の印象を強めます。ただし、表示時間が短い場合や低性能端末を重視する場合は、単色プレースホルダーのほうが適することがあります。
| 比較項目 | スケルトンシマー | 単色プレースホルダー |
|---|---|---|
| アニメーション | あり | なし |
| 処理中の伝わりやすさ | 高い | 中程度 |
| 描画負荷 | 高くなる場合がある | 低い |
| 実装難易度 | 中程度 | 低い |
| 動きへの配慮 | 必要 | 原則不要 |
4.4 ぼかし画像との違い
ぼかし画像は、低解像度の画像を先に表示し、高解像度画像の読み込み後に差し替える方法です。画像の色や雰囲気を事前に示せるため、写真を中心としたページで有効です。
スケルトンシマーは画像の内容までは表現せず、配置と寸法を示します。画像情報を事前に生成できる場合はぼかし画像、画像以外のテキストやカードも含めて仮表示したい場合はスケルトンが適しています。
| 比較項目 | スケルトンシマー | ぼかし画像 |
|---|---|---|
| 画像の色を予告 | できない | できる |
| テキスト領域への利用 | 可能 | 不向き |
| 事前データ | 不要 | 低解像度画像が必要 |
| 主な対象 | 画面全体 | 画像 |
| レイアウト維持 | 可能 | 可能 |
4.5 ローディング文言との違い
「読み込み中です」といった文言は、現在の状態を明確に伝えられます。処理内容や待つ必要がある理由も文章で説明できるため、重要な操作や長時間処理に適しています。
スケルトンシマーは、視覚的に状態を伝える方法です。必要に応じて、画面読み上げ用の文言や長時間読み込み時のメッセージと組み合わせることで、より多くの利用者に状態を伝えられます。
| 比較項目 | スケルトンシマー | ローディング文言 |
|---|---|---|
| 視覚的な構造予告 | 可能 | 不可能 |
| 状態の具体的な説明 | 弱い | 強い |
| 画面読み上げ | 追加対応が必要 | 対応しやすい |
| 短時間処理 | 適している | 点滅して見える場合がある |
| 長時間処理 | 補助表示が必要 | 適している |
5. スケルトンシマーを導入するメリット
適切に設計されたスケルトンシマーは、待ち時間の印象を改善し、画面構造の理解を助けます。ただし、通信速度そのものを向上させるわけではないため、性能改善と併用する必要があります。
5.1 離脱を抑えやすくなる
読み込み中に空白画面が続くと、利用者は表示失敗と判断し、前のページへ戻ったり画面を閉じたりする可能性があります。スケルトンを表示すれば、情報がまもなく表示されることを示せます。
特に検索結果や商品一覧では、閲覧開始までの不安を減らすことが重要です。スケルトンだけで離脱を完全に防げるわけではありませんが、何も表示しない状態よりも継続利用を促しやすくなります。
5.2 レイアウトの変動を抑えられる
実際のコンテンツと同じ高さや幅のスケルトンを確保しておくと、読み込み後の位置移動を軽減できます。画像が後から挿入されてテキストやボタンが押し下げられる問題も防ぎやすくなります。
レイアウトの安定は、見た目だけでなく操作性にも影響します。押そうとしたボタンが読み込みによって移動すると、別の要素を誤って選択する可能性があるため、寸法の事前確保が重要です。
5.3 コンテンツへの期待を形成できる
スケルトンの形によって、記事、商品、動画、コメントなど、これから表示される情報の種類を示せます。利用者は画面を見た瞬間に、どのような内容が読み込まれているかを推測できます。
ただし、期待させた構造と実際の構造が一致しないと、画面の分かりにくさにつながります。スケルトンは装飾ではなく、コンテンツ構造を正確に伝える案内として設計します。
5.4 ブランドの操作感を統一できる
背景色、明るい帯の色、角丸、動作速度をデザイン規則として定義すると、サービス全体で一貫したローディング体験を作れます。ページごとに異なる表現を実装するよりも、品質管理もしやすくなります。
ブランドカラーを強く反映すると、シマーが目立ちすぎる場合があります。通常は無彩色や低彩度の色を中心にし、サービスの背景色と自然になじむ表現を選びます。
5.5 段階的な表示と組み合わせやすい
画像、タイトル、価格などの情報が別々の通信から取得される場合、取得できた部分から順番に実データへ置き換えられます。すべての情報がそろうまで待つ必要がないため、重要な内容を早く見せられます。
ただし、細かく置き換えすぎると画面内の変化が頻繁に発生し、落ち着かない印象になります。カード単位や領域単位など、利用者が変化を追いやすいまとまりで切り替えることが重要です。
6. スケルトンシマーの視覚設計
見やすいスケルトンシマーを作るには、色、形、余白、情報量を実際のコンテンツに合わせる必要があります。派手な演出よりも、読み込み後の画面へ自然につながることを優先します。
6.1 背景色と光の色を決める
スケルトン本体には、ページ背景より少し明るい色または暗い色を使用します。光の帯には、本体との違いが分かる範囲で近い色を設定すると、強すぎない動きを作れます。
明度差が小さすぎると動きが見えず、大きすぎると点滅のように感じられます。明るい画面と暗い画面で別の色を用意し、利用環境に合わせて調整することが重要です。
| 表示環境 | 本体色の例 | 光の色の例 |
|---|---|---|
| 明るい画面 | #e7e7e7 | #f3f3f3 |
| やや灰色の背景 | #dddddd | #ececec |
| 暗い画面 | #2b2b2b | #3a3a3a |
| 高コントラスト画面 | 背景との差を確保 | 動きを弱くする |
6.2 実際のコンテンツに近い寸法を使う
画像領域には固定の縦横比を設定し、タイトルには実際の文字数を想定した幅を与えます。本文を表す線はすべて同じ長さにせず、最後の行だけ短くすると自然な見た目になります。
ただし、実際の文章量を正確に予測できない場合は、最大高さに合わせるのではなく、代表的な高さを使用します。データごとの差が大きい場合は、読み込み後の位置移動を最小限に抑えられる設計を検討します。
6.3 角丸を実コンポーネントに合わせる
カード、画像、ボタン、利用者アイコンには、それぞれ異なる角丸が使われます。スケルトンでも同じ角丸を再現すると、読み込み前後の視覚的な連続性を保ちやすくなります。
すべての要素を同じ角丸にすると、実際のコンテンツ構造が分かりにくくなる場合があります。円形アイコン、長方形画像、丸みのあるボタンなど、役割に応じて形を変えます。
6.4 表示する要素数を絞る
実際の画面に多くの情報がある場合でも、すべてをスケルトン化する必要はありません。主要画像、タイトル、本文、主な操作領域など、レイアウト理解に必要な要素を中心に表示します。
細い線や小さなラベルまで再現すると、画面全体が灰色の図形で埋まり、情報量が多く見えます。仮表示の段階では視認性を優先し、装飾的な要素は省略します。
6.5 デザイン変数として共通管理する
スケルトンの色、角丸、アニメーション速度、光の幅を個別に記述すると、画面ごとの差が生まれやすくなります。CSSのカスタムプロパティやデザイン管理の仕組みを使い、共通値として定義します。
共通値を使用すれば、暗い画面への対応やブランド変更もまとめて行えます。カードごとに必要な寸法だけを変更し、視覚表現は共通化する方法が効率的です。
CSS変数の例
:root {
--skeleton-base: #e5e7eb;
--skeleton-highlight: #f3f4f6;
--skeleton-radius: 8px;
--skeleton-duration: 1.4s;
}
@media (prefers-color-scheme: dark) {
:root {
--skeleton-base: #2f3237;
--skeleton-highlight: #41454c;
}
}
7. シマーアニメーションの設計
シマーアニメーションは、利用者に処理中であることを伝える重要な要素です。ただし、速度や方向、光の幅を適切に設定しなければ、目立ちすぎたり動きが不自然になったりします。
7.1 アニメーション速度を調整する
一般的には、光の帯が要素全体を1秒から2秒程度で通過する動きが使われます。速すぎると点滅やちらつきのように見え、遅すぎると動いていることが分かりにくくなります。
カードが多数並ぶ場合は、すべてを高速で動かすよりも、少し長めの時間を設定したほうが落ち着いた印象になります。実機で確認し、低性能端末でも滑らかに表示できる速度を選びます。
7.2 光の移動方向を統一する
日本語の横書き画面では、左から右へ光を移動させる表現が自然です。ページ内で方向が混在すると、複数の動きが視線を奪い、落ち着かない画面になります。
右から左へ読む言語に対応する場合は、文書方向に合わせて移動方向を変更することも検討します。固定値だけに依存せず、画面の方向設定に対応できる実装が望まれます。
7.3 光の幅を要素サイズに合わせる
光の帯が細すぎると線が移動しているように見え、広すぎると要素全体が一度に明滅して見えます。要素幅の20%から40%程度を目安にしながら、カードや画面サイズに合わせて調整します。
小さなアイコンと大きな画像領域で同じ幅を使用すると、見え方が異なります。背景のグラデーションを要素サイズに応じて変えるか、共通値でも不自然にならない範囲を選びます。
7.4 開始時間をずらすか判断する
複数のカードを同時に表示する場合、すべてのシマーを同じタイミングで動かす方法と、少しずつ開始時間をずらす方法があります。同時に動かすと規則的ですが、大きな面が一斉に光るため目立ちやすくなります。
開始時間をずらすと自然な動きになりますが、要素数が多い場合は画面全体で動きが途切れなくなります。視認性と描画負荷を確認し、必要以上に複雑な遅延を設定しないことが重要です。
7.5 長時間表示時の動きを制御する
通信エラーなどでスケルトンが長時間表示されると、利用者は処理が続いているのか失敗しているのか判断できません。数秒を超えた場合は説明文を表示し、さらに時間が経過した場合は再試行できる状態へ移行します。
アニメーションを無制限に継続させるのではなく、一定時間後に弱めたり停止したりする方法もあります。利用者へ必要な情報を伝えることを優先し、シマーだけに状態説明を任せない設計が必要です。
8. CSSでスケルトンシマーを実装する方法
スケルトンシマーは、HTMLとCSSだけでも実装できます。疑似要素や背景グラデーションを使い、光の帯が左から右へ移動するアニメーションを設定する方法が一般的です。
8.1 HTMLの構造を作る
最初に、カード全体、画像、タイトル、本文を表す要素を用意します。実際のコンテンツと同じ構造に近づけると、読み込み後の差し替えや寸法管理がしやすくなります。
スケルトン要素は装飾目的であるため、画面読み上げ機能へ不要な情報として伝わらないようにします。読み込み状態は、別の状態文言を使って通知する方法が適切です。
HTML実装例
<article class="skeleton-card" aria-hidden="true">
<div class="skeleton skeleton-image"></div>
<div class="skeleton-card__body">
<div class="skeleton skeleton-title"></div>
<div class="skeleton skeleton-text"></div>
<div class="skeleton skeleton-text skeleton-text--short"></div>
</div>
</article>
<p class="visually-hidden" role="status">
コンテンツを読み込んでいます。
</p>
8.2 共通のスケルトンクラスを作る
すべての仮要素に共通する背景色、角丸、位置指定、はみ出し制御を共通クラスへ定義します。そのうえで、画像、タイトル、本文などの寸法を個別クラスで設定します。
共通クラスを作ることで、色やアニメーション速度を一括変更できます。ページごとに同じコードを複製せず、再利用できる状態にしておくことが重要です。
共通CSSの例
.skeleton {
position: relative;
overflow: hidden;
background: var(--skeleton-base, #e5e7eb);
border-radius: var(--skeleton-radius, 8px);
}
.skeleton-image {
width: 100%;
aspect-ratio: 16 / 9;
}
.skeleton-title {
width: 72%;
height: 1.5rem;
margin-bottom: 1rem;
}
.skeleton-text {
width: 100%;
height: 0.875rem;
margin-bottom: 0.625rem;
}
.skeleton-text--short {
width: 58%;
}
8.3 疑似要素で光の帯を作る
疑似要素をスケルトン本体より外側から開始させ、背景グラデーションを設定します。中央部分だけを明るくし、左右を透明にすると、光の帯が通過する表現を作れます。
疑似要素を利用すれば、HTMLにアニメーション専用要素を追加する必要がありません。スケルトンクラスを付けるだけで共通のシマー表現を適用できます。
シマー部分のCSS例
.skeleton::after {
content: "";
position: absolute;
inset: 0;
transform: translateX(-100%);
background: linear-gradient(
90deg,
transparent,
var(--skeleton-highlight, rgba(255, 255, 255, 0.55)),
transparent
);
animation: skeleton-shimmer 1.4s infinite;
}
8.4 キーフレームで光を移動させる
キーフレームでは、疑似要素を左側から右側へ移動させます。変形処理を利用すると、位置情報を直接変更する方法よりも滑らかに描画されやすくなります。
移動距離が短いと光が途中で消え、長すぎると次の動きまで空白時間が生まれます。疑似要素の幅と移動開始位置を確認し、要素全体を通過する値を設定します。
キーフレームの例
@keyframes skeleton-shimmer {
100% {
transform: translateX(100%);
}
}
8.5 カードレイアウトへ適用する
スケルトンのカードは、実際のカードと同じ最大幅、余白、境界線、画像比率を使用します。完成後のカードと共通の外側コンポーネントを使うと、読み込み時の位置変化を抑えられます。
一覧表示では、画面幅に応じて列数を変更します。スケルトンだけ固定列にすると実際の一覧と異なるため、同じグリッド設定を利用します。
カード全体のCSS例
.skeleton-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 24px;
}
.skeleton-card {
overflow: hidden;
border: 1px solid #e5e7eb;
border-radius: 12px;
background: #ffffff;
}
.skeleton-card__body {
padding: 20px;
}
9. JavaScriptで表示状態を切り替える方法
CSSで見た目を作った後は、データ取得の開始、成功、失敗に応じてスケルトンを切り替えます。表示時間が短すぎる場合の点滅や、失敗時にシマーが残り続ける問題にも対応が必要です。
9.1 読み込み開始時にスケルトンを表示する
データ取得前にスケルトン要素を表示し、実コンテンツ領域を非表示または空の状態にします。通信開始後にスケルトンを追加すると、一瞬だけ空白が見える場合があるため、初期HTMLに含める方法も有効です。
サーバーから返される最初のHTMLにスケルトンを含めれば、JavaScriptの読み込み前でも仮レイアウトを表示できます。初期描画を早く見せたい場合に適した方法です。
初期表示の例
const skeleton = document.querySelector(".js-skeleton");
const content = document.querySelector(".js-content");
function showLoading() {
skeleton.hidden = false;
content.hidden = true;
}
9.2 取得成功時に実コンテンツへ置き換える
データ取得に成功したら、取得内容を画面へ描画した後でスケルトンを非表示にします。先にスケルトンを消すと、実コンテンツの描画まで一瞬空白になる可能性があります。
画像を含む場合は、画像の寸法を事前に確保するか、必要に応じて画像の準備状況も考慮します。ただし、すべての画像読み込みを待つと表示が遅くなるため、用途に応じて判断します。
データ取得の例
async function loadArticles() {
showLoading();
try {
const response = await fetch("/api/articles");
if (!response.ok) {
throw new Error("記事を取得できませんでした。");
}
const articles = await response.json();
renderArticles(articles);
skeleton.hidden = true;
content.hidden = false;
} catch (error) {
showError(error.message);
}
}
9.3 エラー時に再試行画面へ切り替える
通信に失敗した場合は、スケルトンを停止し、エラー内容と再試行方法を表示します。処理が失敗しているにもかかわらずシマーが動き続けると、利用者は待ち続けることになります。
技術的なエラーコードをそのまま表示するのではなく、「情報を取得できませんでした」「通信環境を確認して再度お試しください」など、次の行動が分かる文言を使います。
エラー処理の例
function showError(message) {
skeleton.hidden = true;
content.hidden = true;
const errorArea = document.querySelector(".js-error");
errorArea.hidden = false;
errorArea.querySelector(".js-error-message").textContent = message;
}
9.4 最小表示時間を設定する
データ取得が非常に速い場合、スケルトンが一瞬だけ表示されて点滅のように見えることがあります。最小表示時間を設けると、表示と非表示の切り替えを自然にできます。
ただし、取得が完了しているのに長時間スケルトンを残すと、実際の表示速度を意図的に遅くすることになります。最小時間は短めに設定し、実機で違和感がないか確認します。
最小表示時間を設ける例
const wait = (milliseconds) =>
new Promise((resolve) => setTimeout(resolve, milliseconds));
async function loadWithMinimumDuration() {
const minimumDuration = wait(300);
try {
const [response] = await Promise.all([
fetch("/api/articles"),
minimumDuration
]);
if (!response.ok) {
throw new Error("データの取得に失敗しました。");
}
const data = await response.json();
renderArticles(data);
} finally {
skeleton.hidden = true;
}
}
9.5 二重読み込みを防止する
再試行ボタンや絞り込み操作を連続して押せる状態では、複数の通信が同時に実行される可能性があります。古い通信結果が後から表示されると、画面内容が意図しない状態に戻ることがあります。
通信を中断する仕組みや、現在の要求を識別する番号を利用し、最新の結果だけを画面へ反映します。スケルトンの表示状態も、最後に開始した処理に合わせて管理します。
通信を中断する例
let controller;
async function reloadArticles() {
controller?.abort();
controller = new AbortController();
showLoading();
try {
const response = await fetch("/api/articles", {
signal: controller.signal
});
const data = await response.json();
renderArticles(data);
} catch (error) {
if (error.name !== "AbortError") {
showError("情報を取得できませんでした。");
}
} finally {
skeleton.hidden = true;
}
}
10. Reactを使ったスケルトンシマー実装
Reactでは、読み込み状態を表す値に応じて、スケルトンコンポーネントと実コンテンツを切り替えます。再利用可能な部品として設計すると、複数の画面で同じデザインと動作を利用できます。
10.1 スケルトンコンポーネントを作る
共通コンポーネントには、幅、高さ、角丸、追加クラスなどを渡せるようにします。用途ごとにHTMLを複製するよりも、共通部品を組み合わせるほうが変更しやすくなります。
ただし、自由度を高くしすぎると利用方法がばらつきます。代表的なカードや一覧については、専用のスケルトンコンポーネントも用意すると品質を保ちやすくなります。
共通コンポーネントの例
export function Skeleton({
width = "100%",
height = "1rem",
radius = "8px",
className = ""
}) {
return (
<span
className={`skeleton ${className}`}
style={{ width, height, borderRadius: radius }}
aria-hidden="true"
/>
);
}
10.2 カード専用スケルトンを作る
商品カードや記事カードは、画像、タイトル、説明など複数の要素で構成されます。実際のカードと同じ外側レイアウトを利用し、内部だけをスケルトンへ置き換える方法が有効です。
カード専用コンポーネントにすると、画面側では必要な件数を指定するだけで利用できます。デザイン変更時も、一つの部品を修正すれば複数画面へ反映できます。
カードスケルトンの例
export function ArticleCardSkeleton() {
return (
<article className="article-card" aria-hidden="true">
<Skeleton height="180px" radius="12px" />
<div className="article-card__body">
<Skeleton width="72%" height="24px" />
<Skeleton height="14px" />
<Skeleton width="60%" height="14px" />
</div>
</article>
);
}
10.3 読み込み状態に応じて切り替える
通信中はスケルトン、成功時は実コンテンツ、失敗時はエラー表示というように、状態ごとの描画を明確に分けます。単一の真偽値だけでは、初期状態と再取得状態を区別しにくい場合があります。
初回読み込みでは画面全体のスケルトンを表示し、再取得では既存コンテンツを残したまま一部だけ状態表示を行う方法もあります。利用者が現在見ている情報を突然消さないことが重要です。
状態切り替えの例
export function ArticleList({ articles, status, error }) {
if (status === "loading") {
return (
<div className="article-grid">
{Array.from({ length: 6 }).map((_, index) => (
<ArticleCardSkeleton key={index} />
))}
</div>
);
}
if (status === "error") {
return <p role="alert">{error}</p>;
}
return (
<div className="article-grid">
{articles.map((article) => (
<ArticleCard key={article.id} article={article} />
))}
</div>
);
}
10.4 読み込み件数を画面に合わせる
スケルトンの件数が少なすぎると、読み込み後にページが大きく伸びます。多すぎると、画面下部まで不要な仮要素が表示され、描画負荷も増えます。
最初の表示領域を満たす程度の件数を基準にし、画面幅に応じて列数や件数を調整します。無限スクロールでは、追加読み込み部分だけに小さなスケルトンを表示します。
10.5 一意の識別子を適切に扱う
スケルトン一覧を描画する際、配列番号を識別子として使うことがあります。仮要素は並び替えや更新が発生しにくいため、大きな問題にならない場合もあります。
一方で、実コンテンツと同じ配列内でスケルトンを混在させる場合は、重複しない識別子を用意します。不要な再描画や要素の誤再利用を防ぐため、状態とデータ構造を明確に分けます。
11. 画面幅と端末に合わせた設計
スケルトンシマーは、パソコンだけでなくスマートフォンやタブレットでも自然に表示される必要があります。実コンテンツと同じ応答型レイアウトを使い、画面幅による位置変化を抑えます。
11.1 スマートフォンでは情報量を減らす
スマートフォンでは表示領域が狭いため、細かなスケルトンを多数並べると画面が複雑に見えます。画像、タイトル、主要な本文行など、読み込み後の構造理解に必要な要素へ絞ります。
パソコン用のスケルトンをそのまま縮小すると、細い線や小さな図形が密集します。実際のスマートフォン画面と同じように、補助情報を省略したレイアウトを用意します。
11.2 画像の縦横比を維持する
画面幅に応じて画像幅が変わる場合でも、縦横比を指定しておけば高さを事前に確保できます。固定の高さだけを指定すると、画面幅によって画像の比率が実コンテンツと異なる可能性があります。
CSSの縦横比指定を利用し、商品画像、動画画像、記事画像などの比率に合わせます。実画像にも同じ比率を適用すると、読み込み前後の変動を抑えられます。
縦横比の指定例
.skeleton-thumbnail {
width: 100%;
aspect-ratio: 4 / 3;
}
.skeleton-video {
width: 100%;
aspect-ratio: 16 / 9;
}
.skeleton-avatar {
width: 48px;
aspect-ratio: 1;
border-radius: 50%;
}
11.3 画面幅に応じて列数を変更する
一覧画面では、パソコンで4列、タブレットで2列、スマートフォンで1列といった変化が一般的です。スケルトンにも実コンテンツと同じグリッド設定を適用します。
別々のグリッドを定義すると、片方だけ変更された際に表示差が生じます。カードの外側レイアウトを共通化し、内部コンテンツだけを切り替える設計が適しています。
応答型グリッドの例
.content-grid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 24px;
}
@media (max-width: 960px) {
.content-grid {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
@media (max-width: 640px) {
.content-grid {
grid-template-columns: 1fr;
gap: 16px;
}
}
11.4 低性能端末への負荷を抑える
多数の疑似要素やグラデーションを同時に動かすと、低性能端末で動きが途切れる場合があります。画面外の要素までアニメーションさせず、最初に見える範囲へ件数を制限します。
必要に応じて、小さな画面では静止型へ切り替える方法もあります。アニメーションを表示することより、スクロールや操作を滑らかに保つことを優先します。
11.5 画面回転時の変化を確認する
スマートフォンやタブレットでは、縦向きから横向きへ回転した際に列数やカード幅が変わります。スケルトン表示中に回転すると、寸法再計算によってレイアウトが大きく動く可能性があります。
縦横比と応答型グリッドを適切に設定し、固定値への依存を減らします。実データ取得中、取得直後、エラー表示中など、複数の状態で回転テストを行います。
12. アクセシビリティへの対応
スケルトンシマーは視覚的なローディング表現であり、画面読み上げ機能だけでは状態が伝わらない場合があります。また、継続的な動きが負担になる利用者への配慮も必要です。
12.1 読み込み状態を文章でも伝える
スケルトン自体は内容を持たないため、画面読み上げ機能には「コンテンツを読み込んでいます」といった状態文を提供します。見た目だけで処理状況を伝えないことが重要です。
状態文は何度も読み上げられないようにし、読み込み開始と完了の通知量を調整します。短時間の通信ごとに通知すると、操作の妨げになる可能性があります。
12.2 スケルトン要素を読み上げ対象から外す
画像やテキストを模したスケルトン要素が読み上げられる必要はありません。装飾用の領域として扱い、支援技術から隠します。
ただし、親要素全体を隠した結果、必要な状態文まで読まれなくならないように注意します。スケルトンと状態文を別の要素として設置すると管理しやすくなります。
読み上げ対応例
<section aria-busy="true" aria-describedby="loading-message">
<div class="skeleton-list" aria-hidden="true">
<!-- スケルトンカード -->
</div>
<p id="loading-message" class="visually-hidden" role="status">
記事一覧を読み込んでいます。
</p>
</section>
12.3 動きを減らす設定へ対応する
端末やブラウザには、アニメーションを減らす設定が用意されています。利用者が動きを減らす設定を選択している場合は、シマーを停止し、静止型スケルトンへ切り替えます。
完全に非表示にすると読み込み状態が分かりにくくなるため、背景色と形は残し、光の移動だけを停止する方法が適しています。
動きを減らすCSS例
@media (prefers-reduced-motion: reduce) {
.skeleton::after {
animation: none;
}
}
12.4 色だけに依存しない
読み込み状態を背景色の変化だけで伝えると、色の違いを認識しにくい利用者には伝わらない可能性があります。シマーの動き、状態文、領域の形を組み合わせて状態を表現します。
明るい帯と本体色の差を強くしすぎる必要はありません。スケルトンは情報を読む要素ではなく、構造を示す補助要素であるため、視認性と刺激の少なさを両立させます。
12.5 操作可能な要素と誤解させない
ボタンや入力欄に似たスケルトンを表示すると、利用者が操作できる要素だと誤解することがあります。読み込み中の仮要素には、ホバー効果や押下効果を付けないようにします。
実際のボタンが読み込み中で利用できない場合は、無効状態とその理由を明確にします。単にボタンをスケルトンへ置き換えるだけでなく、操作状態を適切に管理します。
13. 表示性能を悪化させない実装
スケルトンシマーは体感速度を高めるための表現ですが、実装方法によっては描画負荷を増やし、実際の操作を遅くする可能性があります。要素数、アニメーション方法、表示範囲を制御することが重要です。
13.1 変形処理を使って移動させる
アニメーションでは、位置を表す値を直接変更するよりも、変形処理を利用する方法が一般的です。描画処理を抑えやすく、滑らかな移動を実現しやすくなります。
ただし、変形処理を利用すれば必ず軽くなるわけではありません。画面全体に多数の大きなレイヤーを作ると、メモリ使用量が増える可能性があります。実際の端末で計測することが必要です。
13.2 表示件数を必要最小限にする
一覧に100件のデータが入る場合でも、100件分のスケルトンを最初から表示する必要はありません。最初の画面を満たす件数と、少し下までスクロールした範囲に限定します。
データ取得後にすぐ実コンテンツへ置き換わる要素へ大量の描画処理を使うと、読み込み完了が遅れる可能性があります。利用者が実際に見る範囲を基準に件数を決めます。
13.3 画面外のアニメーションを停止する
長い一覧では、画面外へスクロールしたスケルトンまで動き続ける可能性があります。表示領域の監視機能などを使い、見えている要素だけを動かす方法を検討します。
ただし、監視処理を複雑にしすぎると、実装と保守の負担が増えます。最初からスケルトン件数を少なくするだけで十分な場合もあるため、画面規模に応じて選択します。
13.4 不要な再描画を減らす
状態が変わるたびにスケルトンコンポーネント全体を作り直すと、不要な描画が発生します。読み込み状態、表示件数、寸法などの値が頻繁に変更されない設計にします。
Reactなどの環境では、親コンポーネントの状態更新によってスケルトン一覧も再描画される場合があります。性能計測を行い、必要な場合に限って再描画を抑える仕組みを利用します。
13.5 実際のデータ取得を優先して改善する
スケルトンシマーは待ち時間を短く感じさせますが、通信や処理そのものを高速化するものではありません。応答データの削減、画像最適化、キャッシュ、事前取得などの改善を同時に行います。
読み込みが5秒以上続く問題をシマーだけで隠す設計は適切ではありません。まず原因を計測し、実時間を短縮したうえで、残る待ち時間をスケルトンで補います。
| 改善対象 | 主な対策 |
|---|---|
| API応答 | 不要項目の削減、キャッシュ |
| 画像 | 適切な形式、寸法、遅延読み込み |
| JavaScript | 分割、不要処理の削除 |
| データベース | 問い合わせの改善 |
| 初期描画 | サーバー側描画、事前生成 |
14. スケルトンシマーの効果を測定する方法
導入後は、見た目の印象だけで成功を判断せず、利用者行動や表示性能の変化を確認します。スケルトンを表示したことで操作が早まったのか、離脱が減ったのかを検証する必要があります。
14.1 離脱率を比較する
検索結果、商品一覧、記事一覧など、スケルトンを導入したページの離脱率を確認します。導入前後で比較する場合は、流入経路、端末、通信環境、期間の違いを考慮します。
離脱率が改善しても、季節要因や広告施策など別の要因が影響している可能性があります。可能であれば、同じ期間に表示方法を分けて比較する試験を行います。
14.2 最初の操作までの時間を測る
ページ表示から最初のクリック、スクロール、入力までの時間を計測すると、利用者がどの時点で画面を理解し、操作を始めたかを確認できます。スケルトンによって視線誘導が改善されれば、操作開始が早まる可能性があります。
ただし、読み込み中に操作できない要素をクリックさせる設計は避けます。操作可能な領域と仮表示領域を明確に分け、誤操作の件数も併せて確認します。
14.3 実際の表示時間を測る
スケルトンの表示開始から実コンテンツへ切り替わるまでの時間を記録します。平均値だけでなく、中央値や遅い利用者の値も確認すると、通信環境による差を把握できます。
表示時間が短すぎる場合は、スケルトンを表示しない遅延設定を検討できます。長すぎる場合は、通信や処理の改善が必要であり、表示表現だけで対応しないことが重要です。
14.4 利用者の主観評価を確認する
数値指標だけでは、待ち時間がどのように感じられたかを完全には把握できません。利用者テストやアンケートを通じて、「読み込みが速く感じたか」「画面が停止したように見えなかったか」を確認します。
シマーの動きが気になる、何が読み込まれているのか分からない、実際の内容と形が違うといった意見が出る場合があります。数値と主観評価の両方を使って改善します。
14.5 比較試験で表示方法を検証する
スケルトンシマー、静止型スケルトン、スピナーなどを分けて表示し、行動指標を比較します。対象ページや処理時間によって適した方法が異なるため、他サービスの事例だけで決めないことが重要です。
試験では、クリック率だけでなく、離脱率、誤操作、再読み込み、エラー率、表示性能も確認します。短期的な反応だけでなく、継続利用への影響も見ます。
| 測定項目 | 確認できる内容 |
|---|---|
| 離脱率 | 待ち時間中の離脱変化 |
| 最初の操作時間 | 画面理解と操作開始の早さ |
| 再読み込み率 | 表示失敗と誤解された可能性 |
| エラー率 | 実装による不具合 |
| 主観評価 | 体感速度や見やすさ |
| 描画時間 | 端末への負荷 |
15. 導入時によくある失敗と改善方法
スケルトンシマーは比較的導入しやすい表現ですが、実コンテンツとの不一致や長時間表示によって、かえってUXを低下させる場合があります。実装前に失敗例を把握しておくことが重要です。
15.1 実コンテンツと形が異なる
スケルトンでは大きな画像を表示しているのに、読み込み後には画像が存在しない場合、利用者は画面が突然縮んだように感じます。タイトル行数やカード高さが大きく異なる場合も、位置移動が発生します。
代表的なデータだけでなく、文字数が短い場合、長い場合、画像がない場合など、複数のデータ状態で確認します。完全一致が難しい場合でも、大きな領域の寸法は合わせます。
15.2 短い処理でも必ず表示する
100ミリ秒程度で終わる処理にスケルトンを表示すると、一瞬だけ灰色の画面が現れ、ちらつきとして認識されることがあります。体感速度を改善するどころか、画面が不安定に見える可能性があります。
一定時間以内に処理が完了した場合はスケルトンを表示しない遅延設定が有効です。読み込みが長引いたときだけ表示し、表示後は短い最小時間を確保する方法もあります。
遅延表示の例
let loadingTimer;
function startDelayedSkeleton() {
loadingTimer = window.setTimeout(() => {
skeleton.hidden = false;
}, 150);
}
function stopDelayedSkeleton() {
window.clearTimeout(loadingTimer);
skeleton.hidden = true;
}
15.3 エラー後もアニメーションを続ける
通信が失敗しているのにシマーが動き続けると、利用者は処理が完了するまで待ち続けます。時間が経っても情報が表示されず、最終的に画面を閉じる可能性があります。
エラーを検出した時点でスケルトンを終了し、再試行、前の画面へ戻る、問い合わせるなどの行動を提示します。自動再試行を行う場合も、現在の状態を文章で伝えます。
15.4 アニメーションを強くしすぎる
明度差が大きい光を高速で動かすと、スケルトンが主役のように目立ちます。カード数が多い画面では、複数の光が同時に動いて視覚的な負担が増えます。
光の色を本体色へ近づけ、速度を落ち着かせ、同時表示件数を制限します。動きを減らす設定にも対応し、静止型でも読み込み状態が分かるデザインにします。
15.5 スケルトンだけで速度問題を解決しようとする
スケルトンを導入すると、読み込みが速くなったように見えることがあります。しかし、実際のデータ取得が遅ければ、利用者は長時間仮表示を見ることになり、最終的には不満を感じます。
スケルトンは性能改善を補助する手段です。通信、画像、JavaScript、サーバー処理を計測し、実際の読み込み時間を短縮します。そのうえで、避けられない短い待ち時間に対して利用します。
| 失敗例 | 主な問題 | 改善方法 |
|---|---|---|
| 実画面と形が違う | 大きな位置移動 | 共通レイアウトを使う |
| 常に表示する | ちらつき | 遅延表示を設定する |
| エラー後も継続 | 待ち続けさせる | 再試行画面へ切り替える |
| 動きが強い | 視覚的な負担 | 明度差と速度を抑える |
| 大量に表示する | 描画負荷 | 件数を限定する |
| 速度改善を行わない | 待ち時間が残る | 通信と処理を最適化する |
おわりに
スケルトンシマーは、読み込み後のコンテンツ構造を仮の図形で示し、光が流れるアニメーションによって処理中であることを伝える表示方法です。空白画面やスピナーだけの表示と比べて、これから表示される情報の位置を予測しやすく、体感的な待ち時間を軽減できる可能性があります。
効果を高めるには、実コンテンツと近い寸法を使い、読み込み後の位置移動を抑えることが重要です。また、アニメーション速度、光の明度、表示件数を調整し、低性能端末や動きを減らす設定にも対応する必要があります。エラー発生時や長時間読み込み時には、シマーを継続するのではなく、状態説明と次の操作を提示します。
スケルトンシマーは、通信時間そのものを短縮する技術ではありません。API応答、画像、JavaScript、サーバー処理などを改善したうえで、残る待ち時間の体験を補う手段として活用することが大切です。導入後は離脱率、最初の操作までの時間、再読み込み率、表示性能、利用者の主観評価を確認し、対象画面に適した表現へ継続的に改善していきましょう。
EN
JP
KR