日本語はIMEを通して、複数のスクリプトを混ぜて、しかもバリデーションが想定しない全角文字でしばしば入力されます。その結果、有効な日本語の氏名を弾き、変換の途中でエラーを出し、ASCIIが不要な場所でASCIIを要求するフォームが、静かに蔓延しています。本記事では、日本でSaaSのフォームを壊す入力のメカニズムと、それをネイティブに感じさせる直し方を整理します。
日本語はラテン文字のように直接打つことができません。漢字は数千あり、数千のキーを持つキーボードは存在しないため、日本語入力はIME(Input Method Editor)を通して行われます。ユーザーが読みを打ち、IMEが変換候補を表示し、ユーザーが選んで確定します。確定したときに初めて、最終的なテキストがフィールドに入力されます。この一点——キー入力と確定済みテキストの間にギャップがあること——が、日本語フォームのバグの大半の根本原因です。
具体的には、「平木」という氏名の入力は段階を踏みます。ユーザーが hiraki と打ち、「ひらき」(ひらがな)が表示され、スペースで変換し、候補リスト(平木、開き、ひらき…)が出て、「平木」を選び、Enterで確定します。最初のキー入力から最後のEnterまで、フィールドには未確定の途中テキストが入っています。ブラウザはこのライフサイクルをcompositionstart、compositionupdate、compositionendのイベントで公開しており、これらを無視するフォームのロジックは、ユーザーがまだ入力していないテキストを相手にしていることになります。
2つ目は文字幅です。IMEはモードによって、数字やASCII記号も含めて、既定で全角の形で文字を生成します。電話番号を入力するユーザーは、本人が意図しないまま、09012345678ではなく09012345678になり、メールが@ではなく@になることがあります。ユーザーにはこれが正しく見えますが、ASCII限定のバリデーションには無効な入力に見えます。
全角・半角の区別は、「このフォームは日本語ユーザーを嫌っている」という報告の最も多い原因です。全角文字は1つのCJK文字の見た目の幅を占め、半角は見慣れた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)」が半角の数字を使うよう伝え、例を示します。氏名フィールドなら、漢字・かな・ローマ字のどれを期待しているかを示すことで、ユーザーが迷わずに済みます。重要なのは、最良のフォームは両方の幅を受け付けて静かに正規化し、ヘルプ文を強制ではなく案内として使う点です。全角の数字を打ったユーザーは、ブロックされるのではなく自動的に補正されます。