WithCodeMedia-1-pc
previous arrowprevious arrow
next arrownext arrow

WithCodeMedia-1-sp
previous arrowprevious arrow
next arrownext arrow

【2026年版】CSSフォームデザイン集|お問い合わせフォームをコピペで整える

生徒

お問い合わせフォームを作ったんですが、入力欄の見た目がブラウザごとにバラバラで…。どこから直せばいいですか?

ペン博士

フォームはブラウザ標準スタイルを打ち消してから積み上げるのがコツだよ。今日は入力欄・セレクト・チェックボックス・ボタンまで、コピペで使える形で順番に渡すね。

お問い合わせフォームは、サイトの中で最もコンバージョンに近い場所です。それなのに、入力欄の高さがバラバラだったり、スマホでタップすると画面が勝手に拡大したりと、細かい粗が残りやすいパーツでもあります。

原因のほとんどは「ブラウザが最初から当てているスタイル」です。inputselectはブラウザごとに独自の見た目を持っているため、そこを整えないまま装飾を足すと差が出ます。

この記事では、ベースのリセットから入力欄・セレクトボックス・チェックボックス・送信ボタン・レイアウト・フォーカス表示まで、コピペしてそのまま使えるCSSを順番に紹介します。最後に全部入りの完成版フォームも置いています。

  • フォームの見た目が崩れる原因(ブラウザ標準スタイル)
  • 最初に入れておくベーススタイル
  • 入力欄(input・textarea)のデザイン3パターン
  • セレクトボックスを自作矢印で整える方法
  • チェックボックス・ラジオボタンのカスタマイズ
  • 送信ボタンのデザインとホバー演出
  • ラベル配置と2カラムレイアウト
  • フォーカス表示とアクセシビリティ配慮
  • 入力エラーの見せ方(:user-invalid)
  • スマホでの入力体験(16px問題・inputmode)
  • コピペ用の完成版お問い合わせフォーム

目次

フォームの見た目が崩れる原因

フォームが崩れる4つの原因

最初に、なぜフォームだけ他のパーツより崩れやすいのかを押さえておきましょう。原因を知っていれば、対処は一度で済みます。

フォーム部品はブラウザが独自に描画しています。ボタンの角丸、セレクトの矢印、チェックボックスの四角はすべてOSとブラウザが用意した見た目で、CSSを当てていない状態では環境ごとに違う姿になります。

  • フォント:input系は親のフォントを継承しない(明朝やSF Proになる)
  • サイズ計算box-sizingの指定がないとpaddingで幅がはみ出す
  • 独自描画:selectの矢印やcheckboxはOS側の部品が出る
  • フォーカス:ブラウザ既定のアウトラインが色・太さともバラバラ

つまり、装飾の前に「継承させる」「計算をそろえる」「独自描画を消す」の3点を済ませておけば、あとは自由に作れます。

最初に入れるベーススタイル

すべてのフォームに共通で入れておくリセットです。これだけで、環境差の大半が消えます。

/* フォーム共通のベース */
input,
textarea,
select,
button {
  font: inherit;          /* 親のフォントを継承させる */
  color: inherit;
  box-sizing: border-box; /* padding込みで幅を計算 */
  max-width: 100%;
}

/* ブラウザ独自の見た目を消す */
input,
textarea,
select {
  appearance: none;
  -webkit-appearance: none;
  background-color: #fff;
  border: 1px solid #d1d5db;
  border-radius: 8px;
  padding: 0.75em 1em;
  width: 100%;
}

/* テキストエリアは縦だけリサイズ可に */
textarea {
  min-height: 8em;
  resize: vertical;
  line-height: 1.7;
}

ポイントはfont: inheritbox-sizing: border-boxの2つです。特にfontの継承漏れは、フォームだけ書体が違うという違和感の主犯なので必ず入れてください。

appearance: noneはセレクトの矢印やiOSの丸みを消します。消したあとは自分で見た目を足す前提なので、次のセクションから順に組み立てます。

入力欄(input・textarea)のデザイン3パターン

入力欄スタイルの選び分け

入力欄はサイトの雰囲気に合わせて選べるよう、3種類用意しました。どれもコピペで動きます。

1. 下線だけのミニマルスタイル

.form-underline input,
.form-underline textarea {
  border: none;
  border-bottom: 2px solid #d1d5db;
  border-radius: 0;
  padding: 0.6em 0.2em;
  background: transparent;
  transition: border-color .2s;
}

.form-underline input:focus,
.form-underline textarea:focus {
  border-bottom-color: #0ea5e9;
  outline: none;
}

余白の広いデザインや、コーポレートサイトの静かなトーンに合います。枠がない分、ラベルとの距離をしっかり取るのがコツです。

2. 枠線ボックススタイル(定番)

.form-box input,
.form-box textarea {
  border: 1px solid #d1d5db;
  border-radius: 8px;
  padding: 0.8em 1em;
  transition: border-color .2s, box-shadow .2s;
}

.form-box input:focus,
.form-box textarea:focus {
  border-color: #0ea5e9;
  box-shadow: 0 0 0 3px rgba(14, 165, 233, .18); /* 外側に光る枠 */
  outline: none;
}

迷ったらこれです。フォーカス時にbox-shadowで外側に光る枠を出すと、どこを入力しているかが一目で伝わります。

3. 塗りつぶし(Filled)スタイル

.form-filled input,
.form-filled textarea {
  border: 1px solid transparent;
  border-radius: 10px;
  background-color: #f3f4f6;
  padding: 0.85em 1em;
  transition: background-color .2s, border-color .2s;
}

.form-filled input:focus,
.form-filled textarea:focus {
  background-color: #fff;
  border-color: #0ea5e9;
  outline: none;
}

入力欄が背景から浮いて見えるので、フォームだと気づいてもらいやすい形です。入力中に白へ変わる動きで、状態の変化も伝わります。

セレクトボックスを自作矢印で整える

selectはブラウザ差が最も大きい部品です。appearance: noneで矢印を消し、背景画像またはラッパー要素で自分の矢印を置きます。

.select-wrap {
  position: relative;
  display: block;
}

.select-wrap select {
  appearance: none;
  -webkit-appearance: none;
  width: 100%;
  padding: 0.8em 2.6em 0.8em 1em; /* 右側に矢印のぶんの余白 */
  border: 1px solid #d1d5db;
  border-radius: 8px;
  background-color: #fff;
  cursor: pointer;
}

/* 擬似要素で三角の矢印を描く */
.select-wrap::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 1em;
  width: 8px;
  height: 8px;
  border-right: 2px solid #6b7280;
  border-bottom: 2px solid #6b7280;
  transform: translateY(-70%) rotate(45deg);
  pointer-events: none; /* クリックをselectに通す */
}
<div class="select-wrap">
  <select name="subject">
    <option value="">お問い合わせ内容を選択</option>
    <option value="estimate">お見積りについて</option>
    <option value="service">サービス内容について</option>
    <option value="other">その他</option>
  </select>
</div>

忘れやすいのがpointer-events: noneです。これが無いと矢印の上をクリックしても反応しないフォームになります。

チェックボックス・ラジオボタンのカスタマイズ

チェックボックスは標準の四角を消して、自前の四角と「レ点」を描くのが定番です。labelで囲むと、文字をタップしても切り替わります。

.check {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  cursor: pointer;
}

.check input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  width: 22px;
  height: 22px;
  flex: none;
  border: 2px solid #d1d5db;
  border-radius: 6px;
  position: relative;
  transition: background-color .15s, border-color .15s;
}

/* チェック時の色とレ点 */
.check input[type="checkbox"]:checked {
  background-color: #0ea5e9;
  border-color: #0ea5e9;
}

.check input[type="checkbox"]:checked::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 6px;
  height: 11px;
  border-right: 2px solid #fff;
  border-bottom: 2px solid #fff;
  transform: rotate(45deg) translate(-1px, -1px);
}

/* ラジオは丸くして中に点を置く */
.check input[type="radio"] {
  appearance: none;
  -webkit-appearance: none;
  width: 22px;
  height: 22px;
  flex: none;
  border: 2px solid #d1d5db;
  border-radius: 50%;
  position: relative;
}

.check input[type="radio"]:checked {
  border-color: #0ea5e9;
}

.check input[type="radio"]:checked::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background-color: #0ea5e9;
}
<label class="check">
  <input type="checkbox" name="agree" value="1">
  <span>プライバシーポリシーに同意する</span>
</label>

flex: noneを入れておくと、文言が長く折り返したときも四角が縦に潰れません。細かいですが、同意チェックは文章が長くなりがちなので効きます。

送信ボタンのデザインとホバー演出

送信ボタンはフォームの結論です。押せる場所だと一目で分かる大きさと、押した感触が返る動きを付けます。

.form-submit {
  display: block;
  width: 100%;
  max-width: 320px;
  margin-inline: auto;
  padding: 1em 2em;
  border: none;
  border-radius: 999px;
  background-color: #0ea5e9;
  color: #fff;
  font-weight: 700;
  cursor: pointer;
  transition: transform .15s, box-shadow .15s, background-color .15s;
  box-shadow: 0 4px 0 #0284c7;
}

.form-submit:hover {
  background-color: #0284c7;
}

.form-submit:active {
  transform: translateY(3px);   /* 押し込まれる動き */
  box-shadow: 0 1px 0 #0284c7;
}

/* 送信できない状態は見た目でも伝える */
.form-submit:disabled {
  background-color: #cbd5e1;
  box-shadow: none;
  cursor: not-allowed;
}

:activeで沈み込ませ、影を薄くすると物理ボタンのような手応えになります。送信処理中はdisabledを付けて二重送信も防ぎましょう。

ラベル配置と2カラムレイアウト

入力項目の並べ方は、PCでは2カラム、スマホでは1カラムに落とすのが基本です。Gridなら数行で切り替えられます。

.form-grid {
  display: grid;
  gap: 1.25rem 1.5rem;
  grid-template-columns: 1fr 1fr;
}

/* 住所や本文など、横幅いっぱい使いたい項目 */
.form-grid .full {
  grid-column: 1 / -1;
}

.form-field label {
  display: block;
  margin-bottom: 0.4em;
  font-weight: 700;
  font-size: 0.95em;
}

/* 必須マーク */
.form-field .req {
  margin-left: 0.5em;
  padding: 0.1em 0.5em;
  border-radius: 4px;
  background-color: #ef4444;
  color: #fff;
  font-size: 0.75em;
}

@media (max-width: 640px) {
  .form-grid {
    grid-template-columns: 1fr; /* スマホは縦積み */
  }
}

ラベルは入力欄の真上に置くのが最も速く読める配置です。左横並びは視線移動が増え、スマホでは折り返して崩れやすいので避けます。

フォーカス表示とアクセシビリティ

フォーカス表示の整え方

outline: noneだけ書いて終わりにすると、キーボード操作の人が現在位置を見失います。消すなら代わりを必ず用意します。

/* マウスクリック時は出さず、キーボード操作時だけ出す */
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
button:focus-visible {
  outline: 3px solid #0ea5e9;
  outline-offset: 2px;
}

/* ラベルと入力欄の関連付けが取れていれば読み上げも通る */
.form-field label {
  cursor: pointer;
}
<div class="form-field">
  <label for="email">メールアドレス<span class="req">必須</span></label>
  <input type="email" id="email" name="email" autocomplete="email" required>
</div>
  • labelforinputidを必ず一致させる
  • :focus-visibleを使えば、マウス操作では枠が出ず見た目も保てる
  • 色だけで必須やエラーを伝えず、文字でも示す

入力エラーの見せ方

HTMLの検証機能とCSSを組み合わせると、JavaScriptなしでも入力状態を伝えられます。ポイントは:user-invalidを使うことです。

/* 一度入力して離れた後にだけエラー色にする */
input:user-invalid,
textarea:user-invalid {
  border-color: #ef4444;
  background-color: #fef2f2;
}

input:user-invalid + .error-text {
  display: block;
}

.error-text {
  display: none;
  margin-top: 0.4em;
  color: #dc2626;
  font-size: 0.9em;
}

/* 入力が正しいときは静かに知らせる */
input:user-valid {
  border-color: #10b981;
}

従来の:invalidは、ページを開いた瞬間から未入力の必須項目を赤くしてしまいます。:user-invalid なら「触ったあと」だけ反応するので、初見で怒られる不快感がありません。

スマホでの入力体験を整える

スマホのフォームで最も多い不満は「タップしたら画面が拡大した」「キーボードが合わない」の2つです。どちらもすぐ直せます。

/* iOSは16px未満の入力欄でズームする */
input,
textarea,
select {
  font-size: 16px;
}

/* タップ領域は十分な高さを確保する */
input,
select,
.form-submit {
  min-height: 48px;
}
<input type="tel" name="tel" inputmode="numeric" autocomplete="tel" placeholder="09012345678">
<input type="email" name="email" inputmode="email" autocomplete="email">
<input type="text" name="zip" inputmode="numeric" autocomplete="postal-code">
属性役割指定例
inputmode出るキーボードの種類を変えるnumeric / email / tel
autocomplete保存済みの情報で自動入力させるemail / tel / postal-code
type入力形式の検証と初期キーボードemail / tel / url
font-size16px以上でiOSの自動ズームを防ぐ16px

この4点を入れるだけで、スマホの入力完了率は目に見えて変わります。特に電話番号と郵便番号はinputmode="numeric"を忘れずに。

コピペ用・完成版お問い合わせフォーム

ここまでの内容をまとめた、そのまま使える一式です。クラス名はプロジェクトに合わせて変えてください。

<form class="form-box" action="/contact/" method="post">
  <div class="form-grid">
    <div class="form-field">
      <label for="name">お名前<span class="req">必須</span></label>
      <input type="text" id="name" name="name" autocomplete="name" required>
    </div>
    <div class="form-field">
      <label for="email">メールアドレス<span class="req">必須</span></label>
      <input type="email" id="email" name="email" autocomplete="email" required>
      <span class="error-text">メールアドレスの形式で入力してください</span>
    </div>
    <div class="form-field full">
      <label for="subject">お問い合わせ内容</label>
      <div class="select-wrap">
        <select id="subject" name="subject">
          <option value="">選択してください</option>
          <option value="estimate">お見積りについて</option>
          <option value="service">サービス内容について</option>
        </select>
      </div>
    </div>
    <div class="form-field full">
      <label for="body">ご相談内容<span class="req">必須</span></label>
      <textarea id="body" name="body" required></textarea>
    </div>
    <div class="form-field full">
      <label class="check">
        <input type="checkbox" name="agree" value="1" required>
        <span>プライバシーポリシーに同意する</span>
      </label>
    </div>
  </div>
  <button type="submit" class="form-submit">送信する</button>
</form>
/* 完成版の土台(前述のベース+レイアウトをまとめたもの) */
.form-box {
  max-width: 720px;
  margin-inline: auto;
}

.form-box input,
.form-box select,
.form-box textarea {
  font: inherit;
  font-size: 16px;
  box-sizing: border-box;
  width: 100%;
  min-height: 48px;
  padding: 0.8em 1em;
  border: 1px solid #d1d5db;
  border-radius: 8px;
  background-color: #fff;
  appearance: none;
  -webkit-appearance: none;
  transition: border-color .2s, box-shadow .2s;
}

.form-box input:focus,
.form-box select:focus,
.form-box textarea:focus {
  border-color: #0ea5e9;
  box-shadow: 0 0 0 3px rgba(14, 165, 233, .18);
  outline: none;
}

よくある失敗と対処

症状から探すフォーム不具合

最後に、フォームで詰まりやすい点をまとめておきます。症状から逆引きしてください。

症状原因対処
入力欄だけ書体が違うfontが継承されないfont: inheritを指定
幅が親からはみ出すpaddingが幅に加算box-sizing: border-box
矢印を押しても開かない擬似要素がクリックを奪うpointer-events: none
タップで画面が拡大文字が16px未満入力欄を16px以上に
枠が消えて操作位置が不明outlineを消した:focus-visibleで代替
開いた瞬間に全部赤い:invalidを使用:user-invalidに変更

どれも装飾ではなく土台の指定漏れが原因です。ベーススタイルを最初に入れておけば、大半は発生しません。


まとめ

フォームのデザインは、ブラウザ標準スタイルを打ち消すベース作りから始めると一気に安定します。入力欄は下線・枠線・塗りつぶしの3パターンから選び、セレクトとチェックボックスはappearance: noneで消してから自作の矢印やレ点を描きます。仕上げに:focus-visibleでフォーカス表示を確保し、スマホでは16px以上とinputmodeを指定すれば、見た目と使いやすさの両方が揃ったフォームになります。

よくある質問(FAQ)

appearance: none を書くと何が消えますか?

セレクトの矢印、チェックボックスやラジオボタンの標準デザイン、iOSの角丸やグラデーションなど、ブラウザやOSが独自に描いている見た目が消えます。消したあとは自分でスタイルを当てる前提なので、矢印やレ点は擬似要素で描き直してください。

input のフォントが本文と違うのはなぜですか?

input・textarea・select・buttonは親要素のフォントを継承しない仕様のためです。font: inheritを指定すると、本文と同じ書体・サイズになります。フォーム崩れの相談で最も多い原因です。

スマホでタップすると画面が拡大してしまいます。

iOSのSafariは、文字サイズが16px未満の入力欄にフォーカスすると自動でズームします。入力欄のfont-sizeを16px以上にすれば止まります。viewportで拡大自体を禁止する方法は、拡大したい利用者を困らせるため推奨されません。

:invalid と :user-invalid の違いは何ですか?

:invalidはページ表示直後から条件を満たさない要素すべてに当たります。:user-invalidは利用者が入力して離れたあとにだけ当たるため、開いた瞬間に必須項目が赤くなる不快な表示を避けられます。

フォーカスのoutlineは消してもいいですか?

見た目のために消すこと自体は可能ですが、代わりの表示を必ず用意してください。キーボードだけで操作する人が現在位置を見失います。:focus-visibleを使えば、マウス操作時は出さずキーボード操作時だけ枠を出せます。

あわせて読みたい関連記事

CSS・Webデザイン実装の総まとめ

CSSの実装テクニックを「レイアウト・装飾・アニメーション・基礎・トラブル解決」の目的別に探せる総まとめページを用意しています。実装で迷ったときの索引としてどうぞ。

AIスキルで、未来の自分をアップデート!

今なら完全無料でAIを学べる!WithAI

今なら完全無料でAIを学べる!

  • 動画や実践で楽しく学べる:初心者でも安心のカリキュラム
  • スマホ・PCどちらでもOK:好きな時間に学習できる
  • 料金は一切ナシ0円でAIスキルが身につく

目的に合わせて選べる「AI副業」「AI転職」「AI活用」の3コースを用意。副収入・キャリアチェンジ・日常の生産性アップまで、あなたのゴールに合わせてAIを学べます。

会員登録はカンタン30秒で完了します。まずは公式LINEから、無料でAI学習をスタートしましょう!

この記事を書いた人

WithCodeでWeb制作を習得後、フリーランスエンジニアとして活動。HTML/CSS・JavaScript・WordPress案件を中心に年間20件以上の制作実績を持つ。「難しい技術をわかりやすく」をモットーに、初心者〜中級者向けの技術記事を執筆。副業・フリーランス独立を目指す方に向けた情報発信に注力している。

– service –WithGroupの運営サービス

  • WithCode
    - ウィズコード -

    スクール

    「未経験」から
    現場で通用する
    スキルを身に付けよう!

    詳細はこちら
  • WithFree
    - ウィズフリ -

    実案件サポート

    制作会社のサポート下で
    実務経験を積んでいこう!

    詳細はこちら

公式サイト より
今すぐ
無料カウンセリング
予約!

目次