カード→詳細のモーフ
一覧のカードを押すと、その位置と大きさを計測して枠いっぱいの詳細へ拡大する(FLIP)。閉じると同じ経路で元のカードへ戻るので、どこから来たかを見失わない。
プレビュー
クリック
操作クリック/タップで動きます。
仕様書
- 向く場面
- 一覧のカードをその場で詳細に広げる
- モーダルの代わりに「どこから来たか」を保ちたい
- 事例・作品一覧の詳細表示
- 避ける場面
- 詳細が長文でスクロールが要る内容
- 枠外へ遷移するページ移動
- 構成要素
- カード(サムネと名前)
- 拡大したカード
- 詳細の見出しと本文
- 閉じるボタン
- 持っている状態
- 通常
- フォーカス
- キーボード
Tab でカードへ、Enter/Space で拡大(フォーカスは「閉じる」へ)。Esc か「閉じる」で戻り、フォーカスは元のカードへ返る
- 支援技術
カードは button、閉じるは aria-label。拡大中は他のカードを inert にして Tab が背後へ抜けない。詳細は aria-live=polite で本文を通知。reduced-motion で 0ms
- 動き
拡大 400ms・縮小 300ms、ease-out(.16,1,.3,1)、origin 左上で translate+scale を同時補間。本文は拡大後に 250ms フェード
原則認知負荷
デザインの要点
- 拡大は「新しい画面を出す」のでなく「同じ要素が大きくなる」。位置の連続性が、戻る場所の記憶になる
- transform-origin を左上に固定し、translate と scale を同時に補間する。中心基準だと途中で位置がずれて見える
- 拡大 400ms に対して縮小は 300ms。行きは見せ場、帰りは片付けなので短くする
- 詳細の本文は拡大が終わってからフェードで出す。拡大中に文字が引き伸ばされるのを見せない
コード(コピーして使えます)
<div class="lm-stage" id="lmStage">
<button class="lm-close" id="lmClose" type="button" aria-label="閉じる">×</button>
<div class="lm-grid">
<button class="lm-card" type="button" style="--lm-c:#2b50c7" data-title="予約管理" data-body="店舗の予約台帳をクラウド化。空き枠の自動提案で、電話対応が月 40 時間減りました。">
<span class="lm-thumb"></span><span class="lm-name">予約管理</span>
</button>
<button class="lm-card" type="button" style="--lm-c:#c7692b" data-title="在庫アラート" data-body="発注点を下回った品目だけを毎朝通知。欠品による機会損失を四半期で 12% 減らしました。">
<span class="lm-thumb"></span><span class="lm-name">在庫アラート</span>
</button>
<button class="lm-card" type="button" style="--lm-c:#2b8a5c" data-title="請求書の自動化" data-body="納品データから請求書を生成し、期日にメール送付。手作業の転記ミスがゼロになりました。">
<span class="lm-thumb"></span><span class="lm-name">請求書の自動化</span>
</button>
<button class="lm-card" type="button" style="--lm-c:#8a2b6e" data-title="シフト調整" data-body="希望シフトの収集から確定までをアプリ内で完結。店長の調整時間が週 5 時間から 1 時間に。">
<span class="lm-thumb"></span><span class="lm-name">シフト調整</span>
</button>
</div>
<div class="lm-detail" id="lmDetail" aria-live="polite">
<h3 class="lm-title" id="lmTitle"></h3>
<p class="lm-body" id="lmBody"></p>
</div>
</div>