Modern HTML 1-4|モダンなフォーム設計|HTML標準で使いやすいフォームを作る
HTMLを順番に学びたい方へ
この記事は、ToshiLabのWEBプログラミング学習記事の一部です。
HTMLを基礎から順番に確認したい方は、WEBプログラミングの入口から進められます。
- この回で分かること
- 前回のミニチェック|Modern HTML 1-3 回答・解説
- フォームは入力欄を並べるだけではない
- form・label・input・buttonの基本構造
- fieldset・legendで関連する項目をまとめる
- inputのtypeは目的に合わせて選ぶ
- numberなら何でも数字というわけではない
- requiredで必須入力をブラウザへ伝える
- autocompleteで入力を助ける
- inputmodeで入力しやすいキーボードを伝える
- ブラウザ標準のバリデーションを活かす
- select・textarea・placeholderを意味から使う
- buttonのtypeを明確にする
- disabledとreadonlyは同じではない
- 使いやすいフォームはアクセシビリティまで考える
- HTML標準でお問い合わせフォームを組み立てる
- 実務ではどこで使う?
- 迷ったときの確認ポイント
- 今回できるようになったこと
- Modern HTML 1-4 ミニチェック
- まとめ
- 前回を確認する
- 次に読む
この回で分かること
Modern HTML 1-3では、見出しや文章、引用、リスト、figureなどを「見た目」ではなく「その内容が何を意味しているのか」から選びました。
Modern HTML 1-4では、その考え方をフォームへ広げます。
フォームというと、「入力欄を置いて、最後に送信ボタンを付ける」という見た目を思い浮かべやすいかもしれません。
しかし、現在のHTMLにはフォームを使いやすくするための多くの標準機能があります。
今回確認するのは、
・form・label・input・buttonの基本構造
・fieldset・legendによる入力項目のグループ化
・目的に合ったinputのtype
・requiredによる必須入力
・autocompleteによる入力補助
・inputmodeによるスマートフォン入力の補助
・select・textarea・placeholderの役割
・ブラウザ標準のバリデーション
・disabledとreadonlyの違い
・フォームとアクセシビリティ
です。
今回もModern HTMLシリーズで共通している、
まずHTML標準で何ができるのかを考える
というNative HTML Firstの考え方を大切にします。
フォームだからといって、最初からJavaScriptを書く必要はありません。
HTMLには入力方法、必須項目、入力補助、バリデーションなど、多くの標準機能があります。
まずHTMLで意味と基本動作を設計し、それだけでは足りない部分をCSSやJavaScriptで補うのがModern HTMLでの基本方針です。
前回のミニチェック|Modern HTML 1-3 回答・解説
Modern HTML 1-3では、見出しや文章、引用、リスト、figureなどを、見た目ではなくコンテンツの意味から考えました。
ここで、前回のミニチェック3問を振り返ります。
Q1|重要な注意書きはstrong・bのどちら?
「この操作は必ず保存してから終了してください」という、内容そのものが重要な注意書きを考えました。
答え:strongが候補です。
strongは、内容の重要性・重大性・緊急性などを表します。
一方、bは文章の意味として重要性を追加するのではなく、キーワードなどへ注意を向けたい場合に使える要素です。
今回のように、
「この内容そのものが重要である」と伝えたい場合
は、strongが適しています。
Q2|Ctrl + SとSaved successfullyは何を使う?
答え:「Ctrl + S」はkbd、「Saved successfully」はsampが候補です。
kbdは、ユーザーがキーボードなどから入力する内容を表します。
そのため、「Ctrl + S」のようなユーザー操作にはkbdが適しています。
sampは、プログラムやコンピューターシステムから返される出力例を表します。
そのため、保存後にシステムから表示される「Saved successfully」はsampが候補になります。
codeはコンピューターコードを表しますが、
ユーザー入力なのか、システム出力なのか
まで区別できる場合には、それぞれの意味に合った要素を選びます。
Q3|すべての画像はfigureで囲む?
答え:いいえ。すべての画像をfigureで囲む必要はありません。
figureは画像専用の要素ではなく、
本文から切り離しても、1つの図・例・素材として独立して扱えるコンテンツ
をまとめる場合に使えます。
画像だから自動的にfigureを使うのではありません。
本文の流れの中で通常の画像として扱えば十分な場合もあります。
figcaptionによるキャプションが必要なのか、独立した図版として扱えるのかなどを考えて判断します。
Modern HTML 1-3の3問でも共通しているのは、
見た目からHTML要素を決めないこと
です。
重要性、ユーザー入力、システム出力、独立した図版など、
「その内容は何なのか?」
からHTMLを選びます。
フォームは入力欄を並べるだけではない
フォームは、ユーザーから情報を受け取るためのUIです。
お問い合わせフォーム、ログイン画面、検索フォーム、会員登録、購入画面など、Webサイトではさまざまな場所で使われています。
入力欄が表示されていればフォームとして動かすことはできますが、
誰が見ても何を入力すればよいか分かり、できるだけ間違えずに操作できること
まで考えると、HTMLの構造が重要になります。
例えば、
・入力欄には何を入力するのか
・その入力は必須なのか任意なのか
・複数の項目は同じグループなのか
・どのような形式の入力を期待しているのか
・最後のボタンを押すと何が起こるのか
といった意味をHTMLで表現できます。

PR:Modern HTML 学習の最初の参考書として、必要な方だけ見てください。
出版社自身が「HTMLの基本を一度学んだ人が再入門・ステップアップする本」と位置づけており、内容もHTML仕様、セマンティクス、主要要素、フォーム、インタラクティブ要素、WAI-ARIAまで扱っています。今回の「初心者HTMLをやり直すのではなく、現在のHTMLへ知識をアップデートする」というシリーズ方針とかなり近いです。
※価格や在庫、版数は変わるため、最終確認はリンク先でお願いします。
form・label・input・buttonの基本構造
まず、フォームの基本となる要素から確認します。
formはフォーム全体を表す
form要素は、入力項目や送信ボタンなどを1つのフォームとしてまとめます。
フォームをどこへ送信するのか、どのHTTPメソッドを使用するのかといった情報も指定できます。
labelは入力項目の名前を伝える
labelは、
この入力欄が何のためのものなのか
をユーザーへ伝えます。
placeholderだけで入力項目を説明するのではなく、基本的にはlabelを用意します。
labelのfor属性とinputのidを対応させると、ラベルと入力欄を明確に関連付けられます。
inputは入力の目的をtypeで伝える
inputは1つの要素ですが、type属性によって役割が変わります。
テキスト入力、メールアドレス、電話番号、日付、検索など、目的に合ったtypeを選ぶことでブラウザにも入力の意味を伝えられます。
buttonは操作を表す
フォームの送信にはbuttonを使用できます。
buttonでは、「送信」だけではなく、
押したあと何が起きるのか分かる文言
を意識すると、より使いやすいフォームになります。
基本構造を確認します。
<form action="/contact" method="post">
<div>
<label for="name">お名前(必須)</label>
<input
type="text"
id="name"
name="name"
autocomplete="name"
required
>
</div>
<div>
<label for="email">メールアドレス(必須)</label>
<input
type="email"
id="email"
name="email"
autocomplete="email"
required
>
</div>
<button type="submit">お問い合わせを送信</button>
</form>HTMLfieldset・legendで関連する項目をまとめる
フォームには、複数の入力項目が同じテーマに属する場合があります。
例えば、「ご希望の連絡方法」というテーマの中に、
・メール
・電話
・どちらでもよい
という選択肢がある場合です。
このような関連するフォームコントロールは、fieldsetでグループ化できます。
legendは、そのグループが何を表しているのかを示します。
fieldsetは、単に枠線を付けるための要素ではありません。
関連する入力項目を1つのグループとして意味付けする要素です。
legendは、そのグループのタイトルを表します。
次で確認します。
<fieldset>
<legend>ご希望の連絡方法</legend>
<label>
<input
type="radio"
name="contact-method"
value="email"
>
メール
</label>
<label>
<input
type="radio"
name="contact-method"
value="tel"
>
電話
</label>
<label>
<input
type="radio"
name="contact-method"
value="either"
>
どちらでもよい
</label>
</fieldset>HTMLinputのtypeは目的に合わせて選ぶ
inputには多くのtypeがあります。
すべてを暗記する必要はありません。
大切なのは、
入力される情報が何なのか
から選ぶことです。
代表的な例として、
type=”text”
通常の文字列
type=”email”
メールアドレス
type=”password”
パスワード
type=”tel”
電話番号
type=”url”
URL
type=”search”
検索語句
type=”number”
数量などの数値
type=”date”
日付
などがあります。
目的に適したtypeを使うことで、ブラウザは入力内容に応じたUIや入力補助を提供できます。
次に代表的な入力タイプを確認します。
<label for="email">メールアドレス</label>
<input type="email" id="email" name="email">
<label for="password">パスワード</label>
<input type="password" id="password" name="password">
<label for="tel">電話番号</label>
<input type="tel" id="tel" name="tel">
<label for="website">Webサイト</label>
<input type="url" id="website" name="website">
<label for="keyword">検索</label>
<input type="search" id="keyword" name="keyword">
<label for="quantity">数量</label>
<input type="number" id="quantity" name="quantity" min="1">
<label for="date">希望日</label>
<input type="date" id="date" name="date">HTMLnumberなら何でも数字というわけではない
数字だけで構成される情報だからといって、必ずtype=”number”を使うわけではありません。
例えば郵便番号は数字で構成されますが、
計算するための数値ではなく識別情報
です。
電話番号も同様です。
数字に見えるかどうかではなく、
その情報が何を意味するのか
からtypeを考えます。
これはModern HTML 1-3で確認した、
見た目ではなく意味からHTMLを選ぶ
という考え方と同じです。
requiredで必須入力をブラウザへ伝える
入力必須の項目にはrequired属性を使用できます。
requiredを指定すると、
この入力項目は空のままでは送信できない
という条件をブラウザへ伝えられます。
JavaScriptでゼロから必須チェックを書く前に、まずHTML標準でできることを使います。
ただし、画面上でも「必須」であることがユーザーに分かるようにすることが大切です。
autocompleteで入力を助ける
autocompleteは、ブラウザに入力項目の意味を伝え、過去の入力情報などから入力候補を提示しやすくするために使えます。
例えば、
autocomplete=”name”
氏名
autocomplete=”email”
メールアドレス
autocomplete=”tel”
電話番号
autocomplete=”postal-code”
郵便番号
autocomplete=”current-password”
現在使用しているパスワード
autocomplete=”new-password”
新しく設定するパスワード
などがあります。
ログインフォームではcurrent-password、新規登録やパスワード変更で新しいパスワードを設定する場合にはnew-passwordのように、入力項目の目的に合った値を指定できます。
入力する内容を毎回手入力させるより、ブラウザ標準の補助を使える方がユーザーの負担を減らせる場合があります。
inputmodeで入力しやすいキーボードを伝える
inputmodeは、主にスマートフォンなどで、
どのような入力用キーボードを表示すると使いやすいのか
をブラウザへ伝えるためのヒントです。
例えば郵便番号のように数字を入力してほしい文字列では、
type=”text”
の意味を保ちながら、
inputmode=”numeric”
を指定する方法があります。
typeとinputmodeは同じ役割ではありません。
typeは入力内容そのものの意味や動作に関係し、inputmodeは入力方法のヒントとして使われます。
required・autocomplete・inputmodeを組み合わせた例を確認します。
<label for="email">メールアドレス</label>
<input
type="email"
id="email"
name="email"
autocomplete="email"
required
>
<label for="postal-code">郵便番号</label>
<input
type="text"
id="postal-code"
name="postal-code"
autocomplete="postal-code"
inputmode="numeric"
pattern="[0-9]{7}"
aria-describedby="postal-code-help"
>
<small id="postal-code-help">
ハイフンなし7桁で入力してください。
</small>HTML
ブラウザ標準のバリデーションを活かす
HTMLには、入力内容が条件に合っているかを確認する仕組みがあります。
例えば、type=”email”を使用すると、ブラウザはメールアドレスとして妥当な形式かどうかを確認できます。
ただし、そのメールアドレスが実在するか、
実際に受信できるかまで確認するものではありません。
requiredを組み合わせれば、
・入力されているか
・期待される形式になっているか
という基本的な確認をHTMLだけでも行えます。
patternやmin・maxなどを利用できる入力タイプもあります。
ブラウザ標準のバリデーションは、入力ミスを減らすためのユーザー体験向上には役立ちます。
ただし、セキュリティ対策としてHTML側のチェックだけに依存してはいけません。
実際にデータを受け取るサーバー側でも、必ず入力内容を検証する必要があります。
select・textarea・placeholderを意味から使う
フォームはinputだけで構成するものではありません。
selectは選択肢から選んでもらう
あらかじめ候補が決まっていて、その中から選択してもらう場合にはselectが使えます。
自由入力より選択肢の方が適している情報であれば、入力ミスを減らせます。
textareaは複数行の文章入力
お問い合わせ内容やコメントなど、複数行の文章を入力してもらう場合にはtextareaが候補になります。
placeholderは入力例やヒント
placeholderには入力例や短いヒントを表示できます。
ただし、
placeholderをlabelの代わりにはしません。
入力を始めるとplaceholderは見えなくなるため、何を入力する欄だったのか分からなくなる可能性があります。
次で確認します。
<label for="contact-type">お問い合わせ種別</label>
<select id="contact-type" name="contact-type" required>
<option value="">選択してください</option>
<option value="question">ご質問</option>
<option value="request">ご依頼</option>
<option value="other">その他</option>
</select>
<label for="message">お問い合わせ内容</label>
<textarea
id="message"
name="message"
rows="6"
placeholder="例:記事について質問があります。"
></textarea>HTMLbuttonのtypeを明確にする
buttonにはtypeを指定できます。
フォームを送信するなら、
type=”submit”
通常の操作用ボタンなら、
type=”button”
入力内容を初期状態へ戻すなら、
type=”reset”
があります。
特にフォーム内部では、buttonの役割を明示しておくとコードを読んだときにも意図が分かりやすくなります。
ボタンの文言も、「送信」だけではなく、
お問い合わせを送信
など、次に何が起こるか分かる表現を検討します。
disabledとreadonlyは同じではない
入力できない状態を作るときには、disabledとreadonlyがあります。
見た目が似る場合がありますが、意味や動作は同じではありません。
disabledは、そのフォームコントロール自体を無効化します。
一般的にはフォーカスできず、フォーム送信時のデータにも含まれません。
readonlyは、値を編集できなくします。
readonlyに対応するコントロールは通常フォーカスでき、
name属性があればフォーム送信時のデータにも含まれます。
一方、disabledのコントロールは通常フォーカスできず、
フォーム送信時のデータにも含まれません。
readonlyはselect・checkbox・radioなどには使用できない点にも注意します。
何を選ぶかは、
なぜユーザーが変更できないのか
から考えます。
buttonのtypeとdisabled・readonlyを確認します。
<label for="customer-id">お客様番号</label>
<input
type="text"
id="customer-id"
name="customer-id"
value="TL-12345"
readonly
>
<label for="system-status">システム状態</label>
<input
type="text"
id="system-status"
value="確認中"
disabled
>
<button type="submit">
お問い合わせを送信
</button>
<button type="button">
入力内容を確認
</button>
<button type="reset">
入力内容をリセット
</button>HTML使いやすいフォームはアクセシビリティまで考える
フォームは、入力できるだけでは十分とは限りません。
誰が使っても、
「何を入力するのか」
「どこで間違えたのか」
「次に何をすればよいのか」
が分かりやすいことが重要です。

labelを見える状態で用意する
placeholderだけに頼らず、何を入力する項目なのか分かるlabelを用意します。
補助情報を入力項目と関連付ける
入力形式や注意事項などの補助情報が必要な場合があります。
HTMLだけでは足りない場面では、aria-describedbyなどを使い、入力項目と補足説明の関係を明示する方法もあります。
ただし、
最初からARIAで作り直すのではなく、まず適切なHTML要素を使う
というNative HTML Firstの考え方は変わりません。
補助情報を関連付ける例を確認します。
<label for="email">メールアドレス</label>
<input
type="email"
id="email"
name="email"
autocomplete="email"
aria-describedby="email-help"
required
>
<small id="email-help">
返信を受け取れるメールアドレスを入力してください。
</small>HTMLキーボードだけでも操作できる構造を意識する
フォームの操作はマウスだけとは限りません。
Tabキーなどで入力項目を移動するユーザーもいます。
HTMLを自然な順序で記述し、不要なtabindexを追加しないことも重要です。
エラーは「間違っています」だけで終わらせない
入力に問題がある場合には、
「入力内容に誤りがあります」
だけではなく、
どの項目を、どのように直せばよいのか
が分かることが重要です。
ブラウザ標準のバリデーションを活かしながら、より高度な独自エラー表示が必要になった場合にJavaScriptなどを追加していきます。
HTML標準でお問い合わせフォームを組み立てる
ここまで確認した内容を1つのフォームへまとめてみます。
今回使用するのは、
・form
・label
・input
・select
・textarea
・fieldset
・legend
・button
・required
・autocomplete
・inputmode
などです。
特別なJavaScriptを使わなくても、HTMLだけでフォームの意味と基本的な入力補助をかなり表現できます。
次に全体例を確認します。
<form action="/contact" method="post">
<p>
<label for="name">お名前(必須)</label>
<input
type="text"
id="name"
name="name"
autocomplete="name"
required
>
</p>
<p>
<label for="email">メールアドレス(必須)</label>
<input
type="email"
id="email"
name="email"
autocomplete="email"
required
>
</p>
<p>
<label for="postal-code">郵便番号</label>
<input
type="text"
id="postal-code"
name="postal-code"
autocomplete="postal-code"
inputmode="numeric"
pattern="[0-9]{7}"
aria-describedby="postal-code-help"
>
<small id="postal-code-help">
ハイフンなし7桁で入力してください。
</small>
</p>
<p>
<label for="contact-type">お問い合わせ種別</label>
<select
id="contact-type"
name="contact-type"
required
>
<option value="">選択してください</option>
<option value="question">ご質問</option>
<option value="request">ご依頼</option>
<option value="other">その他</option>
</select>
</p>
<fieldset>
<legend>ご希望の連絡方法</legend>
<label>
<input
type="radio"
name="contact-method"
value="email"
>
メール
</label>
<label>
<input
type="radio"
name="contact-method"
value="tel"
>
電話
</label>
<label>
<input
type="radio"
name="contact-method"
value="either"
>
どちらでもよい
</label>
</fieldset>
<p>
<label for="message">お問い合わせ内容</label>
<textarea
id="message"
name="message"
rows="6"
required
></textarea>
</p>
<button type="submit">
お問い合わせを送信
</button>
</form>HTMLフォームを作るときは、
HTMLで意味と基本動作を作る
↓
CSSで見た目や状態を整える
↓
HTMLだけでは不足する操作や体験をJavaScriptで補う
という順番で考えると、役割を整理しやすくなります。
実務ではどこで使う?
お問い合わせフォーム
label・required・autocomplete・適切なinput typeを使うことで、入力項目の意味と入力補助をブラウザへ伝えられます。
会員登録やログイン
emailやpassword、autocompleteを適切に設定することで、ブラウザやパスワード管理機能とも連携しやすくなります。
検索フォーム
検索語句にはtype=”search”を検討できます。
スマートフォン向けフォーム
inputmodeなどを利用すると、入力する情報に適したキーボードを表示しやすくなります。
WordPressやCMS
フォーム系プラグインを利用する場合でも、label、required、入力タイプなどHTMLの意味を理解していると、設定内容を判断しやすくなります。
WordPressで実際にお問い合わせフォームを作る場合は、専用のフォームプラグインを使う方法もあります。
WPFormsは、ドラッグ&ドロップでフォームを作成できるWordPress向けフォームプラグインです。
HTMLのlabelやinput、requiredなどの意味を理解したうえでフォームビルダーを見ると、各設定が何をしているのかも理解しやすくなります。
実務では、
フォームが動くかどうか
だけではなく、
ユーザーが迷わず入力できるか
まで考えることが重要です。
迷ったときの確認ポイント
- この入力項目には何を入力してもらうのか
- labelで入力内容が明確になっているか
- 目的に合ったinput typeを使っているか
- 必須項目はrequiredだけでなく見た目でも分かるか
- autocompleteで入力を助けられないか
- スマートフォンではinputmodeが役立たないか
- placeholderをlabel代わりにしていないか
- 関連項目はfieldset・legendでまとめられないか
- ボタンを押したあと何が起きるか分かるか
- JavaScriptを書く前にHTML標準で解決できないか
今回できるようになったこと
・form・label・input・buttonの基本的な役割を整理できる
・labelのforとinputのidを関連付けられる
・fieldset・legendで関連項目をグループ化できる
・入力内容の意味からinput typeを選べる
・requiredで必須入力を指定できる
・autocompleteで入力補助を利用できる
・inputmodeの役割を理解できる
・select・textarea・placeholderを使い分けられる
・ブラウザ標準のバリデーションを活用できる
・disabledとreadonlyの違いを整理できる
・アクセシビリティを考えたフォーム設計へつなげられる
・フォームでもNative HTML Firstを実践できる
Modern HTML 1-4 ミニチェック
Q1
メールアドレスを入力する欄を作ります。
見た目が普通の1行入力欄だからという理由でtype=”text”を使うのではなく、メールアドレスとしての意味をブラウザへ伝えたい場合、どのtypeが候補になるでしょうか?
Q2
郵便番号を入力する欄があります。
数字だけで構成されているからという理由だけで、type=”number”を選べばよいでしょうか?
「数値」と「数字で構成された識別情報」の違いから考えてみてください。
Q3
入力欄の中に、
「例:山田 太郎」
というplaceholderが表示されています。
placeholderがあれば、labelを省略してもよいでしょうか?
ミニチェックの答えは次の記事の冒頭に掲載します。
「Modern HTML|ミニチェック回答・解説」
で確認できるようにします。
回答集では正解だけでなく、
なぜその要素になるのか
まで解説します。
まとめ
Modern HTML 1-4では、モダンなフォーム設計をHTML標準から考えました。
今回のポイントは、
・フォームは入力欄を並べるだけではない
・labelで入力項目の意味を伝える
・fieldset・legendで関連項目をまとめる
・input typeは入力内容の意味から選ぶ
・required・autocomplete・inputmodeなどHTML標準の機能を活かす
・placeholderはlabelの代わりにしない
・ブラウザ標準のバリデーションを活用する
・disabledとreadonlyの意味を分ける
・アクセシビリティまで含めてフォームを考える
という点です。
フォームを作るときに、
「JavaScriptでどう処理するか?」
より先に、
「HTMLだけでどこまで意味と基本動作を表現できるか?」
と考える。
これがModern HTMLシリーズで大切にしているNative HTML Firstにつながります。
前回を確認する
Modern HTML 1-3では、
見出し・文章・引用・リスト・figureなどを、見た目ではなくコンテンツの意味から選ぶ考え方
を整理しました。

次に読む
次回は、
Modern HTML 1-5|HTMLだけで作れるインタラクション
へ進みます。
details・summary・dialogなどを中心に、
JavaScriptを書く前にHTMLだけで実現できるインタラクション
を整理します。



