フォームまわりのHTML:アクセシビリティとマークアップの最適解

Webサイトにおけるフォームは、ユーザーとの接点であり、ビジネスにおける成果を左右する重要な要素です。しかし、視覚的な見栄えだけに注力しすぎると、アクセシビリティが損なわれ、使い勝手が低下してしまうことも。この記事では、アクセシビリティとメンテナンス性を両立したフォームHTMLの最適なマークアップ方法について、実例を交えて解説します。

1. label要素とfor属性の活用

フォームの入力欄には、必ず<label>要素を使用して、ラベルと入力欄を明確に関連付けましょう。これにより、スクリーンリーダーが適切に読み上げ、アクセシビリティが向上します。

<label>の使い方には、以下の2通りがあります。

<!-- for属性を使う方法(推奨) -->
<label for="email">メールアドレス</label>
<input type="email" id="email" name="email">

<!-- label要素で囲む方法 -->
<label>メールアドレス
  <input type="email" name="email">
</label>

ポイント:

  • idforを使ったパターンは、HTML構造が分離されていてもラベルの関連付けが可能で、スタイルやJavaScriptとの相性が良好です。
  • ラベルで囲むパターンは、記述が簡潔でわかりやすい反面、スタイリングが難しい場合があります。

どちらの方法を採用するかは、フォームの設計やデザイン、機能要件に応じて適宜使い分けましょう。

ラベルが視覚的に不要なケースでも、スクリーンリーダーなどに対するラベル提供は不可欠です。その際は、次のような方法が有効です。

<!-- aria-label を使う例 -->
<input type="text" name="username" aria-label="ユーザー名">

<!-- sr-only クラスを使う例 -->
<label class="sr-only" for="search">検索</label>
<input type="search" id="search" name="search">

sr-only はスクリーンリーダー専用のクラスで、以下のようなCSSで視覚的に非表示にします。ただし、display: none はスクリーンリーダーにも読み上げられなくなるため、アクセシビリティ目的では使用しないよう注意してください。

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

2. フォーム構造のグループ化:fieldsetとlegend

関連するフォーム要素は、<fieldset>でグループ化し、<legend>で内容を説明すると構造が明確になります。視覚的な整理だけでなく、スクリーンリーダーによる読み上げ順や意味付けにも効果的です。

<form>
  <fieldset>
    <legend>お客様情報</legend>
    <label for="name">お名前</label>
    <input type="text" id="name" name="name">

    <label for="email">メールアドレス</label>
    <input type="email" id="email" name="email">
  </fieldset>

  <fieldset>
    <legend>お問い合わせ内容</legend>
    <label for="subject">件名</label>
    <input type="text" id="subject" name="subject">

    <label for="message">メッセージ</label>
    <textarea id="message" name="message"></textarea>
  </fieldset>
</form>

このように、複数の<fieldset>を適切に分けて使用することで、長いフォームでも構造が明確になり、ユーザーが迷わず操作できるようになります。


3. aria属性の活用

バリデーションエラーの箇所には、aria-describedbyでエラー文を関連付けましょう。

<label for="name">お名前</label>
<input type="text" id="name" name="name" aria-describedby="name-error">
<p id="name-error" class="error">名前は必須項目です</p>

他にもフォーム周りでよく使用されるaria属性には以下のようなものがあります:

  • aria-required="true"required属性とあわせて使うことで、スクリーンリーダーに「このフィールドは必須です」と明示的に伝えられます。
  • aria-invalid="true":バリデーションエラーが発生したフィールドを示します。
  • aria-live="polite":エラーメッセージの領域などに指定することで、内容が変わった際に読み上げられるようにします(例:AJAXバリデーション結果)。
  • aria-label:ラベル要素を使わずにテキストラベルを提供できます(ただし推奨されるのは明示的な<label>要素です)。

これらの属性は、視覚に頼らず操作するユーザーにとって重要な手がかりとなります。HTMLの構造とあわせて、適切な属性を付与することがアクセシビリティ向上に直結します。


4. 必須項目の明示

required属性を使うだけでなく、ラベルにも「必須」と表示することで、視覚的にもわかりやすくします。また、aria-required="true"を併用することで、スクリーンリーダーにも「この項目は必須である」ことを明確に伝えることができます。

<label for="phone">電話番号 <span class="required">(必須)</span></label>
<input type="tel" id="phone" name="phone" required aria-required="true">

5. input[type=submit]の役割の明示

送信ボタンには明確なラベルを付けましょう。

<button type="submit">お問い合わせを送信</button>

"送信"だけではなく、"お問い合わせを送信"のように、アクション内容を具体的に記述するのが理想です。

また、送信ボタンの実装方法としては、<input type="submit"><button type="submit">の2種類があります。

<!-- input要素を使う場合 -->
<input type="submit" value="送信">

<!-- button要素を使う場合 -->
<button type="submit">送信</button>

それぞれの違いは以下の通りです:

  • <input type="submit"> はシンプルで予期しないスタイルが適用されにくく、古くから使われていますが、HTMLの中に子要素を含められません。
  • <button> は中にHTML(例:アイコン、装飾)を自由に含められるため、装飾性や柔軟なデザインに対応しやすい反面、ブラウザによってデフォルトスタイルのばらつきが出やすいです。

デザインや実装方針に応じて、適切なタグを選択しましょう。


6. 入力補助のためのplaceholderは補助的に

placeholder属性は便利ですが、視覚的に消えてしまうためラベルの代替として使ってはいけません。補助的に使うようにしましょう。

<label for="company">会社名</label>
<input type="text" id="company" name="company" placeholder="例:株式会社サンプル">

また、CSSで::placeholder疑似要素をスタイリングする際は、コントラスト比が十分であることを意識し、テキストが読みづらくならないよう注意が必要です。特にグレーのplaceholderテキストは背景色との視認性が低くなりがちなので、アクセシビリティ基準(WCAG)に基づいた色設計を心がけましょう。

なお、::placeholder疑似要素は、CSS Pseudo-Elements Module Level 4で定義され、現在は主要なブラウザ(Chrome、Edge、Firefox、Safari、Opera)で広くサポートされています。ただし、旧式のIEでは::-ms-input-placeholderのような独自記法が必要なため、サポート対象ブラウザに応じた対応を検討してください。


7. エラーメッセージの表示タイミングに配慮

リアルタイムでエラーを表示する際は、ユーザーの入力を妨げないよう、適切なタイミング(フォーカスアウト後など)で表示しましょう。

以下はJavaScriptを使って、blurイベント(フォーカスが外れたとき)にバリデーションを実行し、エラーメッセージを表示する簡単な例です:

<label for="email">メールアドレス</label>
<input type="email" id="email" name="email">
<p id="email-error" class="error" style="display: none; color: red;">有効なメールアドレスを入力してください</p>
document.getElementById("email").addEventListener("blur", function () {
  const emailInput = this;
  const errorMessage = document.getElementById("email-error");

  if (!emailInput.validity.valid) {
    errorMessage.style.display = "block";
    emailInput.setAttribute("aria-describedby", "email-error");
    emailInput.setAttribute("aria-invalid", "true");
  } else {
    errorMessage.style.display = "none";
    emailInput.removeAttribute("aria-describedby");
    emailInput.removeAttribute("aria-invalid");
  }
});

このように、リアルタイムでのフィードバックを控えめにしつつ、必要なときに明確なエラーを伝えることで、ユーザーのストレスを軽減しつつアクセシビリティも確保できます。


8. 入力内容の保持

送信エラー時にフォームの内容を消さないようにすることで、再入力のストレスを軽減できます。サーバー側・JavaScript側どちらの実装でも配慮が必要です。

具体的な実現方法については、別記事で詳しく解説する予定です。


9. 自動入力支援:autocomplete属性の活用

オートコンプリートがうざいと感じた経験は、誰しも一度はあるのではないでしょうか。autocomplete属性を使えば、ブラウザがユーザー情報を補完してくれるため利便性が向上します。ただし、設定を誤ると意図しない値が自動入力される可能性があるため注意が必要です。たとえば、パスワードやセキュリティ関連のフィールドでは適切なautocomplete値(例:autocomplete="new-password")を指定しないと、古い値が勝手に入力されることもあります。オートコンプリートがうざいと感じた経験は、誰しも一度はあるのではないでしょうか。

また、オートコンプリートを避けたい場面(例:一時的なトークン、確認コード入力欄など)では、autocomplete="off"の指定も検討しましょう。ユーザー体験とセキュリティのバランスを踏まえた設計が求められます。

<input type="email" name="email" autocomplete="email">

10. タブ移動の順番を意識する

フォームの設計時は、Tabキーでのフォーカス移動が自然な流れになるように、要素の並びやHTMLの記述順を意識することが大切です。

以下は、フォーム内でタブ移動が自然に流れるマークアップ例です:

<form>
  <label for="name">お名前</label>
  <input type="text" id="name" name="name">

  <label for="email">メールアドレス</label>
  <input type="email" id="email" name="email">

  <label for="message">お問い合わせ内容</label>
  <textarea id="message" name="message"></textarea>

  <button type="submit">送信</button>
</form>

このように、HTMLの記述順を意識するだけでも、自然なタブ順が実現できます。

また、tabindex属性を使ってフォーカス順を制御したい場面では、次のような記述も可能です:

<form>
  <input type="text" name="step3" tabindex="3" placeholder="3番目にフォーカス">
  <input type="text" name="step1" tabindex="1" placeholder="1番目にフォーカス">
  <input type="text" name="step2" tabindex="2" placeholder="2番目にフォーカス">
</form>

この例では、実際のHTMLの並び順に関係なく、Tabキーの移動順をカスタマイズしています。ただし、tabindexは乱用するとかえってユーザーを混乱させるため、必要最小限の使用にとどめましょう。

また、カスタムUIやJavaScriptによって操作されるフォーム部品を使用する場合、tabindex属性を適切に使って、フォーカス順を調整することも必要です。ただし、tabindexの使いすぎはかえってフォーカス移動を混乱させる原因になるため、基本はHTMLの構造に沿った順序で設計するのが理想です。

スクリーンリーダー利用者や視覚障害を持つユーザーにとっても、タブ順が乱れていると混乱を招くため、実際の操作感を意識したテストを行うこともおすすめです。多くのユーザーはキーボード操作によってフォームを移動するため、タブ順が論理的で直感的であることがアクセシビリティとユーザビリティの両面で重要になります。

また、カスタムUIやJavaScriptによって操作されるフォーム部品を使用する場合、tabindex属性を適切に使って、フォーカス順を調整することも必要です。ただし、tabindexの使いすぎはかえってフォーカス移動を混乱させる原因になるため、基本はHTMLの構造に沿った順序で設計するのが理想です。

スクリーンリーダー利用者や視覚障害を持つユーザーにとっても、タブ順が乱れていると混乱を招くため、実際の操作感を意識したテストを行うこともおすすめです。


まとめ:誰もが使いやすく、検索エンジンにも強いフォーム設計を

アクセシビリティに配慮したフォームマークアップは、すべてのユーザーにとって使いやすくなるだけでなく、検索エンジンや音声ブラウザにも正しく情報が伝わるため、SEOやUXにも良い影響を与えます。小さな工夫の積み重ねが、より良いユーザー体験へとつながります。ぜひ、次回のフォーム実装から意識してみてください。

Contact

ウェブサイトの制作や運用に関わる
お悩みやご相談
お気軽にお問い合わせ下さい

ウェブサイトと一口に言っても、企業サイトやECサイト、ブログ、SNSなど、その“カタチ”は目的に応じてさまざまであり、構築方法や使用する技術も大きく異なります。株式会社コナックスでは、お客様のご要望やブランドの個性を丁寧に汲み取り、最適なウェブサイトの“カタチ”をご提案いたします。

デザイン、ユーザビリティ、SEO対策はもちろん、コンテンツ制作やマーケティング戦略に至るまで、あらゆるフェーズでお客様のビジネスに寄り添い、成果につながるウェブサイトづくりをサポートいたします。私たちは、ウェブサイトの公開をゴールではなくスタートと捉え、お客様のビジネスの成功に向けて共に伴走してまいります。