ページアクセスと同時にモーダルを自動表示
このサンプルはページを開いた瞬間にモーダルが自動で開く実装です。
背景クリック/ESC/ボタンで閉じられ、閉じた後は「もう一度開く」ボタンで再表示できます。
コードについて
本記事のコードは AI(ChatGPT)による生成をベースに作成・調整しています。ご利用の環境でテストの上ご使用ください。
免責
本コードの利用に伴う不具合・損害について、当サイトは責任を負いません。自己責任にてご利用ください。
デモ
このページを表示すると自動でモーダルが開きます。閉じた後は「もう一度開く」で再表示できます。
初回アクセスで開くモーダル
このモーダルはページ読み込み直後に自動で開きます。
タブ切替のコードブロック(コピー可)
<!-- ===============================================
自動表示モーダル:HTML 構造
- .cp-modal …… モーダル一式のラッパー(スコープ)
- .btn …… 開閉トリガー(今回は「もう一度開く」)
- .layer …… 背景の暗幕(クリックで閉じる対象)
- .dialog …… 本体(タイトル・本文・閉じるボタンを内包)
- aria-* …… アクセシビリティ配慮(役割/関連付け)
- tabindex="-1" …… JSでフォーカスを当てられるように
=============================================== -->
<div class="cp-modal" id="cp-modal-2">
<!-- 再表示用のボタン:初回はJSで自動オープン -->
<button class="btn" data-open-modal>もう一度開く</button>
<!-- 暗幕レイヤー:見た目/クリック判定の両方で使用 -->
<div class="layer" aria-hidden="true">
<!-- ダイアログ本体:タイトル・本文・閉じるボタン -->
<div class="dialog" role="dialog" aria-modal="true" aria-labelledby="cp-modal2-title" tabindex="-1">
<!-- タイトル:スクリーンリーダーへ結び付け -->
<h3 id="cp-modal2-title">初回アクセスで開くモーダル</h3>
<!-- 内容:任意の説明やバナー等に置き換え可能 -->
<p>このモーダルはページ読み込み直後に自動で開きます。</p>
<!-- 「閉じる」ボタン:明示的に閉じたい場合 -->
<button class="btn" data-close-modal>閉じる</button>
</div> <!-- /.dialog -->
</div> <!-- /.layer -->
</div> <!-- /.cp-modal -->
/* ===============================================
モーダルの見た目(テーマ衝突を避けるため .cp-modal にスコープ)
=============================================== */
/* ボタン(開く/閉じる 共通の最小スタイル) */
.cp-modal .btn{
background:#0b6bff; /* アクセント色 */
color:#fff; /* 文字は白 */
border:none; /* 既定ボーダーは不要 */
border-radius:12px; /* 角丸でタップしやすく */
padding:10px 14px; /* 触りやすい余白 */
cursor:pointer; /* カーソルで押せる表現 */
}
/* 暗幕レイヤー(初期は非表示:opacity=0 & pointer-events:none) */
.cp-modal .layer{
position:fixed; /* 画面全体を覆う */
inset:0; /* 四辺0でフルスクリーン */
background:rgba(2,8,23,.5); /* 半透明の暗幕 */
display:grid; /* 子を中央配置するためにグリッド使用 */
place-items:center; /* 縦横中央にダイアログを配置 */
opacity:0; /* 初期は見えない */
pointer-events:none; /* 初期はクリック不可(背面に操作を通す) */
transition:.2s; /* フェードイン/アウト */
}
/* 表示フラグ data-open="1" が付いた時に表示状態へ */
.cp-modal[data-open="1"] .layer{
opacity:1; /* フェードインで可視化 */
pointer-events:auto; /* 背景クリックを受け付ける */
}
/* ダイアログ本体(白い箱) */
.cp-modal .dialog{
background:#fff; /* 白背景でカード風 */
color:#0f172a; /* 読みやすい文字色 */
border-radius:12px; /* 角丸 */
padding:20px; /* 内側余白 */
max-width:400px; /* 横幅の上限 */
/* 極小画面での収まりを強めたい場合は width:90vw; を追加 */
}
/* フォーカス可視化(キーボード操作に配慮) */
.cp-modal .btn:focus,
.cp-modal .dialog:focus{
outline:2px solid #93c5fd; /* 明るいリング */
outline-offset:2px; /* リングを少し外側に */
}
/* ===============================================
モーダル開閉ロジック+ページ表示時の自動オープン
- open() : 表示(data-open="1" 付与 & フォーカス移動)
- close() : 非表示(data-open 削除 & 監視解除)
- 入力経路: 1) もう一度開くボタン 2) 背景クリック 3) ESCキー
=============================================== */
(() => {
/* ルートの取得(id は HTML と一致) */
const root = document.getElementById("cp-modal-2");
if(!root) return; /* 念のため要素未取得なら終了 */
/* 操作対象の参照を確保 */
const layer = root.querySelector(".layer"); /* 暗幕(背景クリック判定) */
const dialog = root.querySelector(".dialog"); /* 本体(開時フォーカス先) */
const openBtn = root.querySelector("[data-open-modal]"); /* 「もう一度開く」 */
const closeBtn = root.querySelector("[data-close-modal]"); /* 「閉じる」 */
/* キーイベント:ESCで閉じる */
function onKey(e){ if(e.key==="Escape") close(); }
/* 表示処理:表示フラグ付与+フォーカス移動+ESC監視 */
function open(){
root.setAttribute("data-open","1"); /* CSS表示トリガー */
dialog && dialog.focus(); /* キーボード操作開始点 */
document.addEventListener("keydown", onKey); /* ESC監視を開始 */
}
/* 非表示処理:フラグ解除+監視解除+フォーカス返却 */
function close(){
root.removeAttribute("data-open"); /* 表示トリガー解除 */
document.removeEventListener("keydown", onKey); /* ESC監視解除 */
openBtn && openBtn.focus(); /* 元ボタンへフォーカス返却 */
}
/* クリック経路の接続 */
openBtn && openBtn.addEventListener("click", open); /* 再表示 */
closeBtn && closeBtn.addEventListener("click", close); /* 明示的に閉じる */
layer && layer.addEventListener("click", (e)=>{
/* レイヤー自体をクリックした場合のみ閉じる(ダイアログ内は閉じない) */
if(e.target===layer) close();
});
/* ページアクセス直後に自動で開く(描画が整ってから実行) */
if(document.readyState==="complete" || document.readyState==="interactive"){
setTimeout(open, 0); /* すぐ開く(マイクロタスク明け) */
}else{
document.addEventListener("DOMContentLoaded", ()=> setTimeout(open, 0));
}
})();
ポイント
- 自動表示:
DOMContentLoaded
後に open()
を呼び出し、初回アクセスで即オープン。
- 3つの閉じ方:閉じるボタン/背景クリック/ESC キー。
- 再表示:閉じた後は「もう一度開く」ボタンで再表示可能。
- アクセシビリティ:開いたらダイアログへフォーカス、閉じたらトリガーへ返却。
コメント