モーダルウインドウ内のみキー操作可能にする方法
モーダルウインドウを表示している間、Tabキーによる操作をモーダルウインドウ内だけに制限する方法を紹介します。通常のページには入力欄やセレクトボックス、ボタン、リンクなど複数の操作できる要素がありますが、モーダルを開いているときはモーダル内の操作に集中してもらいたい場合があります。本記事では、HTML・CSS・JavaScriptを使ってキーボード操作の移動範囲を制御します。
サンプルではモーダルウインドウを開くと、最初の入力欄へ自動でフォーカスを移動します。その後Tabキーを押すと、入力欄、セレクトボックス、OKボタン、閉じるボタンの順番でフォーカスが移動します。最後の要素からさらにTabキーを押すと最初の要素へ戻り、Shift+Tabキーで逆方向へ移動した場合もモーダル内を循環するため、背景ページの入力欄やボタンへフォーカスが移動しません。
入力フォームや確認画面、設定画面などをモーダルウインドウで表示する場合に活用できます。また、モーダルを閉じると、フォーカスは最初にモーダルを開いたボタンへ戻ります。マウスだけでなくキーボードでも操作しやすくなり、モーダルを表示している間に誤って背景ページの入力欄やボタンを操作してしまうことを防げます。
免責事項 本コードの利用により発生した損害について、当サイトは一切の責任を負いません。
デモ
モーダルを開いたあとにTabキーを押してください。モーダル表示中は背景側へフォーカスが移動せず、モーダル内の操作項目だけを移動します。
Tabキーを押して、フォーカスの移動範囲を確認してください。
モーダルを開いたあとにTabキーを繰り返し押してください。最後の「閉じる」から次へ進むと最初の入力欄へ戻ります。Shift+Tabキーでは逆方向に移動し、最初の入力欄から最後の「閉じる」へ移動します。
コードをコピーして使おう!
<!DOCTYPE html>
<html lang="ja">
<head>
<!-- 文字コード -->
<meta charset="UTF-8">
<!-- スマートフォン対応 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- ページタイトル -->
<title>モーダルウインドウ内のみキー操作可能にする方法</title>
<!-- CSSファイル -->
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- デモ表示エリア -->
<div class="modal-focus_wrap">
<!-- タイトル -->
<div class="modal-focus_title">
モーダルウインドウ内のみキー操作可能
</div>
<!-- 説明文 -->
<p class="modal-focus_text">
モーダルを開いたあとにTabキーを押してください。モーダル表示中は背景側へフォーカスが移動せず、モーダル内の操作項目だけを移動します。
</p>
<!-- 背景ページ側の操作項目 -->
<div class="modal-focus_demo">
<!-- 背景ページ側の入力欄 -->
<input type="text" placeholder="本文入力欄">
<!-- 背景ページ側のセレクトボックス -->
<select>
<option>本文セレクト</option>
<option>選択肢1</option>
<option>選択肢2</option>
</select>
<!-- モーダルを開くボタン -->
<button class="modal-focus_open" id="modal-focus-open" type="button">
モーダルを開く
</button>
</div>
</div>
<!-- モーダルウインドウ -->
<div class="modal-focus_modal" id="modal-focus-modal" role="dialog" aria-modal="true" aria-labelledby="modal-focus-title">
<!-- モーダルタイトル -->
<div class="modal-focus_modal-title" id="modal-focus-title">
モーダルタイトル
</div>
<!-- モーダル説明文 -->
<p class="modal-focus_modal-text">
Tabキーを押して、フォーカスの移動範囲を確認してください。
</p>
<!-- モーダル内の入力欄 -->
<input type="text" placeholder="モーダル入力欄">
<!-- モーダル内のセレクトボックス -->
<select>
<option>モーダルセレクト</option>
<option>選択肢A</option>
<option>選択肢B</option>
</select>
<!-- モーダル内の操作ボタン -->
<button class="modal-focus_action" type="button">
OK
</button>
<!-- 閉じるボタン -->
<button class="modal-focus_close" id="modal-focus-close" type="button">
閉じる
</button>
</div>
<!-- JavaScriptファイル -->
<script src="script.js"></script>
</body>
</html>
サンプル一式を取得する場合 HTML・CSSなどすべてのファイルが必要な場合は、「サンプル一式をダウンロード」をクリックしてください。
Q ダウンロードしたけど、これをネット上で動かすにはどうするの?
Googleアカウントがあれば、InfinityFreeで無料サーバーを作成して、ダウンロードしたサンプルをネット上で動かせます。
InfinityFreeを初めて利用する場合は①から、すでにサーバーを作成している場合は②へ進んでください。
ファイル構成と設置方法
このサンプルはHTML・CSS・JavaScriptの3ファイルで構成されています。HTMLでは背景ページ側の入力欄やセレクトボックス、モーダルウインドウ内の入力欄やボタンを配置します。CSSでは各操作項目とモーダルウインドウのデザインを設定し、JavaScriptではモーダルの開閉とTabキー・Shift+Tabキーによるフォーカス移動を制御します。
sample/
├── index.html
├── style.css
└── script.js
各ファイルの役割
index.htmlはページ全体を構成するファイルです。背景ページ側には入力欄、セレクトボックス、「モーダルを開く」ボタンを配置し、モーダルウインドウ内には入力欄、セレクトボックス、OKボタン、「閉じる」ボタンを配置しています。背景側にも操作できる要素があるため、モーダル表示中にTabキーを押しても背景側へフォーカスが移動しないことを確認できます。
style.cssはデモ表示エリア、入力欄、セレクトボックス、ボタン、モーダルウインドウのデザインを設定するファイルです。モーダルウインドウは通常時をdisplay:none;で非表示にし、is-activeクラスが追加されるとdisplay:block;へ切り替わって画面中央に表示されます。
script.jsはモーダルウインドウの開閉とキーボードフォーカスを制御するファイルです。モーダルを開くと、モーダル内にある入力欄、セレクトボックス、ボタンを取得して最初の入力欄へフォーカスを移動します。最後の操作項目でTabキーを押すと最初の操作項目へ戻り、最初の操作項目でShift+Tabキーを押すと最後の操作項目へ移動するため、モーダル表示中はフォーカスが背景ページへ移動しません。
設置方法・使い方
sampleフォルダへindex.html、style.css、script.jsを配置します。3つのファイルを同じ階層へ保存したあと、sample/index.htmlをブラウザで開いてください。index.htmlからstyle.cssとscript.jsを読み込む構成になっているため、追加のライブラリや外部サービスを用意する必要はありません。
「モーダルを開く」をクリックするとモーダルウインドウが表示され、最初の入力欄へフォーカスが移動します。その状態でTabキーを押すと、モーダル内の入力欄、セレクトボックス、OKボタン、「閉じる」ボタンの順番でフォーカスが移動します。最後の「閉じる」ボタンからさらにTabキーを押すと最初の入力欄へ戻ります。Shift+Tabキーでは逆方向に移動し、最初の入力欄から背景ページへ戻らず最後の「閉じる」ボタンへ移動します。「閉じる」をクリックするとモーダルが非表示になり、フォーカスは「モーダルを開く」ボタンへ戻ります。
カスタマイズできる内容
index.htmlではタイトルや説明文、入力欄のプレースホルダー、セレクトボックスの選択肢、ボタンの文字などを変更できます。モーダル内でTabキーによるフォーカス移動の対象にする要素を追加する場合は、HTMLへ必要な入力欄やボタンなどを追加できます。
style.cssでは表示エリアやモーダルウインドウの横幅、余白、背景色、角丸、影、入力欄やボタンのサイズなどを変更できます。script.jsではquerySelectorAll("input, select, button")でモーダル内のフォーカス対象を取得しています。配布コードではinput要素、select要素、button要素が対象になっているため、モーダル内の構成を変更する場合は、実際に配置する操作要素に合わせてこのセレクタも変更してください。
数値調整
style.css
padding:40px 20px;
ページ全体の内側余白です。上下の40pxを大きくすると画面上下との間隔が広がり、左右の20pxを大きくすると画面左右との間隔が広がります。
max-width:700px;
デモ表示エリアの最大横幅です。値を大きくすると横に広がり、小さくするとコンパクトになります。
margin:40px auto;
デモ表示エリアの上下余白です。40pxを大きくすると上下の間隔が広がり、小さくすると狭くなります。
padding:32px;
デモ表示エリアの内側余白です。値を大きくすると内容と枠線の間隔が広がり、小さくすると詰まった表示になります。
border-radius:18px;
デモ表示エリアの角丸です。値を大きくすると丸みが強くなり、0にすると四角になります。
font-size:22px;
タイトルの文字サイズです。値を大きくすると文字が大きくなり、小さくすると控えめになります。
margin:0 0 24px;
説明文の下側余白です。24pxを大きくすると背景ページ側の操作項目との間隔が広がり、小さくすると狭くなります。
gap:12px;
背景ページ側の入力欄、セレクトボックス、「モーダルを開く」ボタンの間隔です。値を大きくすると各項目の間隔が広がり、小さくすると狭くなります。
max-width:420px;
背景ページ側の操作エリアとモーダルウインドウの最大横幅です。値を大きくすると横に広がり、小さくするとコンパクトになります。
padding:12px;
入力欄、セレクトボックス、モーダル内のOKボタンなどに使用している内側余白です。値を大きくすると各要素が大きくなり、小さくするとコンパクトになります。
border-radius:8px;
入力欄、セレクトボックス、ボタンに使用している角丸です。値を大きくすると丸みが強くなり、0にすると四角になります。
font-size:16px;
入力欄、セレクトボックス、ボタンに使用している文字サイズです。値を大きくすると文字が大きくなり、小さくすると文字が小さくなります。
width:calc(100% - 40px);
モーダルウインドウの横幅です。40pxは画面幅から差し引く値で、大きくすると画面左右の余白が広がり、小さくするとモーダルが画面端へ近づきます。
z-index:9999;
モーダルウインドウの重なり順です。値が大きい要素ほど前面に表示されます。サイトへ組み込む場合は、ほかの固定要素との重なり順に合わせて調整できます。
padding:28px;
モーダルウインドウの内側余白です。値を大きくすると内容とモーダル外周の間隔が広がり、小さくすると狭くなります。
box-shadow:0 20px 40px rgba(0,0,0,.2);
モーダルウインドウの影です。20pxは影の縦方向の位置、40pxはぼかしの大きさです。値を変更すると影の位置や広がりを調整できます。
margin:0 0 20px;
モーダル内の説明文の下側余白です。20pxを大きくすると入力欄との間隔が広がり、小さくすると狭くなります。
margin-bottom:14px;
モーダル内の入力欄、セレクトボックス、OKボタンに設定している下側余白です。値を大きくすると各操作項目の間隔が広がり、小さくすると狭くなります。
padding:10px 20px;
「閉じる」ボタンの内側余白です。上下の10pxを大きくするとボタンが高くなり、左右の20pxを大きくするとボタンが横に広がります。
レスポンシブ対応
このサンプルはレスポンシブ対応です。style.cssのモーダルウインドウへwidth:calc(100% - 40px)とmax-width:420pxを設定しているため、画面幅が狭くなると左右に余白を残しながら横幅が縮小されます。背景ページ側とモーダル内の入力欄・セレクトボックスにはwidth:100%を設定しているため、それぞれの親要素の横幅に合わせて表示されます。
また、640px以下ではデモ表示エリアの内側余白をpadding:24px 18px;、モーダルウインドウの内側余白をpadding:24px 18px;へ変更しています。画面幅が狭いスマートフォンでは左右の余白を抑え、タブレットやPCでは通常の余白で表示される構成です。
コメント