日本語はIMEを通して入力され、複数の文字種が混ざり、しかもバリデーションが想定していない全角文字がしばしば使われます。その結果、有効な日本語の氏名を弾いたり、変換の途中でエラーを出したり、ASCIIが必要ない場面でASCIIを要求したりするフォームが、静かに増えています。本記事では、日本のSaaSのフォームを壊す入力の仕組みと、それをネイティブに感じさせる直し方を整理します。
日本語はラテン文字のようには直接打てません。漢字は数千あり、数千のキーを持つキーボードは存在しないため、日本語入力はIME(Input Method Editor)を通して行われます。ユーザーが読みを打ち、IMEが変換候補を表示し、ユーザーが選んで確定します。確定して初めて、最終的なテキストがフィールドに入ります。キー入力と確定済みテキストの間にはギャップがあり、このギャップこそが日本語フォームのバグの大半の根本原因です。
具体的には、「開」という氏名を入力するときは、いくつかの段階を踏みます。ユーザーが hiraki と打つと「ひらき」(ひらがな)が表示され、スペースで変換し、候補リスト(開、開き、ひらき…)が出て、「開」を選び、Enterで確定します。最初のキー入力から最後のEnterまで、フィールドには未確定の途中テキストが入っています。ブラウザはこのライフサイクルをcompositionstart、compositionupdate、compositionendのイベントで公開しています。これらを無視するフォームのロジックは、ユーザーがまだ入力し終えていないテキストを相手にしていることになります。
2つ目は文字幅です。IMEはモードによっては、数字やASCII記号も含めて、既定で全角の形で文字を生成します。電話番号を入力するユーザーは、本人が意図しないまま、09012345678ではなく09012345678になったり、メールが@ではなく@になったりすることがあります。ユーザーにはこれが正しく見えますが、ASCII限定のバリデーションには無効な入力に見えます。
全角・半角の区別は、「このフォームは日本語ユーザーを嫌っている」という声が最も多く上がる原因です。全角文字はCJK文字1つ分の見た目の幅を占め、半角は見慣れたASCII幅の形です。日本語のキーボードやIMEはこれらを切り替えますが、ユーザーがどちらを生成するかは、IMEのモードやデバイス、習慣で決まるもので、バリデーションが期待するものとは何の関係もありません。
問題が表面化するのは、まさにASCIIを前提にしたフィールドです。電話番号、郵便番号、クレジットカード番号、メールアドレスです。/^[0-9]+$/ のような正規表現は半角の数字にしか一致せず、ユーザーが有効な電話番号を打っているのに090を弾いてしまいます。正しい対応はほぼ常に、弾くことではなく正規化することです。検証の前に全角の数字とラテン文字を半角に変換し、090と090が同じ保存値になるようにします。
正規化は一貫したやり方で、1か所にまとめて適用すべきです。最も堅牢なのは、サーバー側を確かな正本として正規化し、必要に応じてフィールドのblurやchangeイベントでブラウザ側でも正規化して、ユーザーにすぐフィードバックを返すパターンです。やってはいけないのは、ユーザーが変換している最中にIMEと競合する形で正規化することです。ちらつきや文字落ちの原因になります。値が落ち着いてから正規化し、正規化した値を検証し、正規化した形で保存します。
日本語フォームで最も苛立つバグは、まだ名前を打っている最中に出るエラーです。これは、フォームが input や keyup のイベントで検証しているために起こります。これらのイベントはキー入力のたびに発火し、IMEがまだ最終的な変換を処理している途中の読みのキー入力も含まれます。バリデーターは「ひらき」や「ひら」だけを見て誤りと判断し、ユーザーが何も確定していないのにエラーを出してしまいます。
標準的な直し方は、変換のライフサイクルを使うことです。compositionstart が発火したら、検証を抑制するフラグを立てます。compositionend が発火したら、ユーザーは変換を確定しているので、フラグを解除して確定済みの値を検証します。原則はシンプルです。IMEが変換し終えていないテキストは決して検証しない。この1つの変更で、「入力中にエラー」という苦情がまるごと消えます。
同じ仕組みが、優れたフリガナ自動入力にもつながります。2つの問題は、実は1つの問題なのです。変換イベントを正しく扱うフォームは、早すぎる検証を抑えることと、確定した読みを取得することの両方ができます。これらを無視するフォームは、どちらもできません。
氏名を収集する日本語のフォームは、ほぼ必ずフリガナ(フリガナ/ふりがな)フィールド、つまり氏名の読みも集めます。これは冗長なものではありません。「開」のような漢字の氏名には複数の読み方があり、企業は並べ替えや宛名、電話応対のために読みを必要とします。氏名を二度、漢字で一度、かなで一度打たせるのは、はっきりと認識される摩擦点です。
よくできた日本語のフォームは、ユーザーがIMEに打ち込んだ読みからフリガナを自動入力します。ユーザーが hiraki を「開」に変換するとき、読み「ひらき」はまさに本人が打った文字列で、変換イベントを通して取得できます。その読みをフリガナフィールドに書き込み、フィールドがカナを期待していればカタカナへ変換すれば、ひと手間まるごと省けます。ユーザーはこれにすぐ気づきます。英語フォームの翻訳ではなく、日本語入力を理解している人が作ったフォームだという証です。
長年、開発者はCSSの ime-mode プロパティを使い、数字の郵便番号フィールドなどで、フィールドを半角に強制したり、IMEを完全に無効化したりしようとしてきました。このプロパティは非推奨であり、現代の標準からは外れています。ブラウザ間で挙動が一貫せず、現在のどの実装にも組み込むべきではありません。これに依存すると、あるブラウザでは動き、別のブラウザでは静かに失敗するフィールドができてしまいます。
サポートされている標準的な方法はinputmode属性です。フィールドが期待する入力の種類を、ブラウザやソフトウェアキーボードにヒントとして伝えます。郵便番号には inputmode="numeric"、メールフィールドには inputmode="email" などです。モバイルではこれが適切なキーボードを表示し、デスクトップではヒントになります。重要なのは、inputmodeはあくまでヒントであって保証ではないという点です。ユーザーは依然として全角文字を生成できます。だからこそinputmodeは正規化と組み合わせる必要があります。期待する入力をヒントで示し、届いたものを正規化する。この2つを合わせることが、古くて壊れたime-modeのやり方に取って代わります。
| フィールド | 期待する入力 | 推奨アプローチ | 備考 |
|---|---|---|---|
| 電話番号 | 半角数字 | inputmode="tel" + 全角→半角 正規化 | 全角の数字を受け付けて正規化。090形式の入力を決してブロックしない。 |
| 郵便番号 | 半角数字(7桁) | inputmode="numeric" + 正規化 | ハイフンを除去するか、1234567と123-4567の両方を受け付ける。 |
| メール | 半角英数記号 | inputmode="email" + @等の正規化 | 検証前に全角の@やラテン文字を半角へ変換する。 |
| 氏名(漢字) | 漢字・かな | 幅・スクリプト制限を緩める | ASCIIや「スペース不可」を強制しない。日本人の氏名にはスペースと漢字が含まれる。 |
| フリガナ | カナ/かな | IME読みから自動入力 + かな⇄カナ変換 | 読みから自動入力。ひらがな・カタカナの両方を受け付け、期待する側へ正規化する。 |
| 自由記述コメント | 全角・半角混在 | 幅の制限をしない | 日本語の文章では混在幅が普通。ここでは正規化も制限もしない。 |
この表から見えてくるのは、すべてのフィールドに共通の「正しい」幅など存在しないというルールです。数字フィールドは半角へ正規化すべきで、氏名や自由記述のフィールドは混在幅をそのまま受け付けるべきです。一律に「すべて半角に変換」するルールは、一律に「全角を弾く」ルールと同じくらい誤っています。日本人の氏名や文章を壊してしまうからです。幅の扱いはフィールドごとに、そのフィールドが実際に何を保存するかで決まります。
基本の変換ケースを扱えるフォームでも、さらに2つの挙動でつまずきます。1つ目は予測変換です。現代のIMEはユーザーが打ち終える前に補完を提案し、提案を採用すると、通常の変換とは少し異なるイベント経路でテキストが確定することがあります。フォームは、各予測キー入力を解釈しようとするのではなく、compositionend時(または後続のinput/change)の値を正本として扱うべきです。
2つ目は貼り付け入力です。ユーザーは、どこかからコピーした電話番号や郵便番号を貼り付けることがよくあります。多くは全角で、ー(全角ダッシュ)やスペースといった整形文字が混じります。貼り付けでは変換イベントが発火しないため、変換ベースのロジックだけでは見逃してしまいます。changeやblurイベントでの正規化なら、打った値も貼り付けた値も拾えます。これも、変換処理だけでなく正規化こそが恒久的な直し方である理由です。タイミングは変換で、内容は正規化で扱います。
日本語フォームのエラーを減らす最も安上がりな方法は、入力した後で叱るのではなく、入力する前にそのフィールドが何を期待しているかを伝えることです。最も価値のあるヒントは、期待する文字幅とスクリプトを例とともに示すことです。電話番号フィールドなら「半角数字でご入力ください(例:09012345678)」が、期待する幅と形を伝えます。氏名フィールドなら、漢字・かな・ローマ字のどれを期待しているかを示せば、ユーザーが迷わずに済みます。
ただしヘルプ文は強制ではなく案内であるべきです。最良のフォームは、それでも全角入力を受け付けて静かに正規化します。ヘルプ文は期待値を伝え、驚きを減らすために使い、ブロックの口実にはしません。「半角数字で」と読んでもなお全角を打ってしまうユーザーは、IMEが既定でそうしてしまうからであり、エラーで罰するのではなく正規化で補正すべきです。エラーメッセージは、本当に必要なときには、フィールド名を挙げ、何が問題かを述べ、正しい例を、ですます調の丁寧な日本語で示す、具体的で思いやりのあるものにします。
全角の数字、変換中の検証エラー、ASCII限定の氏名ルール。日本のユーザーがサインアップや決済の途中で離脱する理由として、最も多いのがこれらです。日本語入力のQAレビューでは、IME・全角・貼り付けまで含め、日本のユーザーが実際に打つとおりにフォームをテストし、どのフィールドが気づかれないまま失敗しているのかを正確に特定します。
ミニ診断を依頼するなぜフォームが有効な日本語の氏名や電話番号を弾くのですか?
最も多い原因は、全角と半角の扱いです。入力モードによってはIMEが既定で全角を出すため、日本のユーザーは数字や@記号を全角(090ではなく090、@ではなく@)で打つことがよくあります。ASCIIだけを想定したバリデーションはこれを無効として弾きますが、ユーザーはごく普通の電話番号やメールアドレスを入力しただけです。直し方は、全角入力を弾くのではなく正規化することです。検証の前に全角の数字とラテン文字を半角に変換し、090と090を同じ値として扱います。
なぜユーザーが日本語を入力し終える前にバリデーションが発火するのですか?
日本語の入力はIMEを通して行われ、変換という段階があります。ユーザーが読みを打ち、IMEが変換候補を表示し、確定して初めてテキストが入力されます。キー入力のたび(inputイベントやkeyupイベント)に検証するJavaScriptは、この変換中にも動いてしまいます。未確定の途中テキストを検証し、ユーザーがまだ変換している最中にエラーを出すことがよくあります。直し方は、compositionstartとcompositionendのイベントを監視し、変換中はバリデーションを止めて、ユーザーが変換を確定してから検証することです。
日本語入力の制御にCSSのime-modeプロパティを使うべきですか?
いいえ。CSSのime-modeプロパティは非推奨で、現在のブラウザ標準からは外れています。半角を強制したりIMEを無効にしたりする目的でこれに頼ると、ブラウザによって挙動が不安定になるため、今の実装に組み込むべきではありません。標準でサポートされているのは、input要素のinputmode属性です。これは、期待する入力の種類(numeric、emailなど)をブラウザやソフトウェアキーボードにヒントとして伝えます。半角が必須のフィールド(数字の郵便番号など)では、適切なinputmodeを設定したうえで、全角入力をコード側で正規化するのが正しいやり方です。非推奨のCSSプロパティでIMEを抑え込もうとすべきではありません。
氏名フィールドからのフリガナ自動入力は実際どう動くのですか?
日本語のフォームには、漢字の氏名フィールドの隣にフリガナ(読み)フィールドがあることが多く、よくできたフォームは、ユーザーがIMEに打ち込んだ読みからフリガナを自動入力します。ユーザーは漢字の氏名を入力するとき、まず読みを打ってから変換します。その読みは、IMEの変換イベントを通じてページ側で取得できます。確定した読みを取得してフリガナフィールドに書き込めば、ユーザーは氏名を二度打たずに済みます。ただし、これはフォームが変換イベントを正しく監視している場合にしか機能しません。扱いを誤ると変換中のバリデーションエラーを引き起こすのと、同じ仕組みだからです。
日本語フォームのエラーを最も減らす入力ヘルプ文は何ですか?
最も効果が大きいのは、期待する文字幅と文字種を、入力後のエラーではなく入力前に示すことです。電話番号フィールドなら、「半角数字でご入力ください(例:09012345678)」と書けば、半角数字で入力すべきことが伝わり、例も示せます。氏名フィールドなら、漢字・かな・ローマ字のどれを求めているかを示せば、ユーザーは迷いません。大事なのは、最良のフォームは全角・半角の両方を受け付けて裏で正規化し、ヘルプ文を強制ではなく案内として使っている点です。全角の数字を打ったユーザーはブロックされず、自動で補正されます。
全角の数字、変換中の検証エラー、ASCII限定の氏名ルール、非推奨のime-modeによる小細工。これらは、日本のユーザーがサインアップや決済を離脱する構造的な原因です。的を絞ったQAレビューでは、実際のIMEでフォームをテストし、どのフィールドが有効な入力を静かに弾いているかを特定します。