複数メニューを同時制御/親子メニュー
設定メニューと通知メニューなど、複数のドロワーを同時に扱うサンプルです。親メニューを開いたまま子メニューを操作したり、両方を閉じたりする挙動を制御します。
コードについて
本記事のコードは AI(ChatGPT)による生成をベースに作成・調整しています。ご利用の環境でテストの上ご使用ください。
免責 本コードの利用に伴う不具合・損害について、当サイトは責任を負いません。自己責任にてご利用ください。
免責 本コードの利用に伴う不具合・損害について、当サイトは責任を負いません。自己責任にてご利用ください。
デモ
コードをコピーして使おう!
/* =========================================================
CSS:複数ドロワー(親=設定/子=通知)の同時制御スタイル
対象スコープ:#multi-drawer-demo の子要素のみ
目的:
- 親ドロワーは右端から画面内へスライドイン
- 子ドロワーは「親を閉じずに」親の右側から重ねて出現
- オーバーレイは1枚共通、どちらか開いていれば表示
========================================================= */
/* 1) ラッパー:位置文脈の起点(将来的な拡張に備えて relative) */
#multi-drawer-demo {
position: relative; /* 子要素の絶対配置やスタック順調整に備える */
}
/* 2) 共通ボタン(開くボタン) */
#multi-drawer-demo .menu-btn {
background: #0b6bff; /* 強調色(青) */
color: #fff; /* 白文字でコントラスト確保 */
border: none; /* 既定のボーダーを排除 */
border-radius: 8px; /* 角丸でタップしやすく */
padding: 10px 16px; /* クリック領域確保 */
cursor: pointer; /* ポインタカーソル */
margin: 0 8px 8px 0; /* ボタン間の余白 */
}
/* 3) オーバーレイ:背景の暗幕(共通1枚) */
#multi-drawer-demo .overlay {
position: fixed; /* 画面全体を覆う */
inset: 0; /* top/right/bottom/left を一括指定 */
background: rgba(0,0,0,0.5); /* 半透明の黒で背面を暗くする */
opacity: 0; /* 初期は透明(非表示) */
pointer-events: none; /* クリック不可(当たり判定なし) */
transition: .25s; /* フェードのアニメーション */
z-index: 90; /* パネルより背面に配置(数値は親子の間) */
}
/* オーバーレイの有効状態(どちらか開いていれば付与) */
#multi-drawer-demo .overlay.active {
opacity: 1; /* フェードイン */
pointer-events: auto; /* クリック可能に(タップで閉じる) */
}
/* 4) 親ドロワー(設定):右外→画面内へスライドイン */
#multi-drawer-demo .panel[data-panel="settings"] {
position: fixed; /* ビューポート基準に固定表示 */
top: 0; /* 上端から始める */
right: 0; /* 表示位置は画面右端に固定 */
height: 100dvh; /* 端末の動的ビューポート高をフル使用 */
width: min(80vw, 320px); /* 画面幅に応じて最大320px */
background: #fff; /* 本体の背景を白 */
box-shadow: -6px 0 18px rgba(0,0,0,.25); /* 右からの浮き上がり影 */
transform: translateX(100%); /* 初期は右の外に隠しておく */
transition: .3s ease-out; /* スライドアニメーション */
z-index: 100; /* 子より背面(でもオーバーレイより前) */
}
/* 親ドロワーの「開」状態 */
#multi-drawer-demo .panel[data-panel="settings"].active {
transform: translateX(0); /* 画面内にスライドイン */
}
/* 5) 子ドロワー(通知):親のさらに右側から重ねて出現 */
#multi-drawer-demo .panel[data-panel="notice"] {
position: fixed; /* 親とは独立してビューポート基準 */
top: 0; /* 上端揃え */
right: -100%; /* 初期位置は画面右端のさらに外側 */
height: 100dvh; /* 縦全体 */
width: min(80vw, 300px); /* 親より少し狭めの幅(好みで調整可) */
background: #fff; /* 背景白 */
box-shadow: -6px 0 18px rgba(0,0,0,.25); /* 浮き上がり影 */
transform: translateX(0); /* 初期は移動せず(rightで位置管理) */
transition: .3s ease-out; /* スライドアニメーション */
z-index: 110; /* 親(100)より前面に表示して重なる */
}
/* 子ドロワーの「開」状態(親の上に重なるように right を 0 に) */
#multi-drawer-demo .panel[data-panel="notice"].active {
right: 0; /* 画面右端ピッタリに表示(親の上に重なる) */
transform: translateX(0); /* ここでは transform は固定のまま */
}
/* 6) 共通のヘッダーと内側配置 */
#multi-drawer-demo .panel header {
background: #f8fafc; /* 薄いグレーで区切り */
padding: 14px; /* 見出しの内側余白 */
font-weight: 600; /* 強調 */
border-bottom: 1px solid #e5e7eb; /* 下境界線 */
}
#multi-drawer-demo .panel .inner {
padding: 16px; /* コンテンツの余白 */
}
/* 7) 閉じるボタン:危険色で明確に */
#multi-drawer-demo .close-btn {
display: block; /* ブロック化して横幅・余白を扱いやすく */
margin-top: 20px; /* 前要素との距離を確保 */
background: #e11d48; /* 赤系(注意喚起) */
color: #fff; /* 白文字 */
border: none; /* 不要な枠を外す */
border-radius: 6px; /* 角丸 */
padding: 8px 12px; /* クリック領域 */
cursor: pointer; /* ポインタ表示 */
}
コメント