html・cssのみで動かせるモーダルウインドウ
JavaScriptなしで、HTML+CSSだけで開閉できるモーダルの最小実装です。
チェックボックスと
コードについて
本記事のコードは AI(ChatGPT)による生成をベースに作成・調整しています。ご利用の環境でテストの上ご使用ください。
免責
本コードの利用に伴う不具合・損害について、当サイトは責任を負いません。自己責任にてご利用ください。
デモ
「モーダルを開く」→ 背景クリック or 「閉じる」で閉じます(※ESCやフォーカストラップは非対応)。
タブ切替のコードブロック(コピー可)
--> <!-- メタ情報:作成者・日付・注意 -->
<section class="cssmodal" id="cssonly-05"> <!-- デモ用モーダルのスコープ(任意ID) -->
<input class="toggle" type="checkbox" id="modal05-toggle"> <!-- 視覚非表示のトグル(ONで表示) -->
<label class="btn" for="modal05-toggle">モーダルを開く</label> <!-- 開くボタン(labelでチェックON) -->
<div class="layer" aria-hidden="true"> <!-- 暗幕+本体の入れ物(初期は非表示) -->
<label class="bg" for="modal05-toggle"></label> <!-- 背景クリックで閉じる(チェックOFF) -->
<div class="dialog" role="dialog" aria-labelledby="ttl-cssonly-05" tabindex="-1"> <!-- 本体カード:A11y属性 -->
<h3 id="ttl-cssonly-05">CSS-Only モーダル</h3> <!-- ダイアログの見出し -->
<p>このモーダルは<strong>HTML+CSSだけ</strong>で開閉します。チェックONで表示、背景またはボタンでOFF。</p> <!-- 説明文 -->
<label class="btn" for="modal05-toggle">閉じる</label> <!-- 閉じるボタン(labelでチェックOFF) -->
</div> <!-- /.dialog -->
</div> <!-- /.layer -->
</section> <!-- /.cssmodal -->
/* ========== CSS-Only Modal(最小スタイル) ========== */ /* セクション開始:CSSだけでモーダルを動かす最小スタイル群 */
.cssmodal { /* モーダル全体のセクション要素に適用する基本スタイル */
margin: 8px 0; /* セクション上下の余白(上下8px・左右0) */
} /* /.cssmodal 終了 */
.cssmodal .btn { /* 開閉ボタン(開く/閉じる共通)の見た目 */
background: #0b6bff; /* 背景色:アクセントのブルー */
color: #fff; /* 文字色:白でコントラスト確保 */
border: none; /* 既定のボーダーを除去してフラットに */
border-radius: 12px; /* 角丸でタップしやすく */
padding: 10px 14px; /* 内側余白:上下10px・左右14pxでクリックしやすく */
cursor: pointer; /* ホバー時にポインタカーソル表示 */
} /* /.cssmodal .btn 終了 */
.cssmodal .toggle { /* 表示制御用のチェックボックス(視覚的に非表示) */
position: absolute; /* 画面外配置のため絶対配置に */
inline-size: 1px; /* 横幅1px(視覚非表示テクニックの一部) */
block-size: 1px; /* 高さ1px(視覚非表示テクニックの一部) */
margin: -1px; /* 余白を-1pxにしてレイアウトから外す */
padding: 0; /* 余白をゼロに */
border: 0; /* ボーダーをゼロに */
clip: rect(0 0 0 0); /* 旧来のクリッピングで画面外に隠す(支援技術対応) */
clip-path: inset(50%); /* 新しいクリッピングでも視覚非表示に */
overflow: hidden; /* はみ出し非表示でスクロールさせない */
white-space: nowrap; /* 改行を抑止(念のための保険) */
} /* /.cssmodal .toggle 終了 */
.cssmodal .layer { /* 暗幕レイヤー(背景を覆う半透明+ダイアログの入れ物) */
position: fixed; /* ビューポート基準でスクロールに追従 */
inset: 0; /* 上下左右0で全画面を覆うショートハンド */
display: grid; /* 中央寄せレイアウトに便利なGridを使用 */
place-items: center; /* 子要素(.dialog)を縦横中央に配置 */
opacity: 0; /* 初期状態は透明(非表示) */
pointer-events: none; /* 初期はクリック等を透過(操作不可) */
transition: opacity .2s; /* フェードイン・アウトの滑らかさ */
background: rgba(2, 8, 23, .5); /* 背景色:濃紺の50%透過で背面を暗く */
z-index: 9999; /* ほぼ最前面に配置(テーマ要素より前面) */
} /* /.cssmodal .layer 終了 */
.cssmodal .dialog { /* モーダル本体カード(白い小窓) */
background: #fff; /* 白背景で内容を読みやすく */
color: #0f172a; /* 文字色:濃いインク色でコントラスト確保 */
border-radius: 12px; /* 角丸で柔らかい印象に */
padding: 20px; /* 内側余白たっぷりで可読性UP */
inline-size: min(680px, 92vw); /* 横幅:最大680px、モバイルは92vwまで */
max-block-size: 82vh; /* 最大高さ:画面高の約82%(はみ出し防止) */
overflow: auto; /* 内容が溢れたら内部スクロール */
box-shadow: 0 10px 30px rgba(0, 0, 0, .2); /* 影で背景から浮かせてモーダル感を演出 */
} /* /.cssmodal .dialog 終了 */
.cssmodal .bg { /* 背景クリック領域(labelとして配置) */
position: fixed; /* ビューポート基準で全画面配置 */
inset: 0; /* 四辺0で暗幕と同じ領域を覆う */
} /* /.cssmodal .bg 終了 */
.cssmodal .btn:focus,
.cssmodal .dialog:focus { /* キーボード操作時のフォーカス可視化 */
outline: 2px solid #93c5fd; /* 外枠に2pxのフォーカスリング(淡いブルー) */
outline-offset: 2px; /* 要素から少し離して視認性を高める */
} /* /.cssmodal .btn:focus, .dialog:focus 終了 */
.cssmodal .toggle:checked ~ .layer { /* チェックON時:隣接兄弟以降の.layerに適用(CSSのみの開閉) */
opacity: 1; /* 暗幕とダイアログをフェードイン表示 */
pointer-events: auto; /* クリックを受け付ける(操作可能に) */
} /* /.cssmodal .toggle:checked ~ .layer 終了 */
@media (prefers-reduced-motion: reduce) { /* OSの「動きを減らす」設定に配慮するメディアクエリ */
.cssmodal .layer { /* 暗幕レイヤーのトランジションに適用 */
transition: none; /* フェードを無効化して即時表示・非表示に */
} /* /.cssmodal .layer(reduce)終了 */
} /* /@media (prefers-reduced-motion: reduce) 終了 */
運用のヒント
- 複数設置:同ページに複数置く場合、
id="modal05-toggle"
や id="cssonly-05"
を重複させないでください。
- テーマとの衝突回避:必要に応じてセレクタに親スコープ(例:
.entry-content
)を追加してください。
- JS機能が必要な場合:ESCで閉じる、フォーカストラップ、背面スクロール固定などはJS追加で実現できます。
コメント