表示例
共有する
リンクをコピー
メールで送る
別名・英語表記
- 下から出るパネル
- シート
- アクションシート(iOS)
- スワイプシート
- ハーフモーダル
- セミモーダル
- 半モーダル
- Action sheet
- Bottom sheet
実装例
<div class="x-bottom-sheet">
<div class="x-bottom-sheet__stage">
<div class="x-bottom-sheet__sheet">
<span class="x-bottom-sheet__grip" aria-hidden="true"></span>
<p class="x-bottom-sheet__t">共有する</p>
<p class="x-bottom-sheet__i">リンクをコピー</p>
<p class="x-bottom-sheet__i">メールで送る</p>
</div>
</div>
</div>
/* 貼った先のリセットに頼らないよう、この部品の中だけ border-box にする */
.x-bottom-sheet,
.x-bottom-sheet *:not([class*="fa-"]),
.x-bottom-sheet *:not([class*="fa-"])::before,
.x-bottom-sheet *:not([class*="fa-"])::after {
box-sizing: border-box;
/* 貼った先の既定の書体に引きずられないようにする。書体が変わると
文字の幅と高さが変わり、枠のサイズまでずれる */
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Hiragino Sans", "Noto Sans JP", "Yu Gothic UI", Meiryo, sans-serif;
}
.x-bottom-sheet__stage {
position: relative;
width: 210px;
height: 130px;
border: 1px solid #e3e6ea;
border-radius: 10px;
background: #f1f3f6;
overflow: hidden;
}
.x-bottom-sheet__sheet {
position: absolute;
inset: auto 0 0 0;
padding: 8px 14px 12px;
border-radius: 12px 12px 0 0;
border-top: 1px solid #e3e6ea;
background: #fff;
}
.x-bottom-sheet__grip {
display: block;
width: 36px;
height: 4px;
margin: 0 auto 8px;
border-radius: 999px;
background: #cfd4dc;
}
.x-bottom-sheet__t {
margin: 0 0 6px;
font-size: 11px;
font-weight: 700;
color: #606a7b;
}
.x-bottom-sheet__i {
margin: 0;
padding: 5px 0;
font-size: 12px;
}
AIへの指示文
「ボトムシート(Bottom sheet)」を実装してください。
## これは何か
画面の下から上がってくるパネル。スマートフォンで、親指の届く位置に選択肢を出したいときに使う。
## 使いどころ
- 共有先の選択など、選択肢が数個あるとき
- 地図や一覧の上に、詳細を重ねて出したいとき
## 実装の要件
- dialog 要素を showModal() で開き(地図の上に重ねて背後も操作させるなら show())、position: fixed; inset: auto 0 0; width: auto; max-width: none; margin: 0 を書いて下端に固定する(書かないと既定の配置が残り、上端や中央に出て幅も狭まる)
- dialog に transform: translateY(100%) と transform の transition、dialog[open] に translateY(0) を書く
- 開く動きは、その後ろに置いた @starting-style の中の dialog[open] に translateY(100%) を書いて出す(@starting-style は Chrome・Edge は 117 から、Safari は 17.5 から、Firefox は 129 から)
- 閉じる動きは dialog 側の transition に display と overlay を allow-discrete で足す。閉じる動きが無くても成り立つようにする
- display の遷移は Chrome・Edge は 117 から、Safari は 18 からで、Firefox は未対応のため閉じる動きが飛ぶ。overlay は Chrome・Edge だけで、Safari では最前面から外れた状態で閉じる動きが走る
- 閉じるボタンを必ず置く。暗幕を押しても閉じるなら dialog に closedby="any" を付ける(Chrome・Edge は 134 から、Firefox は 141 から。Safari は 27.0 時点で未対応)
- 'closedBy' in HTMLDialogElement.prototype が偽のときだけ、pointerdown と click の target がどちらも dialog 自身なら requestClose()(無ければ close())を呼ぶ。dialog の padding と border は 0 にし、余白は内側の要素に持たせる
- 高さを画面いっぱいにすると、モーダルとの違いが消える。背後が少し見える高さに留める
- 掴んで下げる操作だけで閉じさせない。閉じるボタンも置く
- キーボードが出る入力を入れると、シートが押し上げられて崩れやすい
## アクセシビリティの要件
- showModal() で開くときはモーダルと同じ扱いにする(フォーカスの移動・Esc・背後の inert はブラウザが持つ)
- 掴む部分(ハンドル)は装飾なので aria-hidden にし、操作は別のボタンで用意する
- 開閉の動きは prefers-reduced-motion のときに止める
## 参考にする実装
この形を出発点にして、プロジェクトの命名規則・色・余白に合わせて調整してください。
```html
<div class="x-bottom-sheet">
<div class="x-bottom-sheet__stage">
<div class="x-bottom-sheet__sheet">
<span class="x-bottom-sheet__grip" aria-hidden="true"></span>
<p class="x-bottom-sheet__t">共有する</p>
<p class="x-bottom-sheet__i">リンクをコピー</p>
<p class="x-bottom-sheet__i">メールで送る</p>
</div>
</div>
</div>
```
```css
/* 貼った先のリセットに頼らないよう、この部品の中だけ border-box にする */
.x-bottom-sheet,
.x-bottom-sheet *:not([class*="fa-"]),
.x-bottom-sheet *:not([class*="fa-"])::before,
.x-bottom-sheet *:not([class*="fa-"])::after {
box-sizing: border-box;
/* 貼った先の既定の書体に引きずられないようにする。書体が変わると
文字の幅と高さが変わり、枠のサイズまでずれる */
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Hiragino Sans", "Noto Sans JP", "Yu Gothic UI", Meiryo, sans-serif;
}
.x-bottom-sheet__stage {
position: relative;
width: 210px;
height: 130px;
border: 1px solid #e3e6ea;
border-radius: 10px;
background: #f1f3f6;
overflow: hidden;
}
.x-bottom-sheet__sheet {
position: absolute;
inset: auto 0 0 0;
padding: 8px 14px 12px;
border-radius: 12px 12px 0 0;
border-top: 1px solid #e3e6ea;
background: #fff;
}
.x-bottom-sheet__grip {
display: block;
width: 36px;
height: 4px;
margin: 0 auto 8px;
border-radius: 999px;
background: #cfd4dc;
}
.x-bottom-sheet__t {
margin: 0 0 6px;
font-size: 11px;
font-weight: 700;
color: #606a7b;
}
.x-bottom-sheet__i {
margin: 0;
padding: 5px 0;
font-size: 12px;
}
```
## 出力の約束
- HTML と CSS を分けて出す。JavaScript が要るときは素の JavaScript で書き、UIフレームワークは使わない。
- 参考実装がアイコンに Font Awesome のクラスを使っている場合は、プロジェクトで使っているアイコンかインライン SVG に置き換えてよい。
- 上のアクセシビリティ要件を満たす。満たせない箇所があるときは、理由を添えて先に知らせる。
- 色・角丸・余白は既存のデザイントークンがあればそれを使う。無ければ CSS 変数として切り出す。
使いどころ
- 共有先の選択など、選択肢が数個あるとき
- 地図や一覧の上に、詳細を重ねて出したいとき
注意点
- 高さを画面いっぱいにすると、モーダルとの違いが消える。背後が少し見える高さに留める
- 掴んで下げる操作だけで閉じさせない。閉じるボタンも置く
- キーボードが出る入力を入れると、シートが押し上げられて崩れやすい
アクセシビリティの要点
- showModal() で開くときはモーダルと同じ扱いにする(フォーカスの移動・Esc・背後の inert はブラウザが持つ)
- 掴む部分(ハンドル)は装飾なので aria-hidden にし、操作は別のボタンで用意する
- 開閉の動きは prefers-reduced-motion のときに止める