フォームの定石:すべての入力欄は問いである
フォームとは、インターフェースが提示をやめて問いかけを始める瞬間です。すべての入力欄は、本当は別のことをしたい人に向けられた質問であり、だからこそ不要な入力欄はひとつ残らず押しつけであり、分かりにくい入力欄は小さな裏切りとなります。フォームの技芸は、頭のなかに収まるだけの定石に還元できます。質問は最小限に、1カラムで、ラベルは常に見えるように。答えは人が自然に書いたままの形で受け取る。バリデーションはキーを打っている最中ではなく、ユーザーが一つの思考を終えたときに走らせる。エラーは直し方が分かる文言で書く。そして、いかなる状況でもユーザーが入力した内容を捨てない。世に出回るフォームの摩擦は、そのほとんどがこのいずれかへの違反です。 {.answer-block}
TL;DR
- フォームは会話です。人が尋ねるように尋ねましょう:質問は可能な限り少なく、順序のある1カラムに、トピックごとにまとめる。そして、すべての入力欄を「尋ねることの代償」に照らして正当化する。
- レイアウトはすでに決着がついています:シングルカラム、ラベルは入力欄の上、フィールド幅は答えの長さを示唆する。マルチカラムのフォームやフローティングラベルの小技は、本当の理解しやすさを、洗練されているという思い込みと引き換えにしています。
- 答えは人が差し出したままの形で受け取ること。 余計なスペースは取り除き、電話番号はどんな書式でも受け付け、3つのボックスに割らずに1つの欄のまま保つ。正規化はソフトウェアの仕事であって、ユーザーの仕事ではありません。
- バリデーションはキーストロークではなくblur(フォーカスが外れたとき)で走らせ、エラーは教える文章で書く:何が問題で、どう直せばよいのかを、該当する入力欄のすぐそばに。
- ユーザーの入力は神聖なものです。 送信に失敗してフォームが空になる、あるいは理由を告げないまま無効化されたボタンは、協力する気のあった参加者を「かつての参加者」に変えてしまいます。
なぜすべての入力欄は問いなのか
フォームを面接の記録だと考えると、その品質は一目で読み取れるようになります。有能な面接官が、習慣だからという理由でファックス番号を尋ねるでしょうか。理由も説明せずに生年月日を要求するでしょうか。メールアドレスを綴っている途中で遮って、それは無効だと宣言するでしょうか。郵便番号にスペースが入っていたというだけで、あなたが話したことをすべて忘れるでしょうか。いずれにも、実際に出荷されているフォームでの対応物が存在します。そしてユーザーは、それを面接官に対するのとまったく同じように——つまり無礼として——受け取ります。
この捉え方は、レイアウトやスタイリングのすべてに先立つ、最初にして最も重要なルールも導きます。すべての入力欄は、尋ねることの代償に見合うだけの存在理由を示さなければならない。 質問が1つ増えるごとに離脱は増えます。集めた答えは、保存し、保護し、責任を負うべきデータになります。フォーム設計で最も強力な一手は削除です。取り除いた入力欄は、そこに施せたはずのどんな磨き上げよりも大きな成果を出します。定番の証拠はExpediaの事例です。予約フォームから「Company(会社名)」という任意項目を1つ削除しただけで、年間およそ1,200万ドルの価値があったと報告されています。顧客がそこに取引銀行の名前を入力し、住所照合に失敗していたのです。1つの入力欄を正直に問い詰めることが、どんなリデザインにも勝りました。「任意」は正当化にはなりません。押しつけの度合いが小さいだけで、やはり押しつけです。取引を完了するために必要なものだけを尋ね、まれにある任意項目には任意と明示し、それ以外はすべて後回しにしましょう——関係がそれを尋ねるに値するようになってからで十分です。(反対の流儀は、代わりに必須項目すべてにアスタリスクを付けます。ほとんどが必須であれば、アスタリスクはただの壁紙です。)
レイアウトのルール
フォームのレイアウトは、デザインのなかでも証拠がほぼ決着している数少ない一角です。だからこそ、そこから逸脱することはユーザーに逆らう選択になります。
1カラムにする。 フォームは質問の連なりであり、シングルカラムはその連なりを曖昧さなく示します。答える、下に進む、終わる。マルチカラムのレイアウトは、行ごとに読む順序の判断——横か、下か——を強い、ユーザーの解決の仕方は一定しません。結果として、見ることすらなかった入力欄を飛ばしてしまいます。最もよく知られたアイトラッキングの比較では、同じ項目をシングルカラムに並べたほうが、2列に分けた場合より約15秒早く完了しました。例外は、1つの答えとして読める真の複合項目です。市区町村/都道府県/郵便番号を1行に、日付を3つのパーツに。これらは3つの入力欄をまとった1つの質問であって、3つの質問ではありません。
ラベルは入力欄の上に、常に見えるように。 入力欄の横に置いたラベルは、視線の移動をぎざぎざにします。入力欄の中に置いたラベル(プレースホルダーをラベル代わりにするやり方)は、ユーザーが入力を始めた瞬間に消えます——まさにそれが必要になる瞬間にです。長いフォームの途中では、埋まった入力欄はどれも「これは何だったか」という中身の見えない箱になります。アニメーションによる折衷案であるフローティングラベルは、フォーカス後も生き残りはしますが、キャプションほどの大きさに縮み、空の入力欄が埋まっているように見えてしまいます。同じ取引のもう少し穏やかな版であり、支払う代償はやはり理解しやすさです。プレースホルダーは書式のヒント(「[email protected]」)のためのものであって、質問そのもののためではありません。
フィールド幅は情報です。 住所欄と同じ幅の郵便番号欄は、答えの形について嘘をついています。入力欄を想定される内容に合わせて——郵便番号は短く、住所は長く——サイズを決めることは、グルーピングを空白で表現することと同じ技芸です。ジオメトリが静かに意味を伝えているのです。
トピックごとにまとめ、まとめは余白に任せる。 連絡先、配送先、支払い——関連する質問のかたまりと、その間にはっきりした継ぎ目を置きます。継ぎ目を作るのは罫線やボックスではなく、余白です。3つの小さなトピックとして読めるフォームは、同じ項目をのっぺりした一枚板として並べたものより、心理的に小さく感じられます。
入力のルール
入力設計のテーマは一文に尽きます。正規化はソフトウェアの仕事である。 書式を整える負担がどれだけあろうと、それを担うのは機械です。気にしているのは機械のほうなのですから。
- 雑な答えを受け入れる。 空白は取り除きましょう。オートコンプリートされたメールアドレスの末尾に付いた余分なスペースは、そんな権利もないのに数えきれないログインを失敗させてきました。電話番号はハイフン、ドット、スペース、括弧つき、あるいは区切りなしでも受け取ります。カード番号は隙間があってもなくても受け付けます。解析できるなら解析する。
5558675309が欲しかったからといって555 867 5309を拒否するのは、あなたの文字列整形コードをユーザーに手で実行させているのと同じです。 - ユーザーが1つのものだと考えているものを分割しない。 3つのボックスに割った電話番号、3つのドロップダウンに割った日付、自前のフォーカス移動を仕込んだ6つの1文字セルの確認コード——どれも1つの心のなかの答えをナビゲーションのパズルに変え、たいていはペーストを壊します。ペーストこそ、ユーザーが持つ最も効率的な入力手段なのに。(レイアウトのルールにあった複合項目の例外は生きています。日付を3つのテキスト入力に分けるのは構いません。罪はドロップダウンという儀式と、奪われるフォーカスであって、隣り合っていること自体ではありません。コードについては、
autocomplete="one-time-code"を付けた1つの入力欄が長持ちする答えです。) - 正しいキーボードを呼び出す。 タッチデバイスでは、
type="email"やinputmode="numeric"といった指定が、そのために設計されたキーボードでアドレスを打てるか、記号レイヤーをかき分けて@を探すかの分かれ目になります。コストは属性1つです。 - ブラウザに手伝わせる。 正しい
autocompleteトークンは、12項目のチェックアウトを、再訪ユーザーにとっての2タップに変えます。住所や支払いの入力欄でオートフィルを無効にするのは——たいていは実際には行われなかったセキュリティレビューから受け継いだ迷信ですが——フォームで使える最大の高速化手段を捨てる行為です。 - 指が着地する場所で受け止める。 入力欄、そのボタン、その他タップできるものはすべて、プラットフォームの最小タッチターゲット——iOSでは44pt、Androidでは48dp——を守ります。親指が確実に当てられないコンパクトで優美な入力欄は、スマートフォンの衣装をまとったデスクトップのフォームです。
キーボードとオートフィルのルールは、あわせても属性数個で済みます。
<input type="tel" autocomplete="tel"> <!-- phone keypad, autofilled -->
<input inputmode="numeric" autocomplete="one-time-code"> <!-- digit pad, code autofills -->
バリデーションのルール
フォームが最も敵対的になりやすいのはバリデーションのタイミングであり、ルールは単純です。ユーザーが一つの思考を終えたときに応答する。 キーを打つたびに走らせるということは、メールアドレスを4文字打った人に向かって「無効なメールアドレスです!」と叫ぶことであり、文が終わる前に文章を批評するようなものです。反対の流派は送信時にのみ検証します。こちらにも真面目な擁護者がいます。GOV.UKのデザインシステムはまさにこれを採用し、送信とページ上部のエラーサマリーを組み合わせています。サマリーはスクリーンリーダーに読み上げさせられますし、キーボードユーザーには修正を始める場所が1か所にまとまるからです。アクセシビリティが制約条件になるサービスに合わせて調整された、筋の通った立場だと言えます。それでも、たいていのプロダクトのフォームについては私はblur派です。ユーザーが入力欄を書き終え、次に進んだところで、思考と思考の継ぎ目に、まだ考えが温かいうちにフィードバックが返るからです。(ひとつ補足があります。いったん無効と判定された入力欄は、キーストロークごとに再検証してよいでしょう。そうすれば、修正が入った瞬間に赤い状態が消え、1項目分遅れて追いかけてくることがありません。)
エラーの文章も同じ会話のテストに従います。エラーは判決ではなく、修理の指示です。「入力が無効です」はテストに落ちます——どう無効なのでしょうか。「このメールアドレスには @ がありません」なら合格です。(そして指示は、実際のルールに照らして正しくなければなりません。カード番号は12桁から19桁まで正当に存在するので、「16桁で入力してください」はエラーメッセージではなく、Amexの利用者を全員はじくバリデーションのバグです。)メッセージは、該当する入力欄のところに、テキストで置きます。色だけでは色覚に違いのあるユーザーを排除しますし、テキストは何も描画しない読み手に見える唯一のチャネルだからです。そのうえで、aria-describedby でプログラム的に入力欄と結び付けます。そうすれば支援技術はエラーを入力欄と一緒に読み上げ、画面上に取り残すことがありません。トーンは事実に徹しましょう。フォームの仕事はユーザーを最後まで届けることであって、非を裁くことではありません。ルール全体は、この2つを並べれば分かります。
<!-- before: a verdict, visually nearby, programmatically stranded -->
<label for="email">Email</label>
<input id="email" type="email">
<span class="error">Invalid input</span>
<!-- after: a repair instruction, announced with its field -->
<label for="email">Email</label>
<input id="email" type="email"
aria-invalid="true" aria-describedby="email-err">
<span id="email-err">This email address is missing its @</span>
構造に関する2つのルールが、この組を締めくくります。バリデーションの手段として送信ボタンを無効化しない。 説明のない死んだボタンはパズルであり、ユーザーの次の一手は立ち去ることです。送信させたうえで、何に注意が必要なのかを正確に示しましょう。(二重課金を防ぐために送信処理中だけ無効化するのは別の話です。あれは判定ではなく状態です。)そして定石のなかで最も深い法則。送信に失敗しても、ユーザーの入力は一打ちも失われない。 エラーで内容が消えるフォームは、人が何分もかけた労力を、本人の目の前で燃やしたのです。どんな見た目の洗練も、そこからは回復させてくれません。
チェックリストとしての定石
以上のすべてを実務の形にしたものが、次の表です。出荷前のどんなフォームにも当ててみてください。
| ルール | 防げる違反 |
|---|---|
| すべての入力欄を正当化する、さもなくば削除する | 好奇心で尋ねた質問が買い込んだ離脱 |
| 1カラム、複合項目のみ例外 | 読む順序が曖昧なことによる入力漏れ |
| ラベルは上に、常に見えるように | フォーム途中の中身の見えない箱、ラベル代わりのプレースホルダー |
| フィールド幅が答えの形と一致する | 想定入力についてジオメトリがつく嘘 |
| トピックごとにまとめ、継ぎ目は余白で | のっぺりした一枚板 |
| 解析できる書式はすべて受け入れる | 整形コードをユーザーに手で実行させること |
| 1つの答えに1つの入力欄(複合項目は例外) | 壊れたペースト、フォーカス移動のパズル |
| 正しいキーボードとautocomplete | タッチでの記号探し、2タップで済むはずの12タップ |
| プラットフォームのタッチターゲット(44pt/48dp) | 親指が当てられない優美な入力欄 |
| blurで検証し、エラーは入力欄のそばで教え、ariaで結び付ける | 打鍵中の叱責、支援技術から切り離されたエラー |
| バリデーションのために送信を無効化しない | 死んだボタンのパズル |
| 入力は失敗を生き延びる | 空になったフォームと、二度と戻らないユーザー |
デザインシステムのなかでは、これらはフォームコンポーネント自体に固められます——ラベルのスロットを上に、エラーのスロットを下に備え、バリデーションのタイミングを組み込んだテキストフィールド。そうすれば定石は既定で守られ、そこから外れるほうに労力がかかるようになります。これはモーショントークンとまったく同じシステム化の論法です。決定は一度だけエンコードするか、さもなければ機能ごとに蒸し返すかです。
よくある質問
フォームは1カラムにすべきですか、2カラムにすべきですか?
1カラムです。シングルカラムは答える順序を曖昧さなく示し、完了までの時間も測れるほど短くなります。マルチカラムのレイアウトでは、ユーザーが読む順序を一定しない形で解決するため、入力漏れが起こります。例外は複合的な答え——市区町村/都道府県/郵便番号——で、これは隣り合う入力欄で表現された1つの質問です。
フォームのバリデーションはいつ走らせるべきですか?
blur時、つまりユーザーが入力欄を離れたときです。キーストロークごとではなく、たいていのプロダクトのフォームでは送信時までためておくのでもありません。キーストロークでの検証は書きかけの答えを批評します。送信時のみの検証は、すべての失敗を一度に突きつけます。ただし、スクリーンリーダーへの読み上げが制約条件になる場面では、GOV.UKの送信時エラーサマリーが正解です。すでに無効と表示されている入力欄は、キーストロークごとに再確認してよいでしょう。修正した瞬間にエラーが消えます。
プレースホルダーのテキストを入力欄のラベルとして使ってもよいですか?
いいえ。ラベル代わりのプレースホルダーは、ユーザーが入力を始めた瞬間、つまり質問を思い出したいまさにその瞬間に消えてしまい、確認のときにはすべての埋まった入力欄がラベルのないデータになります。ラベルは入力欄の上に見える形で置き、プレースホルダーは書式の例のために取っておきましょう。
フォームが有効になるまで送信ボタンは無効にしておくべきですか?
いいえ。説明のない無効化された送信ボタンは、ユーザーが自分で原因を突き止めなければならない行き止まりです。有効なままにしておき、送信時に、未解決の入力欄それぞれのそばに具体的で手ほどきになるエラーを出しましょう——そのとき、すでに入力された内容はすべて保持したままで。