FLIP で並び替え
「シャッフル」「数値順」で DOM の順序を入れ替えても、各行が元の位置から新しい位置へ滑らかに移動する。First / Last / Invert / Play の4手順を JS で実装。
プレビュー
クリック
操作クリック/タップで動きます。
仕様書
- 向く場面
- 並び替え・ソートで行の移動先を追わせたい一覧
- ランキングの順位変動を見せる画面
- フィルタで残った項目の位置移動
- 避ける場面
- 数百行の一覧(全行の矩形計測が重い)
- 毎秒更新されるライブデータの表
- 構成要素
- シャッフル/数値順ボタン
- 一覧の行
- 色の点
- 名前
- 数値
- 持っている状態
- 通常
- フォーカス
- キーボード
Tab で「シャッフル」「数値順」へ、Enter/Space で並び替える
- 支援技術
ul/li の DOM 順=表示順なので読み上げ順も並び替え後に一致。並び替え結果は aria-live=polite の文(「数値順に並び替えました」等)で通知。reduced-motion では即時入替
- 動き
各行 translateY 350ms ease-out(.16,1,.3,1)。DOM を先に変えて差分だけ巻き戻す FLIP で、位置の連続性を保つ
デザインの要点
- FLIP は「先に DOM を変えて最終位置を確定させ、差分だけ transform で巻き戻して再生」する。レイアウトを触るのは1回で済む
- アニメーションは transform と opacity だけに絞る。top/left や height を動かすと毎フレーム再レイアウトが走る
- 移動距離が長い行ほど時間を伸ばさず、同じ 350ms で揃える。速度差が「一斉に入れ替わった」感を作る
- 新しく入る行は fade+rise、消える行は fade だけ。出入りは移動より短く(200ms)して主役を移動に譲る
コード(コピーして使えます)
<div class="fl-wrap">
<div class="fl-bar">
<button class="fl-btn" id="flShuffle" type="button">シャッフル</button>
<button class="fl-btn" id="flSort" type="button">数値順</button>
</div>
<ul class="fl-list" id="flList">
<li class="fl-item" data-v="1284"><span class="fl-dot" style="--c:#2b50c7"></span><span class="fl-name">ミナト工房</span><span class="fl-val">1,284</span></li>
<li class="fl-item" data-v="962"><span class="fl-dot" style="--c:#c7692b"></span><span class="fl-name">Aoi Analytics</span><span class="fl-val">962</span></li>
<li class="fl-item" data-v="2410"><span class="fl-dot" style="--c:#2b8a5c"></span><span class="fl-name">はるか商店</span><span class="fl-val">2,410</span></li>
<li class="fl-item" data-v="533"><span class="fl-dot" style="--c:#8a2b6e"></span><span class="fl-name">ナギ設計</span><span class="fl-val">533</span></li>
<li class="fl-item" data-v="1790"><span class="fl-dot" style="--c:#6b655c"></span><span class="fl-name">ソラ物流</span><span class="fl-val">1,790</span></li>
</ul>
<p class="fl-read" id="flRead" aria-live="polite"></p>
</div>