Quick answer: Bootstrap forms are one class per element: form-label, form-control (inputs/textareas), form-select (dropdowns), wrapped in mb-3 divs. Validation comes in two flavors: browser-native (add required plus the was-validated class on submit) or custom messages with invalid-feedback divs and is-invalid/is-valid classes. This guide gives you the complete contact-form pattern that works everywhere.

The complete form pattern

<form class="needs-validation" novalidate>
  <div class="mb-3">
    <label for="email" class="form-label">Email</label>
    <input type="email" class="form-control" id="email" required>
    <div class="invalid-feedback">Please enter a valid email.</div>
  </div>
  <div class="mb-3">
    <label for="msg" class="form-label">Message</label>
    <textarea class="form-control" id="msg" rows="4" minlength="10" required></textarea>
    <div class="invalid-feedback">At least 10 characters, please.</div>
  </div>
  <button class="btn btn-primary" type="submit">Send</button>
</form>

<script>
document.querySelector('.needs-validation').addEventListener('submit', function (e) {
  if (!this.checkValidity()) { e.preventDefault(); }
  this.classList.add('was-validated');
});
</script>

How it works: novalidate disables the browser’s ugly default bubbles so Bootstrap’s green/red states take over. On submit, was-validated makes every invalid-feedback show for failed fields automatically — no per-field JavaScript. Native HTML rules (required, type="email", minlength) do the actual checking.

Layout: rows, columns and inline forms

GoalPattern
Two fields side by siderow + two col-md-6 wrappers around the mb-3 divs
Horizontal labelsrow mb-3 + col-sm-2 col-form-label + col-sm-10 input wrapper
Inline (search bar style)row row-cols-auto g-3 align-items-center + form-control + btn
Input with button attachedinput-group wrapping input + button
Help textform-text div under the input

Server-side reminder

Client validation is UX; the server must re-check everything. When your form actually sends data, our PHP contact form with reCAPTCHA guide shows the full pipeline including spam protection — and the React way of the same patterns is in our React events and forms guide.

Want an instructor reviewing your forms and validation logic? Ampersand Academy teaches full-stack web development one-to-one.

Frequently asked questions

How do I validate a Bootstrap form?

Add the needs-validation and novalidate classes to the form, required attributes to fields, and a small script that adds was-validated on submit. Failed fields automatically show red borders and any invalid-feedback messages.

What is the difference between form-control and form-select?

form-control styles text inputs and textareas; form-select styles dropdown selects, adding the custom chevron arrow and matching padding. Using form-control on a select loses the arrow.

How do I show custom error messages in Bootstrap?

Place a div with class invalid-feedback after the input and write your message inside. It appears automatically when the field fails validation while the form has the was-validated class.

How do I place two form fields side by side in Bootstrap?

Wrap each field’s mb-3 div in a col-md-6 inside a row. On mobile they stack; from md up they sit side by side with the grid gutter spacing them.

Does Bootstrap validate data for me?

No. Bootstrap only styles validation states. The rules come from HTML attributes like required and minlength (or your own script), and the server must always re-validate submitted data.