最適なフォームの作成

モバイルでのフォーム入力は大変な作業です。最高のフォームとは、入力内容を最小限にしたフォームです。良いフォームは意味のある入力タイプを提供します。ユーザーの入力タイプに応じて表示するキーボードを変え、シーンによってはユーザーがカレンダー上の日付を選択できるようにします。ユーザーへの通知も必要です。検証ツールを使用して、フォームを送信する前に必要なことをユーザーに伝えましょう。

効率的なフォームを設計する

効率的なフォームを設計するには、繰り返しのアクションを避けて、必要な情報のみを要求します。さらにマルチパート フォームのどの段階まで入力しているのかを示すことによって、ユーザーをガイドします

TL;DR

  • フィールドに既存のデータをあらかじめ設定し、自動入力を有効にします。
  • ユーザーがマルチ パート フォームを活用できるよう、明確にラベル付けされたプログレス バーを使用します。
  • カレンダーを表示することで、ユーザーがサイトを離れてスマートフォンのカレンダー アプリを開く手間を省きます。

繰り返しのアクションとフィールドを最小限に抑える

マルチパート フォームに進捗を表示
Progressive.com のウェブサイトでは、ユーザーは最初に郵便番号の入力を要求されます。その内容が、フォームの次の部分に事前に設定されます。

フォームに繰り返しのアクションがないことを確認し、フィールドの使用は必要最低限にとどめてください。自動入力を活用すると、あらかじめデータが設定されるため、ユーザーは簡単にフォームの入力を完了できます。

取得済みの情報を事前入力することで、ユーザーがその情報を入力する手間を省ける箇所がないか探します。 たとえば、ユーザーによって入力された最新の配送先住所を事前に設定します。

ユーザーに進捗状況を示す

マルチパート フォームに進捗を表示
ユーザーがマルチパート フォームを活用できるよう、明確にラベル付けされたプログレス バーを使用します。

プログレス バーとメニューを使い、マルチステップのフォームやプロセスおける全体的な進捗状況を正確に伝える必要があります。

前のステップで不相応に複雑なフォームを配置した場合、ユーザーは全体のプロセスを終える前に、サイトを離れる可能性が高くなります。

日付を選択するためのカレンダーを表示

使いやすいカレンダーを使用するホテル予約サイト
ホテル予約サイトでは、日付を簡単に選ぶためのカレンダー ウィジェットを使用しています。

ユーザーは旅行の予定や日程をスケジュールするときに、より多くのコンテキストを必要とする傾向があります。ユーザーがカレンダーをチェックするためにサイトを離れることを防止し、操作を容易にするために、開始日と終了日を選択するための明確なラベルがついたカレンダーを表示します。

最適な入力タイプを選ぶ

正しい入力タイプを使用して情報の入力を効率化します。ユーザーは、電話番号を入力する際に自動的に数字キーパッドが表示されたり、入力後に自動的に次のフィールドへ遷移したりするウェブサイトを好みます。

できるだけ無駄なタップ操作を省いたフォームにしましょう。

TL;DR

  • データを簡単に入力できるよう、最適な入力タイプを選択します。
  • datalist 要素を使用して、ユーザーの入力時に候補を表示します。

HTML5 入力タイプ

HTML5 では多くの新しい入力タイプが導入されています。これらの新しい入力タイプは、画面上のキーボードとして表示するキーボード レイアウトの種類をブラウザに伝えます。

ユーザーはキーボードを変更しなくても、入力タイプに合った適切なキーが表示されるため、必要な情報をより簡単に入力することができます。

入力 type
url
URL を入力します。これは有効な URI スキームで始まる必要があります。たとえば http://ftp:// または mailto:mailto: などです。
tel
電話番号を入力します。tel では、特定の構文に従った入力は必須ではありません。 したがって、特定の形式で入力されるようにしたい場合は、pattern 属性を使用します。
email
メールアドレスを入力します。@ がデフォルトでキーボードに表示されます。 multiple 属性を追加すると、複数のメールアドレスが入力可能になります。
search
プラットフォームの検索フィールドとスタイルを合わせたテキスト入力フィールドです。
number
数字を入力します。有理整数または浮動小数点値です。
range
数字を入力しますが、number の入力タイプとは違い、数値自体は重要ではありません。 これは、スライダ コントロールとしてユーザーに表示されます。
datetime-local
日付と時刻の値を入力します。ここで提供されるタイムゾーンは現地時間です。
date
タイムゾーンなしで日付(のみ)を入力します。
time
タイムゾーンなしで時間(のみ)を入力します。
week
タイムゾーンなしで週(のみ)を入力します。
month
タイムゾーンなしで月(のみ)を入力します。
color
色を選択します。

警告: 入力タイプを選択する際は、ローカライズについても考慮してください。地域によっては、セパレータにカンマ(,)ではなく、ドット(.)を使用することもあります。

データリストで入力中に候補を表示する

datalist 要素は入力タイプではなく、フォーム フィールドに関連付けられた入力値の候補リストです。 これによってブラウザは、ユーザーの入力時に、オートコンプリート機能で入力候補を表示できます。 ユーザーが値を見つけるために長いリストをスキャンしなければならず、さらに入力内容が限定される選択要素とは異なり、datalist 要素ではユーザーの入力に応じて候補を表示できます。

<label for="frmFavChocolate">Favorite Type of Chocolate</label>
<input type="text" name="fav-choc" id="frmFavChocolate" list="chocType">
<datalist id="chocType">
  <option value="white">
  <option value="milk">
  <option value="dark">
</datalist>

サンプルを見る

注: datalist の値は候補として表示されますが、ユーザーは提示された内容以外も入力できます。

入力項目に適切なラベルと名前を付ける

モバイルでのフォーム入力は大変な作業です。最高のフォームとは、入力内容を最小限にしたフォームです。良いフォームは意味のある入力タイプを提供します。ユーザーの入力タイプに応じて表示するキーボードを変え、シーンによってはユーザーがカレンダー上の日付を選択できるようにします。ユーザーへの通知も必要です。検証ツールを使用して、フォームを送信する前に必要なことをユーザーに伝えましょう。

TL;DR

  • フォームの入力項目には必ず label を使用して、フォーカスが当たってる項目が見えるようにします。
  • placeholder を使用して、期待する入力する内容を例示します。
  • ブラウザでフォームを自動補完するために、要素に既定の name を使用し、 autocomplete 属性を含めます。

ラベルの重要性

label 要素は、フォーム要素で必要な情報をユーザに伝えます。 各 labellabel 要素の内部に配置されることによって、あるいは 「for」属性を使用することによって、入力要素と関連付けられます。要素を形成するためにラベルを適用すると、タッチ ターゲットのサイズを改善するのに役立ちます。ユーザーがラベルまたは入力要素のいずれかをタッチすること、入力項目にフォーカスが当たります。

<label for="frmAddressS">Address</label>
<input type="text" name="ship-address" required id="frmAddressS"
  placeholder="123 Any Street" autocomplete="shipping street-address">

サンプルを見る

ラベルのサイズと配置

ラベルと入力項目は、押しやすいように十分大きくなければなりません。縦向きのビューポートでは、フィールド ラベルは入力要素の上にあり、横向きのビューポートでは横に配置されます。フィールド ラベルと対応する入力ボックスが同時に表示されることを確認してください。カスタム スクロール ハンドラに注意してください。入力要素をページの先頭にスクロールしてラベルを隠したり、入力要素の下に配置されたラベルが仮想キーボードによって覆われることがあります。

プレースホルダの使用

プレースホルダ属性は、期待される入力内容をユーザーに示唆します。通常、ユーザーが入力を開始するまで、明るい色のテキストで値が表示されます。

<input type="text" placeholder="MM-YYYY" ...>

警告: プレースホルダは、ユーザーが要素に入力を始めるとすぐに消えるため、ラベルの代わりにはなりません。プレースホルダは、入力すべき内容とその形式をユーザーに示すためのヒントとして使用してください。

オートコンプリートを有効にするためにメタデータを使用

ウェブ サイトで、名前、メールアドレス、その他の頻繁に使用されるフィールドに自動的に入力することによって、ユーザーの時間を節約します。これは潜在的な入力ミスを減らすのに役立ち、特に仮想キーボードや小さな端末で便利です。

ブラウザではヒューリスティクスを多用し、ユーザーが以前に指定したデータに基づいて自動入力が可能な項目を判断します。また、そのための情報として、各入力要素の name 属性と autocomplete 属性をブラウザに伝えることができます。

注: Chrome では、自動入力を有効にするために、input 要素を <form> タグで囲む必要があります。 form タグで囲まれていない場合、Chrome によって候補は提示されますが、フォーム入力は完了しません

たとえば、ユーザー名、電子メールアドレス、電話番号を使用してフォームをオートコンプリートするようブラウザに伝えるには、次のようにします。

<label for="frmNameA">Name</label>
<input type="text" name="name" id="frmNameA"
  placeholder="Full name" required autocomplete="name">

<label for="frmEmailA">Email</label>
<input type="email" name="email" id="frmEmailA"
  placeholder="name@example.com" required autocomplete="email">

<label for="frmEmailC">Confirm Email</label>
<input type="email" name="emailC" id="frmEmailC"
  placeholder="name@example.com" required autocomplete="email">

<label for="frmPhoneNumA">Phone</label>
<input type="tel" name="phone" id="frmPhoneNumA"
  placeholder="+1-555-555-1212" required autocomplete="tel">

サンプルを見る

推奨入力 name および autocomplete 属性値

autocomplete 属性値は現在の WHATWG HTML Standard の一部です。一般に使用される autocomplete 属性は以下のとおりです。

autocomplete 属性は shippinggiven-name または billingstreet-address などのセクション名を伴うことができます。ブラウザは、異なるセクションを継続的なフォームとしてではなく、個別にオートコンプリートします。

コンテンツの種類 name 属性 autocomplete 属性
名前 name fname mname lname
  • name(姓名)
  • given-name(名)
  • additional-name(ミドルネーム)
  • family-name(姓)
メールアドレス email email
住所 address city region province state zip zip2 postal country
  • アドレスを 1 つ入力:
    • street-address
  • アドレスを 2 つ入力:
    • address-line1
    • address-line2
  • address-level1(州または県)
  • address-level2(市)
  • postal-code(郵便番号)
  • country
電話番号 phone mobile country-code area-code exchange suffix ext tel
クレジットカード ccname cardnumber cvc ccmonth ccyear exp-date card-type
  • cc-name
  • cc-number
  • cc-csc
  • cc-exp-month
  • cc-exp-year
  • cc-exp
  • cc-type
ユーザー名 username
  • username
パスワード password
  • current-password(サインイン フォーム)
  • new-password(サインアップおよびパスワード変更フォーム)

注: street-address のみ、または address-line1address-line2 の両方を使用します。 address-level1address-level2 は、住所形式に必要な場合にのみ使用します。

autofocus 属性

Google のホームページなどのフォームで、ユーザーが特定のフィールドだけを入力する場合などは、autofocus 属性を追加できます。設定した場合、デスクトップ ブラウザはすぐに入力フォールドにフォーカスを移動し、ユーザーが簡単にすばやくフォームの使用を開始できるようにします。モバイル ブラウザは autofocus 属性を無視し、キーボードがランダムに表示されるのを防止します。

オートフォーカス属性を使用する際には注意してください。キーボード フォーカスを妨げ、ナビゲーションにバックスペース文字が使用されるのを潜在的に防止するためです。

<input type="text" autofocus ...>

リアルタイム検証のサポート

リアルタイム データ検証は、データを明確に保つだけではなく、ユーザー エクスペリエンスを改善するのにも役立ちます。最近のブラウザにはリアルタイム データ検証の実施に役立つ複数のツールが組み込まれており、ユーザーが無効なフォームを送信するのを回避することができます。フォームが正しく記入されたかどうかを示すには、視覚的な指示を使用する必要があります。

TL;DR

  • patternrequiredminmax などのブラウザに組み込まれた検証属性を活用します。
  • より複雑な検証要件には、JavaScript と Constraints Validation API を使用します。
  • リアルタイムで検証エラーを表示し、ユーザーが無効なフォームを送信しようとした際は、修正が必要な項目をすべて表示します。

入力内容の検証に使用する属性

pattern 属性

pattern 属性で、入力項目の検証に使用する正規表現を指定します。 たとえば、米国の郵便番号(5 桁の数字。そのあとにダッシュと 4 桁の数字が続く場合もある)を検証するには、pattern を次のように指定します。

<input type="text" pattern="^\d{5,6}(?:[-\s]\d{4})?$" ...>
一般的な正規表現パターン
正規表現
住所 [a-zA-Z\d\s\-\,\#\.\+]+
郵便番号(US) ^\d{5,6}(?:[-\s]\d{4})?$
IP アドレス(IPv4) ^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$
IP アドレス(IPv6) ^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$
IP アドレス(両方) ^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$
クレジット カード番号 ^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|6(?:011|5[0-9]{2})[0-9]{12}|(?:2131|1800|35\d{3})\d{11})$
社会保障番号 ^\d{3}-\d{2}-\d{4}$
北米電話番号 ^(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:\(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*\)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)?([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?$

required 属性

required 属性が存在する場合は、フォームを送信する前に、フィールドに値が含まれている必要があります。 たとえば、郵便番号を必須にするには、単純に required 属性を追加します。

<input type="text" required pattern="^\d{5,6}(?:[-\s]\d{4})?$" ...>

minmax および step 属性

数値や範囲のような数値入力タイプ、および日付や時刻の入力については、最小値と最大値を指定できるほか、スライダまたはスピンボールで調整されるときの増減刻み値を設定することができます。たとえば、靴のサイズの入力については、最小サイズを 1、最大サイズを 13、刻み値を 0.5 に設定します。

<input type="number" min="1" max="13" step="0.5" ...>

maxlength 属性

maxlength 属性を使用すると、入力またはテキストボックスの最大長を指定できます。この属性は、ユーザが入力できる情報の長さを制限する場合に便利です。たとえば、ファイル名の長さを 12 文字に制限する場合は、次のようにします。

<input type="text" id="83filename" maxlength="12" ...>

minlength 属性

minlength 属性を使用すると、入力またはテキストボックスの最小長を指定できます。この属性は、ユーザが入力する必要のある最小長を指定する場合に便利です。たとえば、ファイル名の最小長を 8 文字と指定する場合は、次のようにします。

<input type="text" id="83filename" minlength="8" ...>

novalidate 属性

フォームに無効な入力が含まれている場合でも、フォームの送信をユーザに許可したい場合があります。 その場合は、フォーム要素、または個々の入力フィールドに novalidate 属性を追加します。 その場合、すべての疑似クラスと JavaScript API では、依然としてフォームが正しいかどうかをチェックできます。

<form role="form" novalidate>
  <label for="inpEmail">メールアドレス</label>
  <input type="email" ...>
</form>

ポイント: データの一貫性とセキュリティを確保するために、クライアント側の入力検証においても、必ずサーバ側でデータを検証を行うことが重要です。

JavaScript を使用した複雑なリアルタイム検証

組み込みの検証機能と正規表現で十分でない場合は、Constraint Validation API を使用できます。これは独自の検証を制御するための強力なツールです。この API を使用すると、独自のエラーの設定や、要素が有効かどうかのチェックなどの処理を実行でき、要素が無効である理由を判定できます。

制約の検証
setCustomValidity() カスタム検証メッセージ、および ValidityState オブジェクトの customError プロパティを true に設定します。
validationMessage 入力内容が検証テストに通らなかった理由を示す文字列を返します。
checkValidity() 要素がすべての制約を満たす場合は true を返し、それ以外の場合は false を返します。チェックで false が返されたときにページがどのように応答するかを決めるのは、デベロッパーの作業です。
reportValidity() 要素がすべての制約を満たす場合は true を返し、それ以外の場合は false を返します。ページから false が返される場合は、制約上の問題点がユーザーに報告されます。
validity 要素の有効性を表す ValidityState オブジェクトを返します。

カスタム検証メッセージの設定

フィールドの検証でエラーが出た場合は、setCustomValidity() を使用してフィールドを無効とマークし、フィールドがエラーになった理由を説明します。 たとえば、サインアップ フォームでは、ユーザーに電子メールアドレスを 2 回入力させることで、そのアドレスが正しいことを確認させます。 2 回目の入力時に blur イベントを使用して 2 つの入力内容を検証し、適切な応答メッセージを設定します。次に例を示します。

if (input.value != primaryEmail) {
  // the provided value doesn't match the primary email address
  input.setCustomValidity('The two email addresses must match.');
  console.log("E-mail addresses do not match", primaryEmail, input.value);
} else {
  // input is valid -- reset the error message
  input.setCustomValidity('');
}

サンプルを見る

無効なフォームの送信禁止

フォームに無効なデータが入力されている場合に、すべてのブラウザがユーザによるフォームの送信を禁止するわけではないため、送信イベントを捕捉し、フォーム要素で checkValidity() を使用して、フォームが有効かどうかを判定する必要があります。

次に例を示します。

form.addEventListener("submit", function(evt) {
  if (form.checkValidity() === false) {
    evt.preventDefault();
    alert("Form is invalid - submission prevented!");
    return false;
  } else {
    // To prevent data from being sent, we've prevented submission
    // here, but normally this code block would not exist.
    evt.preventDefault();
    alert("Form is valid - submission prevented to protect privacy.");
    return false;
  }
});

サンプルを見る

フィードバックのリアルタイム表示

ユーザがフォームを送信する前に、フォームが正しく入力されたかどうかを示す視覚的指示を各フィールドで提示すると便利です。HTML5 には複数の新しい疑似クラスも用意されています。これらのクラスを使用すると、入力値または属性に基づいて入力をスタイル化できます。

リアルタイムのフィードバック
:valid 入力値がすべての検証要件を満たすときに、入力要素に使用するスタイルを明示的に設定します。
:invalid 入力値がすべての検証要件を満たさないときに、入力要素に使用するスタイルを明示的に設定します。
:required required 属性が設定された入力要素のスタイルを明示的に設定します。
:optional required 属性が設定されていない入力要素のスタイルを明示的に設定します。
:in-range 値が範囲内にある数値入力要素のスタイルを明示的に設定します。
:out-of-range 値が範囲外にある数値入力要素のスタイルを明示的に設定します。

検証は即座に実行されます。つまり、ページがロードされた直後で、ユーザーがまだフィールドに入力する機会がなくても、フィールドが無効とマークされる可能性があります。また、ユーザーが入力している最中に、無効なスタイルだと表示されることがあります。これを避けるために、CSS と JavaScript を組み合わせて、ユーザーがフィールドを操作したときのみ、無効なスタイルであることを表示することができます。

input.dirty:not(:focus):invalid {
  background-color: #FFD9D9;
}
input.dirty:not(:focus):valid {
  background-color: #D9FFD9;
}
var inputs = document.getElementsByTagName("input");
var inputs_len = inputs.length;
var addDirtyClass = function(evt) {
  sampleCompleted("Forms-order-dirty");
  evt.srcElement.classList.toggle("dirty", true);
};
for (var i = 0; i < inputs_len; i++) {
  var input = inputs[i];
  input.addEventListener("blur", addDirtyClass);
  input.addEventListener("invalid", addDirtyClass);
  input.addEventListener("valid", addDirtyClass);
}

サンプルを見る

ポイント: 問題点は 1 つずつ表示せずに、フォーム上のすべての問題をまとめてユーザーに表示してください。