画面の端(主に左右や下部)からスライドインして表示されるパネル。ダイアログ(モーダル)の一種だが、画面中央を完全に塞ぐDialogと異なり、親画面の文脈(横や一部)を視界に残しながら詳細情報やナビゲーションを提供するコンポーネント。
この記事を読むと、Dialogとの明確な使い分け、スマートフォンでのBottom Sheet活用、A11yとしてのフォーカストラップ設計が自分でできるようになります。
1. UI例(Preview / Live)
実装で見る(GunjoUI)
この部品を、デザインシステム GUNJO の実装で確かめられます。
2. 定義(Definition)
画面の端(Left, Right, Bottom, Top)からアニメーションと共に滑り出してくる、画面全体へのオーバーレイ領域を利用したダイアログ。本質的にはDialog(モーダル)と同じ機能を持つ。
Dialog / Modalとの違い:中央に浮かぶDialogに対し、Sheet(Drawer)は画面の端を占有し、親画面(Main Content)を背後に視覚的に一部残す。これによりコンテキスト(自分が今どこで何をしているか)の喪失を防ぐ 효과を持ち、縦に長いコンテンツも無理なく表示できる。
3. 使い分け(When to use / When NOT to use)
3.1 When to use
- スマートフォン等の狭い画面で、メニュー(ハンバーガーメニューから展開)やフィルタ検索を表示したいとき
- デスクトップで、親画面のリスト(表など)を参照しながら、特定のアイテムの詳細情報や編集フォームを横並び感覚で扱いたいとき
- Dialog(中央モーダル)に収めきれないほど、入力項目や縦長の内容が多い設定画面
3.2 When NOT to use
- 単純な「はい/いいえ」の確認や、ごく短いフォーム(中央のDialogを使うべき)
- 画面遷移すれば済む内容(独立したURLを持たせるべき独立した画面・ページ。※URLでSheet状態を管理できるならOK)
3.3 代替UI(Alternatives)
- 破壊的操作の警告 →
AlertDialog - 短い確認・入力 →
Dialog - デスクトップのメニューツリー →
Sidebar (固定)
4. 設計判断の核(Decision Principles)
「親の文脈(リスト)と、子の詳細(Sheet)」の関係性を最大限に活かす。
判断の優先順位:① 画面幅(SPは下、PCは右) → ② 情報量(スクロール可能な領域) → ③ 閉じる手段(Swipe/Click/Esc)
- PCの場合、左は「グローバルメニュー」、右は「詳細・ヘルプ・フィルタ」として使うのが現代のデファクトスタンダード。
- Central Dialog(中央ダイアログ)と異なり、上から下まで大きく使えるため「スクロールへの耐性」が極めて高い。
5. 状態設計(States)
5.1 必須状態(Required)
- Default:画面端から登場し、背面に暗いオーバーレイ(Scrim)を敷いて前面のSheet操作を強制している状態
- Focus Trap:Dialogと同じく、Tabキー操作がSheet内だけでループしている状態
5.2 条件付き状態(Conditional)
- Scroll:コンテンツ超過時、ヘッダーとフッター(保存ボタン等)を固定し、中間領域のみがスクロールする状態
- Swipe to Dismiss / Drag:(特にモバイルのBottom Sheetにおいて)下へのスワイプやドラッグで直感的に閉じられる状態
5.3 State Gallery
| 状態 | 必須 | 何を伝えるか |
|---|---|---|
| Default | ✅ | 後ろの画面がロックされ、端に出現したパネルだけが操作可能であること |
| Focus Trap | ✅ | キーボードとスクリーンリーダーの焦点を強制的にシートへ合わせる |
| Scroll | — | 長い設定やフォームを扱うため、絶対にボタンを見失わせない |
| Swipe / Drag to Dismiss | — | (モバイル用途)指の自然な動きで素早く元の画面へ戻れる快適さ |
6. バリエーション設計(Variants)
出現する「方向(Side)」によって役割が明確に異なる。
| バリアント | 目的と位置 |
|---|---|
| Side Left | 主にナビゲーション(ハンバーガーメニュー等)。サイト全体の移動用 |
| Side Right | 主に詳細情報(Inspector)、設定パネル、フィルタ、チャット。その画面内の操作用 |
| Bottom | モバイル特化。画面下部から登場するメニューやアクションシート。親指で届く |
| Top | 限定的。検索バーやグローバルな通知バーとして上から落ちてくる |
ルール:デスクトップで「左」から詳細(Inspector)を出したり、逆に「右」からグローバルメニューを出したりしてユーザーのメンタルモデルを破壊しない。
7. パターン集(Good / Bad / How to fix)
7.0 よく崩れる設計パターン(3つ)
- 閉じ方不明:「✖️ボタン」がなく、背景クリックで閉じる仕様を知らないPCユーザーが設定から抜け出せなくなる
- スクロール崩壊:Sheetの中で
overflow-autoを適切に設定しておらず、保存ボタンがはるか画面外へ消えて押せなくなる - A11y非対応:Focus Trapが設定されておらず、Tab移動していくと見えない背後の画面のリンクにフォーカスが飛ぶ
7.1 Bad(典型3つ)
- スマートフォンの画面で、中央のDialog(モーダル)の中に長大な入力フォームが詰め込まれ、見切れてスクロールも重い(Bottom Sheetを使うべき)
- デスクトップの右から出たSheetの最下部に「保存ボタン」があるが、ヘッダー固定されていないため延々と下までスクロールしないと押せない
- 開いた瞬間、フォーカスが裏の親画面のままになっておりスクリーンリーダーがSheetの存在に気付けない
7.2 Good(対になる3つ)
- スマートフォンの複雑なフィルタ検索やメニューは、親指で届く Bottom Sheet に集約している
- 長いフォームを持つSheetは、上部に「タイトルと✖️閉じるボタン」、下部に「保存ボタン群」をSticky固定し、安全にスクロールできる
- 実装としては
role="dialog"とaria-modal="true"が付与され、開いた瞬間に最初の入力要素へフォーカスが自動移動する
7.3 How to fix(手順)
- 中身の情報量が多く、中央のDialogでは狭い場合はSheet(PC=Right, SP=Bottom)に切り替える
- モバイルのBottom Sheetを実装する場合、最上部中央に横棒(Drag Handle / Notch)を置いてスワイプで閉じられることを示唆する
- ヘッダーとフッターを
flex-noneまたはstickyで固定し、中間のコンテンツエリアだけをflex-1 overflow-y-autoに設定する - Tabキー移動にFocusTrap処理を追加し、Escキーでも確実に閉じられるようにする
8. ルール(Must / Better)
Must(守らないと壊れる)
Better(品質が跳ねる)
9. アクセシビリティ要件(必須)
Keyboard
EscキーでSheetを閉じることができる- フォーカストラップ:
Tabキー移動がSheet内のみでループし、裏側のページには移動しない
Focus
- Sheetが開いた瞬間、内部の最初のインタラクティブ要素(例えば閉じるボタンや最初の入力欄)に自動でフォーカスを移す
- 閉じた後は、Sheetを開くトリガーとなった元のボタンへフォーカスを確実に戻す
Screen Reader
- Sheetは本質的にダイアログであるため、コンテナに
role="dialog"を付与する aria-labelledby(タイトル用)とaria-describedby(説明文用が必要なら)を使用して内容を読み上げさせるaria-modal="true"を指定し、これがモーダルであることを明示する
Touch / Pointer
- (任意・推奨)オーバーレイ(暗転)部分をタップした際にSheetを閉じる挙動(Dismiss)をサポートする(※未保存フォームがある場合を除く)
- モバイルの Bottom Sheet では、ドラッグハンドラーを提供しスワイプで閉じられるようにする
10. 実装メモ(Implementation Notes)
radix-uiなどのライブラリにおけるDialogコンポーネントを用い、CSSアニメーション(Tailwind ならslide-in-from-[方向]と位置指定inset-y-0 right-0等)を変更するだけでセマンティックで安全なSheetを自作できる- モバイル特有のネイティブライクな動き(指に吸い付くドラッグ、速度計算によるクローズ等)を実現するには
vaulのような Bottom Sheet 専用の高度なライブラリに頼るのがベストプラクティス position: fixedで画面の中央から端まで覆ったとき、iOS Safari固有の下部メニューバー(Safe Area)による高さ100vhのバグに注意し、サポートブラウザに合わせてdvh(Dynamic Viewport Height) などを利用する
11. 関連リンク
- 関連するUIデザイン原則: フィードバック (Feedback), コンポーネントの視覚一貫性 (Component Consistency)
- 用語集(定義): アクセシビリティ (Accessibility), フォーカストラップ (Focus Trap)
- 関連するUIコンポーネント(横): Dialog(ダイアログ / モーダル), AlertDialog(警告ダイアログ)
12. まとめ
Sheet / Drawerは、情報量が爆発しがちな現代のWebアプリケーションや、画面が狭いモバイル環境において「親の文脈を残しながら大量の情報をさばく」ための強力な武器です。ただし、内部的には完全にDialog(モーダル)と同じ力学・注意点(FocusTrapなど)を持つため、外見の違いに騙されずA11yの基本設計を確実に行うことが重要です。