Bootstrap: フォームとフォームバリデーション

最終更新:2026-08-26

1. はじめに

(1) 前提条件

(2) 🎯 学習内容


(3) 課題

ボブはユーザー登録ページを開発しており、名前、メール、パスワード、国選択、利用規約への同意を収集する必要があります。Bootstrapのフォームクラスを使用すれば、CSSスタイルを一切書かずに、HTML構造とバリデーションロジックだけに集中できます。

(4) 解決策

フォームはユーザーと対話するための主要な方法です。Bootstrapは、統一されたフォームコントロールスタイルとバリデーションフィードバックシステムを提供し、フォーム開発を効率的で美しくします。

理解のポイント: Bootstrapフォーム = ネイティブブラウザコントロールのビューティーフィルターです。<input><select><textarea> のすべての要素が .form-control でラップされると、統一されたスタイル、間隔、インタラクティブフィードバックが付与されます。

(5) メリット

Bootstrapのフォームユーティリティクラスを使用することで、CSSスタイルコードを一切書かずに、HTML構造とバリデーションロジックに集中できます。


2. フォームコントロール

すべてのテキストベースの入力コントロールは .form-control を使用します。

▶ サンプル 基本的なフォーム

HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Form Demo</title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
  <div class="container py-4">
    <form>
      <div class="mb-3">
        <label for="name" class="form-label">Full Name</label>
        <input type="text" class="form-control" id="name" placeholder="Enter your name">
      </div>

      <div class="mb-3">
        <label for="country" class="form-label">Country</label>
        <select class="form-select" id="country">
          <option selected>Choose...</option>
          <option value="us">United States</option>
          <option value="jp">Japan</option>
          <option value="uk">United Kingdom</option>
        </select>
      </div>

      <div class="mb-3">
        <label class="form-label">Skills</label>
        <div class="form-check">
          <input class="form-check-input" type="checkbox" id="html" checked>
          <label class="form-check-label" for="html">HTML</label>
        </div>
        <div class="form-check">
          <input class="form-check-input" type="checkbox" id="css">
          <label class="form-check-label" for="css">CSS</label>
        </div>
      </div>

      <div class="mb-3">
        <label class="form-label">Experience Level</label>
        <div class="form-check">
          <input class="form-check-input" type="radio" name="level" id="beginner" checked>
          <label class="form-check-label" for="beginner">Beginner</label>
        </div>
        <div class="form-check">
          <input class="form-check-input" type="radio" name="level" id="advanced">
          <label class="form-check-label" for="advanced">Advanced</label>
        </div>
      </div>

      <button type="submit" class="btn btn-primary">Submit</button>
    </form>
  </div>
</body>
</html>
▶ 試してみよう

出力: Bootstrap 5.3でスタイルされたコンポーネント(例:ボタン、カード、カルーセル、折りたたみなど)の効果。ページはデフォルトのBootstrapテーマ(ライト)とレスポンシブグリッドを使用しています。



3. フォームコントロールの種類

コントロール クラス 説明
テキスト入力 form-control 1行テキスト、メール、パスワード、URLなど
テキストエリア form-control 複数行テキスト(rowsが行数を制御)
セレクト form-select ドロップダウン選択ボックス
チェックボックス form-check-input 複数選択
ラジオボタン form-check-input 単一選択(同じ名前で相互排他)
範囲 form-range スライダー
ファイル form-control ファイルアップロード


4. フォームレイアウト

(1) グリッドレイアウト

HTML
<div class="row">
  <div class="col-md-6 mb-3">
    <label for="firstName" class="form-label">First Name</label>
    <input type="text" class="form-control" id="firstName">
  </div>
  <div class="col-md-6 mb-3">
    <label for="lastName" class="form-label">Last Name</label>
    <input type="text" class="form-control" id="lastName">
  </div>
</div>
▶ 試してみよう

出力: Bootstrap 5.3でスタイルされたコンポーネント(例:ボタン、カード、カルーセル、折りたたみなど)の効果。ページはデフォルトのBootstrapテーマ(ライト)とレスポンシブグリッドを使用しています。

(2) インラインフォーム

HTML
<form class="row g-3">
  <div class="col-auto">
    <input type="search" class="form-control" placeholder="Search...">
  </div>
  <div class="col-auto">
    <button class="btn btn-primary" type="submit">Go</button>
  </div>
</form>
▶ 試してみよう

出力: Bootstrap 5.3でスタイルされたコンポーネント(例:ボタン、カード、カルーセル、折りたたみなど)の効果。ページはデフォルトのBootstrapテーマ(ライト)とレスポンシブグリッドを使用しています。

(3) 水平フォーム

HTML
<div class="row mb-3">
  <label for="email2" class="col-sm-2 col-form-label">Email</label>
  <div class="col-sm-10">
    <input type="email" class="form-control" id="email2">
  </div>
</div>
▶ 試してみよう

出力: Bootstrap 5.3でスタイルされたコンポーネント(例:ボタン、カード、カルーセル、折りたたみなど)の効果。ページはデフォルトのBootstrapテーマ(ライト)とレスポンシブグリッドを使用しています。



5. 入力グループ

HTML
<div class="input-group mb-3">
  <span class="input-group-text">@</span>
  <input type="text" class="form-control" placeholder="Username">
</div>

<div class="input-group mb-3">
  <input type="text" class="form-control" placeholder="Amount">
  <span class="input-group-text">.00</span>
</div>

<div class="input-group mb-3">
  <button class="btn btn-outline-secondary" type="button">Search</button>
  <input type="text" class="form-control" placeholder="Type to search">
</div>
▶ 試してみよう

出力: Bootstrap 5.3でスタイルされたコンポーネント(例:ボタン、カード、カルーセル、折りたたみなど)の効果。ページはデフォルトのBootstrapテーマ(ライト)とレスポンシブグリッドを使用しています。



6. フォームバリデーション

HTML
<form class="row g-3 needs-validation" novalidate>
  <div class="col-md-4">
    <label for="validationName" class="form-label">First Name</label>
    <input type="text" class="form-control" id="validationName" required>
    <div class="valid-feedback">Looks good!</div>
    <div class="invalid-feedback">Please enter your name.</div>
  </div>

  <div class="col-md-4">
    <label for="validationEmail" class="form-label">Email</label>
    <input type="email" class="form-control" id="validationEmail" required>
    <div class="valid-feedback">Valid email!</div>
    <div class="invalid-feedback">Please provide a valid email.</div>
  </div>

  <div class="col-12">
    <button class="btn btn-primary" type="submit">Submit</button>
  </div>
</form>

<script>
  (function() {
    var forms = document.querySelectorAll('.needs-validation')
    Array.prototype.slice.call(forms).forEach(function(form) {
      form.addEventListener('submit', function(event) {
        if (!form.checkValidity()) {
          event.preventDefault()
          event.stopPropagation()
        }
        form.classList.add('was-validated')
      }, false)
    })
  })()
</script>
▶ 試してみよう

出力: Bootstrap 5.3でスタイルされたコンポーネント(例:ボタン、カード、カルーセル、折りたたみなど)の効果。ページはデフォルトのBootstrapテーマ(ライト)とレスポンシブグリッドを使用しています。

(1) バリデーションフィードバックスタイル

クラス 条件 表示方法
.valid-feedback 入力が有効 緑色テキスト
.invalid-feedback 入力が無効 赤色テキスト
.was-validated フォーム送信後 すべてのフィードバックをトリガー
is-valid / is-invalid 手動制御 ステータスボーダー


7. その他のフォーム例

▶ サンプル 完全な登録フォーム(バリデーション付き)

HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Signup Form</title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
  <div class="container py-4">
    <div class="card mx-auto" style="max-width: 500px;">
      <div class="card-header bg-primary text-white">
        <h4 class="mb-0">Create Account</h4>
      </div>
      <div class="card-body">
        <form class="needs-validation" novalidate>
          <div class="mb-3">
            <label for="fullName" class="form-label">Full Name</label>
            <input type="text" class="form-control" id="fullName" required>
            <div class="invalid-feedback">Please enter your name.</div>
          </div>
          <div class="mb-3">
            <label for="signupEmail" class="form-label">Email</label>
            <input type="email" class="form-control" id="signupEmail" required>
            <div class="invalid-feedback">Please enter a valid email.</div>
          </div>
          <div class="row mb-3">
            <div class="col-md-6">
              <label for="password" class="form-label">Password</label>
              <input type="password" class="form-control" id="password" minlength="8" required>
              <div class="invalid-feedback">Password must be at least 8 characters.</div>
            </div>
            <div class="col-md-6">
              <label for="confirmPwd" class="form-label">Confirm</label>
              <input type="password" class="form-control" id="confirmPwd" required>
              <div class="invalid-feedback">Passwords must match.</div>
            </div>
          </div>
          <div class="mb-3">
            <label for="countrySelect" class="form-label">Country</label>
            <select class="form-select" id="countrySelect" required>
              <option value="">Choose...</option>
              <option value="us">United States</option>
              <option value="uk">United Kingdom</option>
              <option value="jp">Japan</option>
            </select>
            <div class="invalid-feedback">Please select a country.</div>
          </div>
          <div class="mb-3 form-check">
            <input type="checkbox" class="form-check-input" id="agreeTerms" required>
            <label class="form-check-label" for="agreeTerms">I agree to the terms and conditions</label>
            <div class="invalid-feedback">You must agree to continue.</div>
          </div>
          <button type="submit" class="btn btn-primary w-100">Register</button>
        </form>
      </div>
    </div>
  </div>
  <script>
    (function() {
      var forms = document.querySelectorAll('.needs-validation')
      Array.prototype.slice.call(forms).forEach(function(form) {
        form.addEventListener('submit', function(event) {
          if (!form.checkValidity()) {
            event.preventDefault()
            event.stopPropagation()
          }
          form.classList.add('was-validated')
        }, false)
      })
    })()
  </script>
</body>
</html>
▶ 試してみよう

出力: Bootstrap 5.3でスタイルされたコンポーネント(例:ボタン、カード、カルーセル、折りたたみなど)の効果。ページはデフォルトのBootstrapテーマ(ライト)とレスポンシブグリッドを使用しています。

▶ サンプル 検索フォーム(入力グループ)

HTML
<form class="container py-4">
  <div class="row g-2">
    <div class="col-md-3">
      <select class="form-select">
        <option selected>All Categories</option>
        <option value="electronics">Electronics</option>
        <option value="clothing">Clothing</option>
        <option value="books">Books</option>
      </select>
    </div>
    <div class="col-md-6">
      <div class="input-group">
        <input type="search" class="form-control" placeholder="Search products...">
        <button class="btn btn-primary" type="submit">Search</button>
      </div>
    </div>
    <div class="col-md-3">
      <button class="btn btn-outline-secondary w-100" type="button">Advanced Filters</button>
    </div>
  </div>
</form>
▶ 試してみよう

出力: Bootstrap 5.3でスタイルされたコンポーネント(例:ボタン、カード、カルーセル、折りたたみなど)の効果。ページはデフォルトのBootstrapテーマ(ライト)とレスポンシブグリッドを使用しています。

▶ サンプル インラインフォーム

HTML
<form class="row row-cols-lg-auto g-3 align-items-center">
  <div class="col-12">
    <input type="text" class="form-control" placeholder="Username">
  </div>
  <div class="col-12">
    <input type="password" class="form-control" placeholder="Password">
  </div>
  <div class="col-12">
    <div class="form-check">
      <input class="form-check-input" type="checkbox" id="rememberMe">
      <label class="form-check-label" for="rememberMe">Remember me</label>
    </div>
  </div>
  <div class="col-12">
    <button type="submit" class="btn btn-primary">Sign In</button>
  </div>
</form>
▶ 試してみよう

出力: Bootstrap 5.3でスタイルされたコンポーネント(例:ボタン、カード、カルーセル、折りたたみなど)の効果。ページはデフォルトのBootstrapテーマ(ライト)とレスポンシブグリッドを使用しています。

▶ サンプル フローティングラベルフォーム

HTML
<div class="container py-4" style="max-width: 400px;">
  <form>
    <div class="form-floating mb-3">
      <input type="email" class="form-control" id="floatingEmail" placeholder="name@example.com">
      <label for="floatingEmail">Email address</label>
    </div>
    <div class="form-floating mb-3">
      <input type="password" class="form-control" id="floatingPassword" placeholder="Password">
      <label for="floatingPassword">Password</label>
    </div>
    <div class="form-floating mb-3">
      <select class="form-select" id="floatingSelect">
        <option value="">Choose...</option>
        <option value="free">Free Plan</option>
        <option value="pro">Pro Plan</option>
        <option value="enterprise">Enterprise</option>
      </select>
      <label for="floatingSelect">Subscription Plan</label>
    </div>
    <div class="form-floating mb-3">
      <textarea class="form-control" id="floatingTextarea" style="height: 100px" placeholder="Comments"></textarea>
      <label for="floatingTextarea">Message</label>
    </div>
    <button class="btn btn-primary w-100">Submit</button>
  </form>
</div>
▶ 試してみよう

出力: Bootstrap 5.3でスタイルされたコンポーネント(例:ボタン、カード、カルーセル、折りたたみなど)の効果。ページはデフォルトのBootstrapテーマ(ライト)とレスポンシブグリッドを使用しています。

(1) フォームレイアウト決定フロー

100%
flowchart TD
    A[フォームの設計を開始] --> B{フィールド数}
    B -->|1-3| C[単純なスタック<br/>mb-3で区切る]
    B -->|4-8| D{グループ化が必要?}
    D -->|はい| E[グリッドレイアウト<br/>row + col-*]
    D -->|いいえ| F[インライン/水平レイアウト]
    B -->|8以上| G[複数カラムのグリッド<br/>または段階的表示]
    E --> H{プレフィックスが必要?}
    H -->|はい| I[input-group]
    H -->|いいえ| J[直接 form-control]
    F --> K{フローティングラベル?}
    K -->|はい| L[form-floating]
    K -->|いいえ| M[通常のラベル]

出力: Bootstrap 5.3でスタイルされたコンポーネント(例:ボタン、カード、カルーセル、折りたたみなど)の効果。ページはデフォルトのBootstrapテーマ(ライト)とレスポンシブグリッドを使用しています。

フォームコントロール クラス 適用可能なデータ型
1行テキスト form-control 名前、メール、パスワード
複数行テキスト form-control (textarea) コメント、説明
ドロップダウン選択 form-select 国、カテゴリ、オプション
チェックボックス form-check-input 複数選択、利用規約同意
ラジオボタン form-check-checkbox-input (radio) 性別、レベル、オプション
スライダー form-range 価格帯、評価
ファイルアップロード form-control (file) 画像、ドキュメント
入力グループのバリアント コードパターン 用途
プレフィックステキスト input-group-text + form-control 金額 $、ユーザー名 @ プレフィックス
サフィックステキスト form-control + input-group-text サフィックス .00、単位 px
プレフィックスボタン button + form-control 検索ボックス
サフィックスボタン form-control + button パスワード表示切替
複数要素 複数の input-group-text 日付範囲、組み合わせ入力
バリデーション状態 クラス ボーダー フィードバックテキスト
有効 is-valid valid-feedback
無効 is-invalid invalid-feedback
送信後 was-validated 自動切替 すべてのフィードバックをトリガー
ツールチップ valid-tooltip と組み合わせ 上記と同じ バブルスタイルのヒント

❓ よくある質問

Q なぜフォームコントロールには独自の幅がないのですか?
A .form-control はデフォルトで width: 100% です。幅を制御するには、グリッドカラム (col-*) の内側に配置するか、style="width: 300px" を追加します。
Q .form-label の目的は何ですか?
A <label> の間隔 (margin-bottom: 0.5rem) とフォントサイズを統一します。なくても動作しますが、一貫性のために追加することをお勧めします。
Q フォームバリデーションのエラーメッセージをカスタマイズできますか?
A はい。<div class="invalid-feedback"> の中身は任意のテキストにできます。さらに、setCustomValidity() メソッドもサポートされています。
Q 入力グループに複数の要素をネストできますか?
A はい。input-group には複数の input-group-textform-control、ボタンを含めることができます。
Q フローティングラベル (form-floating) はすべてのブラウザをサポートしていますか?
A フローティングラベルはCSSの :placeholder-shown 疑似クラスを使用しており、モダンブラウザでサポートされています。IEはサポートしていませんが、IEはメンテナンスが終了しています。非常に古いブラウザをサポートする必要がある場合は、従来のラベルレイアウトを使用することをお勧めします。

📖 まとめ


📝 練習問題

  1. ⭐ 完全な登録フォームを作成してください: 名前(テキスト)、年齢(数値)、国(セレクト)、パスワード(パスワード)、パスワード確認。すべてBootstrapスタイルを使用すること。
  2. ⭐⭐ 課題1のフォームにバリデーションを実装してください: 名前は必須で2〜20文字、パスワードは8文字以上、メールは正しい形式であること。条件を満たさない場合、赤い invalid-feedback を表示すること。
  3. ⭐⭐⭐ 検索入力グループを作成してください: 左側にカテゴリ選択用の form-select + 中央に form-control 検索ボックス + 右側に検索ボタン。

前のレッスン: テーブル · 次のレッスン: カルーセルとモーダル

Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%