ui
Bottom sheet / Half modal / Swipe-down sheet
01Demo触って、数値を決める
開く・閉じる・引き下ろしが届かず戻る、の3つに共通の時間。観察元は0.3s。0.25〜0.35sが軽快で、0.5sを超えると「選ぶ前に待たされる」部品になる。
グラバーを引き下ろして離したとき、この距離を越えていれば閉じる。観察元は80px。40px以下はリストを触ろうとしただけで誤って閉じ、シートの高さの半分を超えると「引いても閉じない」と感じられる。
画面の高さに対するシートの高さ。観察元は min-height 70dvh(上限85dvh)。50%前後なら背後の画面が読めるハーフモーダル、85%を超えると全画面のモーダルと区別が付かなくなる。
背後に敷く黒幕の不透明度。観察元は rgba(0,0,0,0.4)。0.3〜0.5で「背後はまだ在るが今は触れない」が伝わる。0にすると背後を押して閉じられることが分からない。
02Prompt数値はスライダーと連動
03 Vocab この動きを構成する語彙
ボトムシート(bottom sheet) — 画面の下端からせり上がるパネル。Material Design の呼び名で、iOS では sheet、日本の現場ではハーフモーダルとも呼ぶ。背後の画面を残したまま追加の選択肢を出す。
グラバー(grabber / drag handle) — シート上端に置く、幅40px前後の短い横棒。「ここを掴んで引ける」ことを示す取っ手で、ドラッグの受け口もここに絞る。
dismiss threshold — 引き下ろして離したとき、閉じるか戻るかを分ける距離。px 固定(80px前後)か、シートの高さの割合で決める。
スクリム(scrim) — モーダルの背後に敷く半透明の黒幕。背後がまだ在ることを見せつつ、今は操作できないことを伝える。押すと閉じるのが作法。
デテント(detent) — シートが止まれる高さの段。iOS の medium / large のように半分と全体の2段を持たせる型もある。この項目は1段(開くか閉じるか)の基本形。
04 NG → OK 伝え方の差分
NG
言い方: 「スマホで下から出てくるメニューを作って。スワイプで閉じられるように」
なぜNG: 下から出るだけのモーダルに、指を離したあとで判定する swipe イベント(上下どちらかへ動いたら即閉じる)が付いた実装が返ってきやすい。引いている間にシートが指に付いてこないので掴んだ手応えが無く、少し触っただけで閉じる誤爆も起きる。高さの指定が無いと全画面で出てきて、背後の画面を残す意味も消える。
OK
言い方: 「bottom sheetを。高さ70%、translateY(100%)→0を0.3s cubic-bezier(0.12,0.67,0.53,1)で上げ、黒幕0.4を同じ時間で連動。グラバーをpointerdownしたらtransitionを切ってtranslateY(max(0,dy))で指に追従、離して80pxを越えていれば閉じ、越えていなければ0へ戻す。reduced-motionでは即時」
なぜOK: 「指に付いてくる区間」と「離した瞬間の距離判定」を分けて数値で書いているので、掴んで引き下ろす手応えと、届かなければ戻る返事の両方が出る。dy を max(0, …) で下向きだけに絞っているので、上へ引いて画面から浮く崩れも起きない。
