はじめに
モーダルの外をクリックしたら閉じるべきか。
この問いに対して、私は今、次のように考えています。
問題は「外クリックで閉じるかどうか」ではなく、
ユーザーがまだ「入力途中」かどうかである。
この考えに基づいて、最終的に整理した判断ルールは以下です。
結論:最終的に採用した判断ルール(第三版)
A. 閲覧型モーダル
閲覧専用で送信操作のないモーダル
➡️モーダル外をクリックすると閉じる
B. 単一アクション型モーダル
1回のクリックで送信操作が完了するモーダル
(操作後、自動的にモーダルが閉じられる場合が多い)
➡️モーダル外をクリックすると閉じる
C. 複数ステップ型モーダル
入力&送信、選択&送信、複数回の削除操作など、
モーダル内で送信操作が1回のクリックで完了しない、
あるいは送信操作を複数回行えるモーダル
➡️モーダル外をクリックしても閉じない
👆このルールは最終的なアウトプットであり、
実際の仕様判断にそのまま使える形です。
ただし、本当に重要なのはこのルールそのものではありません。
ここに至るまでの思考の過程にこそ、再利用できる学びがあります。
そもそも、最初のルールはなぜ破綻しなかったのか
最初に合意した判断基準は、もっと単純なものでした。
- 入力項目がないモーダルは、外クリックで閉じる
- 入力項目があり、かつ単一選択のモーダルも、外クリックで閉じる
- 入力項目があり、または複数選択のモーダルは、外クリックで閉じない
この時点では、仕様として特に大きな問題はありませんでした。
理由は、全員が同じ前提を暗黙に共有していたからです。
ここで言う「単一選択」とは、
選択した瞬間に処理が走り、
モーダルが自動的に閉じる操作
つまり、1回のクリックで完了する画面遷移や切り替えを指していました。
しかし、この前提はどこにも明文化されていませんでした。
「単一選択」という言葉が生んだズレ
問題が顕在化したのは、
モーダル内に選択式の UI が登場したときです。
ラジオボタンのように、選択肢は1つ。
字面だけ見れば、これは「単一選択」です。
しかしその選択は、
- システムの状態を変更し
- データとして保存され
- 明示的な確定を前提とする
ものでした。
ここで初めて、
「単一選択」という言葉が、
操作回数と入力形式という2つの意味を混同していた
ことに気づきます。
「入力項目」という言葉も、実は曖昧だった
さらに問題を深掘りすると、
「入力項目」という言葉自体にも誤解がありました。
当初、私は無意識に、
input 要素(文字入力)があるかどうか
で入力項目を判断していました。
しかしこの定義では、
- 選択による状態変更
- チェックボックス
- 削除操作
- ファイルアップロード
といった操作が、入力項目として扱えなくなります。
本来、形式は関係ありません。
システムや DB の状態を更新する操作は、
すべて入力である
と定義し直さなければ、
ルールは必ずどこかで矛盾します。
第二版ルールと、その限界
この曖昧さを補うため、
次に使った判断軸が「送信ボタンの有無」でした。
- OK や送信ボタンがない場合は閉じてよい
- 送信とキャンセルがある場合は閉じてはいけない
一見すると、より具体的で実用的です。
しかし実際には、
- 送信操作は行われている
- 状態は変わっている
- それでも「OK」「更新」などの送信ボタンが存在しない
というケースが存在しました。
この時点で、
UI コンポーネントを基準にする限界が明確になります。
判断軸を「送信操作」に移す
ここで初めて、
判断の基準を UI の形から切り離すことができました。
重要なのは、
- ボタンがあるかどうか
- 入力欄があるかどうか
ではなく、
ユーザーが送信操作を行っているかどうか
です。
この視点に立つと、
すべてのモーダルを矛盾なく整理できます。
本当に覚えておくべき、抽象的な二分法
最終的に残った、最も抽象的で本質的な考え方はこれです。
「入力途中」に不意にモーダルを閉じてしまうと、悲しくなる。
ここで言う「入力途中」とは、
- 1つ以上の入力(=状態更新)があり
- 送信やキャンセルによって操作を終える必要があり
- ユーザーが思考時間を使っている状態
を指します。
モーダルを開いてから、
操作を終えるまでの全体が「途中」です。
なぜ三分類が必要だったのか
この二分法は非常に強力ですが、
抽象度が高いため、解釈のズレを生みやすい側面もあります。
だからこそ、
実装や仕様判断の現場では、
- 閲覧型
- 単一アクション型
- 複数ステップ型
という三分類に落とし込みました。
三分類は結論ではなく、
二分法を安全に運用するための具体例です。
おわりに
モーダル外クリックの議論は、
UI パターンの話ではありません。
言葉をどう定義し、
どの抽象度で考えるかの問題です。
仕様が破綻したとき、
実装を疑う前に、
まず言葉を疑う。
今回の経験で、
それがいちばん大きな学びでした。



