コピペで完結!ドロワーメニュー#05【メニュー表示で背景をぼかす】

html/css/js

ドロワーメニュー(右)表示で背景をぼかす

背景を半透明+ブラーでフェードし、右からスライドするドロワーを実装します。ESC・背景クリック・閉じるボタンに対応し、スクロールロック&簡易フォーカストラップも備えています。

コードについて 本記事のコードは AI(ChatGPT)による生成をベースに作成・調整しています。ご利用の環境でテストの上ご使用ください。
免責 本コードの利用に伴う不具合・損害について、当サイトは責任を負いません。自己責任にてご利用ください。

デモ

コードをコピーして使おう!

/* =========================================================
  半透明ブラー背景付きドロワー(右)— 完全版 CSS
  ・背景は backdrop-filter でブラー
  ・[data-open="1"] の付与/削除で開閉制御
  ・トリガーボタン(#openDrawerBtn / .btn)に確実にスタイルを適用
    └ WPテーマの既定ボタンに負けないように appearance/border 等をリセット
========================================================= */

/* --------------------------------
   0) トリガーボタン(開くボタン)
   - HTML例:<button id="openDrawerBtn" class="btn">メニューを開く</button>
   - #openDrawerBtn と .btn の両方を指定し、WP既定を打ち消して青ボタン化
-------------------------------- */
button#openDrawerBtn,          /* id優先(特異性を上げて確実に適用) */
button.btn,                    /* button要素に .btn が付いた場合 */
.btn{                          /* a.btn にも効かせるための保険 */
  -webkit-appearance:none;     /* iOS等の既定外観を無効化 */
  appearance:none;             /* 各ブラウザの既定外観を無効化 */
  background:#0b6bff;          /* アクセントの青い背景 */
  color:#fff;                  /* 文字色は白 */
  border:none;                 /* 枠線をリセット */
  box-shadow:none;             /* 既定のシャドウを除去(WP対策) */
  border-radius:12px;          /* 角丸でボタンらしく */
  padding:10px 14px;           /* タップしやすい余白 */
  line-height:1.2;             /* ボタン内の行高を詰める */
  font:inherit;                /* 親のフォント設定を継承 */
  display:inline-block;        /* 幅・高さを素直に扱えるように */
  text-decoration:none;        /* a.btn の下線を消す */
  cursor:pointer;              /* マウスポインタを指マークに */
}
button#openDrawerBtn:hover,
button.btn:hover,
.btn:hover{
  opacity:.92;                 /* ホバーでわずかに暗くして反応を出す */
}
button#openDrawerBtn:active,
button.btn:active,
.btn:active{
  transform:translateY(1px);   /* クリック時に1px沈ませる */
}
button#openDrawerBtn:focus-visible,
button.btn:focus-visible,
.btn:focus-visible{
  outline:2px solid #93c5fd;   /* キーボード操作時の可視フォーカス */
  outline-offset:2px;          /* 枠を外側にずらして見やすく */
}

/* --------------------------------
   1) ドロワーの土台(必要に応じて position などを追加)
-------------------------------- */
.drawer{                        /* ルート。現状は特に指定不要(状態は data-open で管理) */ }

/* --------------------------------
   2) オーバーレイ(半透明+ブラー)
   - ブラウザ対応のため -webkit-backdrop-filter も併記
-------------------------------- */
.drawer .overlay{
  position:fixed;               /* 画面全体を覆う */
  inset:0;                      /* top/right/bottom/left: 0 を一括指定 */
  z-index:9998;                 /* パネルより一段下に配置 */
  background:rgba(2,8,23,.35);  /* 半透明の下地(ブラーと併用) */
  -webkit-backdrop-filter:blur(12px); /* Safari等の前置き版 */
  backdrop-filter:blur(12px);          /* 主要ブラウザのブラー */
  opacity:0;                    /* 初期は非表示 */
  pointer-events:none;          /* 初期はクリック無効(背面操作を妨げない) */
  transition:opacity .28s ease-out; /* フェードイン/アウト */
}

/* --------------------------------
   3) パネル本体(右からスライドイン)
-------------------------------- */
.drawer .panel{
  position:fixed;               /* ビューポート基準に固定 */
  top:0;                        /* 上端に貼り付け */
  right:0;                      /* 右端から出す */
  z-index:9999;                 /* 最前面に配置(オーバーレイより上) */
  height:100dvh;                /* 端末UIに強いvh単位で全高 */
  width:min(86vw,360px);        /* 画面幅86%か360pxの小さい方 */
  background:#fff;              /* パネルの背景は白 */
  color:#0f172a;                /* 文字色(濃いインク色) */
  border-left:1px solid #e5e7eb;/* 画面との区切り線(左辺) */
  box-shadow:-10px 0 32px rgba(2,8,23,.18); /* 左方向へ落ちる影 */
  transform:translateX(100%);   /* 初期は画面外(右)へ退避 */
  transition:transform .32s cubic-bezier(.22,.9,.24,1); /* スライドの動き */
  display:flex;                 /* 中身を縦積みレイアウトに */
  flex-direction:column;        /* ヘッダー→本文の順で縦方向 */
}

/* パネル内ヘッダー(タイトル+閉じる) */
.drawer .panel header{
  display:flex;                 /* タイトルとボタンを横並び */
  align-items:center;           /* 縦方向中央揃え */
  justify-content:space-between;/* 左右に振り分け */
  padding:14px 16px;            /* 内側余白(タップしやすさも確保) */
  border-bottom:1px solid #e5e7eb;/* 下辺の区切り線 */
  background:#fff;              /* スクロール時も白背景を維持 */
  position:sticky;              /* ヘッダーを上部に固定 */
  top:0;                        /* 固定位置:上端 */
}
.drawer .panel h3{
  margin:0;                     /* 既定の上下余白をリセット */
  font-size:16px;               /* 見出しサイズ(モバイル基準) */
}
.drawer .close{
  background:#fff;              /* 背景白(透過時の読みやすさ) */
  border:1px solid #e5e7eb;     /* 薄い枠線でボタン感を出す */
  border-radius:10px;           /* 角丸 */
  padding:6px 10px;             /* クリック領域の確保 */
  cursor:pointer;               /* クリック可能であることを示す */
}

/* コンテンツ(例:ナビ) */
.drawer nav{
  display:grid;                 /* 縦並び+gap で間隔管理 */
  gap:8px;                      /* 各項目の間隔 */
  padding:12px;                 /* 内側余白 */
}
.drawer nav a{
  display:block;                /* 全幅のタップ領域に */
  padding:10px 12px;            /* クリックしやすい余白 */
  border-radius:10px;           /* 角丸 */
  color:#0f172a;                /* テキスト色 */
  text-decoration:none;         /* 下線を消す */
}
.drawer nav a:hover{
  background:#f8fafc;           /* ホバー時の薄いハイライト */
}

/* --------------------------------
   4) 開いた状態(オーバーレイON + パネルIN)
-------------------------------- */
.drawer[data-open="1"] .overlay{
  opacity:1;                    /* オーバーレイを表示 */
  pointer-events:auto;          /* 背景クリックで閉じられる */
}
.drawer[data-open="1"] .panel{
  transform:translateX(0);      /* パネルを画面内へスライドイン */
}

/* --------------------------------
   5) 背景スクロールロック(必要な場合に body へ付与)
-------------------------------- */
body.is-locked{
  overflow:hidden;              /* 背景をスクロール不可に */
  touch-action:none;            /* モバイルでのスワイプ抑止 */
}

/* --------------------------------
   6) ブラー非対応ブラウザのフォールバック
-------------------------------- */
@supports not ((-webkit-backdrop-filter:blur(1px)) or (backdrop-filter:blur(1px))){
  .drawer .overlay{
    background:rgba(2,8,23,.55);/* ぼかし無しでも視認性が出るよう濃くする */
  }
}

コメント