💬

モーダルをどのように使うべきか

2024/12/12に公開

この記事は MICIN Advent Calendar 2024 の12日目の記事です。
https://adventar.org/calendars/10022
前回は Hiroki Tanaka さんの、「インターンから正社員になった話」 でした。

はじめに

日々アプリケーションを開発する中でモーダルを実装することもありますが、時々「このモーダルの使い方嫌だな…」と思うことがありました。
例えばモーダルの中で別のモーダルを開いたり、モーダルの中で複雑なタスクが始まったり、しかしなぜこれが嫌なのか、自分でも一貫した良い説明ができませんでした。
そこで、そもそもモーダルはいつ使うべきなのか、ベストプラクティスはないのか、ということを調べてみました。

前提:言葉の定義

ここまで「モーダル」という言葉を散々使っていますが、皆さんが「モーダル」と聞くと、以下のようなアプリケーション上の要素を思い浮かべるかも知れません。

modal-dialog

しかし、厳密にはこれ自体はモーダルではありません。
モーダルとは、ユーザーが特定の操作しかできないように制限されている状態のことです。上記スクリーンショットの画面では、投稿内容の入力と各種ボタンの押下だけができるようになっており、このウインドウの周りの灰色がかった部分は押下できなくなっています(あるいは押下するとモーダル状態ではなくなる)。
この状態がモーダルと呼ぶべきものです。表示されているウインドウ自体はモーダルではなく、ダイアログなどと呼ぶのが本来は適切です。

また、モーダルは単に上記のような「状態」を意味するので、ダイアログ上の操作以外もできる場合は「非モーダルダイアログ」、「モードレスダイアログ」、「ノンモーダルダイアログ」などと呼びます(この記事ではモードレスダイアログと呼ぶことにします)。
モードレスダイアログにはいくつかのバリエーションがあり、例えば以下のスクリーンショットのような画面の下部から表示されて一部を覆っている形のものは Material Design では Bottom Sheets と呼ばれています。

bottom-sheets

ただややこしいのですが、 Material Design ではモーダルな Bottom Sheets も定義されており、チーム内でのコミュニケーションではこのあたりの言葉は慎重に使う必要がありそうです。

https://m3.material.io/components/bottom-sheets/overview

余談ですが、今年10月にリリースされた Chakra の v3 では従来の Modal というコンポーネントは Dialog にリネームされています。もしかしたら本来の命名にするという意図なのかもしれません。
https://www.chakra-ui.com/docs/get-started/migration#modal

以降この記事内ではモーダルな状態で表示されるダイアログ自体を「モーダルダイアログ」と表記し、単に「モーダル」と書く場合は他の操作を制限している状態のことを指します。

モーダルダイアログの特徴

前述の通り、モーダルダイアログが表示されている間、ユーザーはモーダルダイアログ内の操作しかできなくなり、何らかの明示的なアクションがないと元の画面に戻ることができません。この基本的な性質から、以下のような特徴があります。

  • 重要な情報を表示し、ユーザーをこの情報に集中させることができる
  • ユーザーに特定の操作を要求することができる
  • 現在のタスクから切り離された新しいタスクが始まったことをユーザーに感じさせることができる

👍 モーダルダイアログを使うべきケース

モーダルダイアログはユーザーの注意を引くための強力なツールではあるものの、必要以上に使いすぎるとユーザーへの負担を増やしてしまいます。
そのためモーダルダイアログを採用するケースは適切に選択する必要があります。どのようなケースで使うべきかはそのアプリの思想やデザインシステムによって多少異なりますが、以下のケースで採用することは一般的に望ましいと言えます。

ユーザーの操作を中断するほどの重要な警告を表示する場合

確実にユーザーに伝える必要がある重要な情報はモーダルダイアログで表示することが効果的です。
例えば、X(旧 Twitter)のようなアプリで投稿内容を入力している最中にその入力フォームを閉じようとする場合には、モーダルダイアログを表示し、これまで入力していた内容が消えてしまうことを確認させることができます。
このようなユーザーの操作によって不可逆な結果が生じるケースでは、モーダルダイアログを採用することが適切です。

good-example

ユーザーの操作を続けるために必須の情報を要求する場合

ユーザーがアプリを使っている最中に、そのタスクを続けるために必要な情報がある場合、それを要求するためにモーダルダイアログを採用することも効果的です。
例えば、 Zenn において MICIN の Publication ページにアクセスすることは未ログイン状態でも可能です。しかしフォローするためにはログインが必要なため、フォローボタンを押すとログインさせるためのモーダルダイアログが表示されます。あるいはモーダルダイアログの中に ID とパスワードを入力させるフォームがあるものもしばしば見ることがあると思います。
このようなケースでは、ユーザーがもともと行っていたメインのタスクから切り離された別のタスクを要求するためにモーダルダイアログは効果的です。

good-example

👎 モーダルダイアログを使うべきではないケース

モーダルダイアログを適切に使わないと、ユーザーに余計な認知負荷を与え、アプリを使いにくく感じさせてしまいます。以下のようなケースではモーダルダイアログを使うべきではありません。

表示する情報がそれほど重要ではない場合

それほど重要ではない情報をモーダルダイアログに表示することで、ユーザーはこの形式に悪い意味で慣れてしまい、注意しなくなってしまいます。結果として本当にユーザーの注目を集めるべきモーダルダイアログがあまり注目されなくなってしまいます。

ユーザーに要求するタスクが複雑な場合

前述の通りモーダルダイアログはユーザーのそれまでのタスクを中断し新しいタスクを要求できますが、新しいタスクをしている間、もともとのタスクの状況をユーザーは把握しておく必要があります。
そのため新しいタスクが複雑すぎると、ユーザーの認知負荷を増やしてしまいます。

ユーザーが追加の情報を参照する必要がある場合

モーダルダイアログが表示されている間、ユーザーはこのダイアログを閉じない限り他の操作をできません。そのため、モーダルダイアログの外にある情報を参照する必要がある場合は、モーダルダイアログを使うべきではありません。
例えばメーラーで新規メールを作成する場合、新規メール作成のためのモーダルダイアログを採用してしまうと、その間にユーザーが他のメールを参照したいと思っても、モーダルな状態ではそれができません。

要議論:ネストされたモーダルダイアログを許容するか

個人的にはネストされたモーダルダイアログはアンチパターンの1つだと思っていたのですが、 Primer Design System には以下のような記述があります。

Nested dialogs
It is acceptable to have up to two nested dialogs as long as the dialog is implemented with expected focus management behavior. Upon closing the second nested dialog, focus should return to the trigger control within the first dialog. When the two stacked dialogs are open, pressing Esc should only close the top-level dialog. When one clicks outside of the second dialog with a mouse, only the second dialog should close.

以下のようなフォーカスの挙動を満たしてモーダルダイアログが実装されていれば、2つのネストされたモーダルダイアログは許容できるということになります。

  • 2つ目のモーダルダイアログを閉じるとき、1つ目のモーダルダイアログの中にある2つ目のモーダルダイアログのトリガーにフォーカスを戻す
  • 2つのモーダルダイアログが表示されているときに Esc キーを押下した場合は上のモーダルダイアログだけを閉じる
  • 2つ目のモーダルダイアログの外側をクリックした場合は2つ目のモーダルダイアログだけを閉じる

一方、 Apple の Human Interface Guidelines では以下のように記述されています。

別のモーダルビューを表示する前に、ユーザがモーダルビューを閉じるようにする。 同時に複数のモーダルビューを表示できるようにすると見た目が雑然としがちで、散らかってまとまりのない印象のアプリになりかねません。ユーザは、操作する上でモーダルビューが表示される前の画面内容を覚えている必要があるので、複数のビューを表示するとユーザの認知負荷が増えます。モーダルビューが別のモーダルビューに重なって前の画面内容が見えなくなるような場合は、特にそうです。ほかのモーダルビューを含むほかのコンテンツのどれかにアラートが表示されることはあるかもしれませんが、同時に複数のアラートが表示される状況には絶対にならないようにしてください。

やはり個人的には後者の思想に基づいて、モーダルダイアログはネストされるべきではないと思いますが、いずれにせよこのあたりはプロダクトによってチーム内で認識を統一することが重要でしょう。

代わりにどうするべきか

モーダルダイアログを使うべきではないケースでは、以下のような代替手段を考えるべきです。

  • 要求するタスクが複雑な場合、1つのページとして切り出す
  • モードレスダイアログを検討する
  • 表示したい情報の重要度に応じて適切なコンポーネントを検討する

ちなみに Material UI では情報の重要度に応じて適切なコンポーネントを示しています。これらを参考に検討すると良さそうです。
https://m3.material.io/components/dialogs/guidelines#822de58f-0391-483c-a9eb-8ee52c072a78

モーダルダイアログのベストプラクティス

モーダルダイアログを使うべきケースと使うべきではないケースをここまで書いてきましたが、モーダルダイアログ自体のベストプラクティスをいくつか示します。
基本的にはモーダルダイアログによってユーザーの認知負荷を増やさないようにするためのベストプラクティスです。

目的を明確にする

  • 複数の目的を1つのモーダルダイアログに持たせず、1つの目的に集中させる
  • 目的を明確にするために、モーダルダイアログ内の見出し、本文、ボタンのテキストに曖昧な表現を使わない
    • 質問の文言は「hogehoge しますか?」という形にし、ボタンのテキストは「hogehoge」または「hogehoge する」にする

タスクはシンプルにする

  • 複数の段階を踏むような複雑なタスクは避ける
  • シングルカラムレイアウトが望ましい
    • サイドナビゲーションなどがなく、コンテンツが縦1列に並んでいるレイアウト

理解しやすいボタンにする

  • モーダルダイアログ内に配置するボタンは最大で2つまでにする
    • ボタンが2つの場合、承認とキャンセルのボタンだけにする
    • ボタンが1つの場合、承認のボタンだけにする
  • Windows と Mac では承認ボタンとキャンセルボタンの位置が逆であるため、モーダルダイアログの閉じるボタンとキャンセルボタンの位置は揃えるのが望ましい
    • そのため、ユーザーの利用環境を把握しておく必要がある
Windows Mac
modal-dialog-in-windows modal-dialog-in-mac

簡単に閉じることができるようにする

  • モーダルダイアログは元のタスクに割り込んで表示されているものであるため、ユーザーが簡単に元のタスクに戻れるようにしておく
  • 簡単に閉じる方法としては、ダイアログの左上の閉じるボタン、Esc キー、モーダルをダイアログの外側をクリック、などがあるが、どの画面でどの方法を採用するかは検討して挙動を統一する

モヤモヤの原因

これらの使うべきケース、使わないべきケース、ベストプラクティスを踏まえると、感じていたモヤモヤの原因はモーダルダイアログ内のタスクをシンプルにできていないことに起因していると考えられます。

モーダルダイアログの中で別のモーダルダイアログを開くケース

このケースでは、1つ目のモーダルダイアログが元のタスクからユーザーの意識を奪い、2つ目のモーダルダイアログが更にそこから意識を奪う、ということが起きてしまいます。このような意識の遷移が多くなることでユーザーの認知負荷を増やしてしまうことにモヤモヤを感じていました。

モーダルダイアログの中で複雑なタスクが始まるケース

このケースでは元のタスクからユーザーの意識を奪い、モーダルダイアログ内でいくつかの段階を踏むような複雑なタスクがユーザーの意識を長時間独占してしまうことになります。これもまたやはりユーザーの認知負荷を増やしてしまいます。

Spindle

モヤモヤの原因を考えていたところ、Ameba のデザインシステムである Spindle にモーダルダイアログの表示パターンごとのユーザーの意識の遷移を可視化した図が示されており、これが非常にわかりやすかったです。

https://spindle.ameba.design/components/modal/

まとめ

端的に言ってしまうと、モーダルダイアログはとにかくシンプルにわかりやすく、本当に重要なときにだけ使え!ということに尽きると思います。しかしこれを実現するためには、まずこれをチーム内のスタートラインとして共有し、同じ認識を持つことから始まるのかなと感じました。
ひいてはモーダルダイアログに限らず、アプリケーション全体のデザインシステムを構築し共有することで、一貫性のあるアプリケーションができるのだろうと思います。

参考 URL


MICINではメンバーを大募集しています。
「とりあえず話を聞いてみたい」でも大歓迎ですので、お気軽にご応募ください!
https://recruit.micin.jp/

株式会社MICIN

Discussion