HTMLでお問い合わせフォームを作るには、form要素の中へlabel、input、textarea、送信ボタンを配置します。見た目だけならHTMLとCSSで作れますが、入力内容をメール送信・保存する処理にはPHPなどのサーバー側プログラムやフォームサービスが必要です。
この記事では、コピーして試せる完成コードを使いながら、各タグと属性の役割、スマートフォン対応、入力チェック、アクセシビリティ、安全に公開するための注意点まで初心者向けに解説します。
HTMLお問い合わせフォームの完成イメージ
今回は「お名前」「メールアドレス」「電話番号」「お問い合わせ内容」「同意確認」を持つフォームを作ります。パソコンでもスマートフォンでも入力欄が横にはみ出さず、キーボード操作中のフォーカス位置も分かるデザインです。

作業用フォルダにindex.htmlとstyle.cssを用意してください。HTMLファイルからCSSファイルを読み込む基本形で進めます。
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>お問い合わせ</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="contact-page">
<h1>お問い合わせ</h1>
<p>必要事項を入力し、「送信内容を確認する」を押してください。</p>
<form class="contact-form" action="/contact/submit" method="post">
<div class="form-field">
<label for="name">
お名前 <span class="required" aria-hidden="true">必須</span>
</label>
<input
type="text"
id="name"
name="name"
autocomplete="name"
required
>
</div>
<div class="form-field">
<label for="email">
メールアドレス <span class="required" aria-hidden="true">必須</span>
</label>
<input
type="email"
id="email"
name="email"
autocomplete="email"
aria-describedby="email-help"
required
>
<p class="form-help" id="email-help">返信先として使用します。</p>
</div>
<div class="form-field">
<label for="tel">電話番号 <span class="optional">任意</span></label>
<input
type="tel"
id="tel"
name="tel"
autocomplete="tel"
>
</div>
<div class="form-field">
<label for="message">
お問い合わせ内容 <span class="required" aria-hidden="true">必須</span>
</label>
<textarea
id="message"
name="message"
rows="8"
minlength="10"
maxlength="1000"
required
></textarea>
</div>
<div class="form-check">
<input type="checkbox" id="privacy" name="privacy" value="agreed" required>
<label for="privacy">プライバシーポリシーに同意します</label>
</div>
<button type="submit">送信内容を確認する</button>
</form>
</main>
</body>
</html>action="/contact/submit"は説明用の送信先です。そのままでは送信できないため、実際に公開するときは自分で用意したサーバー側処理や利用するフォームサービスの送信先へ置き換えてください。
お問い合わせフォームをCSSで整える
次のCSSでは、フォームの最大幅を決め、入力欄を親要素の幅いっぱいに広げます。box-sizing: border-boxも指定するため、paddingと枠線を加えても画面からはみ出しません。
:root {
color: #172033;
background: #f4f7fb;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.contact-page {
width: min(100% - 32px, 720px);
margin: 64px auto;
}
.contact-page h1 {
margin-bottom: 8px;
}
.contact-form {
display: grid;
gap: 24px;
margin-top: 32px;
padding: 32px;
border: 1px solid #d7deea;
border-radius: 16px;
background: #ffffff;
box-shadow: 0 16px 40px rgb(23 32 51 / 8%);
}
.form-field {
display: grid;
gap: 8px;
}
.form-field label,
.form-check label {
font-weight: 700;
}
.required,
.optional {
display: inline-block;
margin-left: 8px;
padding: 2px 8px;
border-radius: 999px;
font-size: 0.75rem;
font-weight: 700;
}
.required {
color: #9f1d20;
background: #fff0f0;
}
.optional {
color: #475569;
background: #eef2f7;
}
input,
textarea,
button {
font: inherit;
}
input[type="text"],
input[type="email"],
input[type="tel"],
textarea {
width: 100%;
padding: 12px 14px;
border: 1px solid #aeb8c8;
border-radius: 8px;
color: #172033;
background: #ffffff;
}
textarea {
min-height: 180px;
resize: vertical;
}
input:focus-visible,
textarea:focus-visible,
button:focus-visible {
outline: 3px solid #2563eb;
outline-offset: 2px;
}
.form-help {
margin: 0;
color: #526077;
font-size: 0.875rem;
}
.form-check {
display: flex;
align-items: flex-start;
gap: 10px;
}
.form-check input {
width: 20px;
height: 20px;
margin: 2px 0 0;
}
button[type="submit"] {
min-height: 48px;
padding: 12px 24px;
border: 0;
border-radius: 8px;
color: #ffffff;
background: #d83a43;
font-weight: 700;
cursor: pointer;
}
button[type="submit"]:hover {
background: #b72b34;
}
@media (max-width: 600px) {
.contact-page {
margin-block: 32px;
}
.contact-form {
gap: 20px;
padding: 20px;
}
}ブラウザで表示し、画面幅を狭めてみましょう。入力欄とボタンがフォーム内に収まり、スマートフォンでは外側と内側の余白が少し小さくなれば成功です。
フォームの横幅に使ったwidthとmin()の考え方は、次の記事でも詳しく確認できます。
formタグのactionとmethodを設定する
form要素は、入力欄と送信ボタンを一つのフォームとしてまとめます。送信に関係する主な属性はactionとmethodです。
| 属性 | 役割 | 例 |
|---|---|---|
action | 入力データを送るURLを指定する | /contact/submit |
method | HTTPの送信方法を指定する | getまたはpost |
autocomplete | フォーム全体の自動入力方針を伝える | onまたはoff |
お問い合わせフォームでは通常postを使う
getでは入力値がURLのクエリ文字列に含まれます。サイト内検索のようにURLを共有したい処理に向きますが、氏名やメールアドレスを扱うお問い合わせフォームには適しません。
postでは入力値をリクエスト本文へ入れて送ります。ただし、postを使うだけで暗号化されるわけではありません。公開サイトではHTTPSを使用し、サーバー側でも安全に処理してください。
<form action="/contact/submit" method="post">
<!-- 入力欄と送信ボタンを入れる -->
</form>labelとinputで一行の入力欄を作る
labelは、入力欄へ何を入力するのかを表示する要素です。labelのforと入力欄のidを同じ値にすると、ラベルをクリックしたときにも入力欄へフォーカスできます。
<label for="email">メールアドレス</label>
<input
type="email"
id="email"
name="email"
autocomplete="email"
required
>idはページ内で入力欄を識別し、labelやCSS、JavaScriptから参照するときに使います。nameは送信時の項目名になるため、サーバー側が期待する名前と一致させる必要があります。
| type | 用途 | ブラウザの補助 |
|---|---|---|
text | 氏名や件名などの一行テキスト | 一般的な文字入力欄を表示する |
email | メールアドレス | 形式を検証し、端末に合うキーボードを出しやすい |
tel | 電話番号 | 数字を入力しやすいキーボードを出しやすい |
checkbox | 同意や複数選択 | オン・オフできる選択欄を表示する |
placeholderだけで項目名を表すと、入力後に何の欄だったか分からなくなります。表示されるlabelを用意し、placeholderは入力例などの補助にだけ使いましょう。
textareaでお問い合わせ内容の入力欄を作る
複数行の文章にはtextareaを使います。開始タグと終了タグの間に空白や改行を入れると初期値として扱われるため、空欄にしたい場合はタグを続けて記述します。
<label for="message">お問い合わせ内容</label>
<textarea
id="message"
name="message"
rows="8"
minlength="10"
maxlength="1000"
required
></textarea>rowsは表示する行数の目安、minlengthとmaxlengthは入力できる文字数の範囲です。CSSでresize: verticalを指定しておくと、読者は必要に応じて高さだけを変更できます。
textareaの基本とデザイン例を詳しく確認したい方は、こちらの記事も参考にしてください。
buttonで送信ボタンを作る
フォームを送信するボタンにはbutton要素を使い、type="submit"を指定します。フォーム内のbuttonは既定でsubmitとして扱われますが、役割を明確にするためtypeを省略しない方が安全です。
<button type="submit">送信内容を確認する</button>送信ボタンと別ページへ移動するリンクは役割が違います。ボタンとリンクの使い分けは、次の記事で詳しく解説しています。
requiredとtypeで入力内容をチェックする
requiredを付けた項目が空のまま送信されると、ブラウザが標準のエラーを表示します。type="email"ならメールアドレスとして妥当な形式かも確認されます。
<input
type="email"
id="email"
name="email"
autocomplete="email"
required
>この検証は入力ミスを減らすための補助であり、セキュリティ対策ではありません。HTML属性はブラウザの開発者ツールなどで変更できるため、サーバー側でも必須・形式・文字数を必ず再検証します。
autocompleteで自動入力を助ける
autocomplete="name"、email、telのように入力内容の種類を伝えると、ブラウザが保存済み情報を適切な欄へ提案しやすくなります。長いフォームほど入力の負担を減らせます。
使いやすくアクセシブルなフォームにする
お問い合わせフォームは、見た目だけでなく「何を入力するか」「どこで間違えたか」が分かることが重要です。次の点を確認しましょう。
- すべての入力欄に内容を説明するlabelを関連付ける
- 必須・任意を色だけでなく文字でも示す
- 必要な情報だけを尋ね、項目を増やしすぎない
- 入力形式や文字数に条件がある場合は入力前に説明する
- エラーは対象項目の近くへ、修正方法が分かる文章で表示する
- フォーカスの枠線を消さず、キーボードで現在位置が分かるようにする
- 関連するラジオボタンやチェックボックスはfieldsetとlegendでまとめる
- 送信成功後は受付が完了したことを明確に伝える
labelを関連付けると、支援技術が入力欄の目的を読み上げられるだけでなく、ラベル部分もクリックできるため操作しやすくなります。placeholderやアイコンだけで項目名を表さないことが大切です。
HTMLだけではメール送信できない
HTMLの役割は入力画面を作り、指定された送信先へデータを渡すところまでです。メール送信、データベースへの保存、自動返信、確認画面の表示には、次のいずれかが必要です。
- PHP、Ruby、Node.jsなどで作ったサーバー側プログラム
- WordPressのフォームプラグイン
- 外部のフォーム作成・送信サービス
- 静的サイト向けホスティングのフォーム機能やサーバーレス関数
サーバー側では、入力値の再検証、HTMLエスケープ、CSRF対策、送信回数の制限、スパム対策、ログへ個人情報を残しすぎない設計などが必要です。受信メールへ入力値をそのままヘッダーとして使うことも避けてください。
WordPressならフォームプラグインを使える
WordPressでは、送信処理を一から開発せずフォームプラグインを利用できます。Contact Form 7でフォームを作る手順はこちらの記事で確認できます。
公開前の確認チェックリスト
見た目が完成しても、実際に問い合わせを受け取れるとは限りません。公開前と更新後に、次の項目を実際の端末で確認してください。
- パソコンとスマートフォンで入力欄がはみ出さない
- labelを押すと対応する入力欄へフォーカスする
- Tabキーだけで全項目と送信ボタンへ移動できる
- 必須項目、メール形式、文字数のエラーが分かる
- 確認画面から戻っても入力内容が必要に応じて保持される
- 送信完了メッセージと自動返信が届く
- 管理者宛てメールが迷惑メールへ入らない
- 同じ問い合わせが二重送信されない
- HTTPSで送信され、個人情報の扱いがプライバシーポリシーと一致する
まとめ
HTMLのお問い合わせフォームは、formの中へlabel、input、textarea、buttonを配置して作ります。labelのforと入力欄のidを対応させ、送信に使うname、用途に合うtype、required、autocompleteも設定しましょう。
CSSでは入力欄を幅100%にし、スマートフォンでも読みやすい余白とフォーカス表示を用意します。そして、HTMLだけではメール送信できないため、公開時は安全なサーバー側処理・WordPressプラグイン・フォームサービスのいずれかへ接続してください。
