スケルトン→本文クロスフェード
スケルトンと本文を同じグリッドセルに重ねて置き、読み込み完了で不透明度だけを入れ替える。要素の差し替えをしないのでレイアウトシフトが起きない。
プレビュー
クリック
操作クリック/タップで動きます。
仕様書
- 向く場面
- カード・記事の読み込み待ちでレイアウトを揺らさない
- 本文の行数・画像比率が事前に分かる一覧
- 300ms 以上かかる非同期取得
- 避ける場面
- 300ms 未満で終わる読み込み(一瞬の骨組み)
- 本文の高さが予測できない可変コンテンツ
- 構成要素
- スケルトン層
- 本文層
- シマー
- 再読み込みボタン
- 持っている状態
- 通常
- フォーカス
- 無効
- 読み込み中
- キーボード
Tab で「再読み込み」へ、Enter/Space で読み込み状態を 1.4 秒再現。読み込み中はボタンが無効
- 支援技術
カードに aria-busy=true/false、スケルトン層は aria-hidden。本文は常に DOM にあり読み上げ順が変わらない。reduced-motion でシマーとフェード無し
- 動き
同じ grid セルに重ねた2層の opacity を 250ms ease で入れ替える(差し替え無し)。骨組みのシマーは 1.2s 無限ループ
目的待たせる
デザインの要点
- スケルトンと本文を grid-area: 1 / 1 で重ねる。display の切替は高さが一瞬 0 になり、下の要素が跳ねる
- 本文の行数・画像の比率をスケルトンと揃える。骨組みと実物の高さが違うと、フェードの最中にずれが見える
- フェードは 250ms。長くすると「まだ読み込み中」に見え、短すぎると点滅に見える
- 読み込みが 300ms 未満で終わるならスケルトンを出さない。一瞬だけ出る骨組みは、遅く感じさせる
コード(コピーして使えます)
<div class="sk2-wrap">
<article class="sk2-card" id="sk2Card" aria-busy="false">
<div class="sk2-layer sk2-skel" aria-hidden="true">
<div class="sk2-b sk2-b-img"></div>
<div class="sk2-b sk2-b-line" style="width:70%"></div>
<div class="sk2-b sk2-b-line" style="width:95%"></div>
<div class="sk2-b sk2-b-line" style="width:60%"></div>
<div class="sk2-b sk2-b-line" style="width:45%"></div>
<div class="sk2-b sk2-b-btn"></div>
</div>
<div class="sk2-layer sk2-real">
<div class="sk2-img"></div>
<h3 class="sk2-title">春の新作テーブル、受注開始</h3>
<p class="sk2-text">ナラ材の一枚板を使った 4 人掛け。脚の位置を 2 段階で選べます。</p>
<p class="sk2-meta">¥168,000 ・ 納期 6 週間</p>
<span class="sk2-cta">詳細を見る</span>
</div>
</article>
<button class="sk2-btn" id="sk2Reload" type="button">再読み込み</button>
</div>