CodeMIRAI
0 XP

Forms

3 min read 6 runnable examples Quiz included

Form controls

HTML + Bootstrap
<form class="p-3" style="max-width: 26rem">
  <div class="mb-3">
    <label for="email" class="form-label">Email address</label>
    <input type="email" class="form-control" id="email" placeholder="you@example.com" aria-describedby="emailHelp">
    <div id="emailHelp" class="form-text">We'll never share your email.</div>
  </div>
  <div class="mb-3">
    <label for="msg" class="form-label">Message</label>
    <textarea class="form-control" id="msg" rows="3"></textarea>
  </div>
  <div class="mb-3">
    <label for="topic" class="form-label">Topic</label>
    <select class="form-select" id="topic">
      <option selected>Choose...</option>
      <option>Courses</option>
      <option>Billing</option>
    </select>
  </div>
  <button type="submit" class="btn btn-primary">Send</button>
</form>
  • form-control styles text inputs and textareas; form-select styles selects.
  • form-label styles labels; form-text is small help text, linked to its input with aria-describedby so screen readers read it too.
  • mb-3 spaces the groups apart.

Checkboxes, radios and switches

HTML + Bootstrap
<div class="p-3">
  <div class="form-check">
    <input class="form-check-input" type="checkbox" id="terms">
    <label class="form-check-label" for="terms">I agree to the terms</label>
  </div>
  <div class="form-check">
    <input class="form-check-input" type="radio" name="level" id="beg" checked>
    <label class="form-check-label" for="beg">Beginner</label>
  </div>
  <div class="form-check">
    <input class="form-check-input" type="radio" name="level" id="adv">
    <label class="form-check-label" for="adv">Advanced</label>
  </div>
  <div class="form-check form-switch">
    <input class="form-check-input" type="checkbox" role="switch" id="dark">
    <label class="form-check-label" for="dark">Dark mode</label>
  </div>
</div>

Input groups

HTML + Bootstrap
<div class="p-3" style="max-width: 26rem">
  <div class="input-group mb-3">
    <span class="input-group-text">@</span>
    <input type="text" class="form-control" placeholder="Username" aria-label="Username">
  </div>
  <div class="input-group mb-3">
    <span class="input-group-text">₹</span>
    <input type="number" class="form-control" aria-label="Amount in rupees">
    <span class="input-group-text">.00</span>
  </div>
  <div class="input-group">
    <input type="search" class="form-control" placeholder="Search lessons" aria-label="Search lessons">
    <button class="btn btn-outline-secondary" type="button">Search</button>
  </div>
</div>

An input group attaches text or buttons to the sides of an input.

Floating labels

HTML + Bootstrap
<div class="p-3" style="max-width: 24rem">
  <div class="form-floating mb-3">
    <input type="email" class="form-control" id="floatEmail" placeholder="name@example.com">
    <label for="floatEmail">Email address</label>
  </div>
  <div class="form-floating">
    <input type="password" class="form-control" id="floatPass" placeholder="Password">
    <label for="floatPass">Password</label>
  </div>
</div>

The label sits inside the box, then floats up when you click in. Floating labels need the <label> after the input, and a placeholder on the input (it isn't shown, but the effect depends on it).

Layout with the grid

HTML + Bootstrap
<form class="row g-3 p-3">
  <div class="col-md-6">
    <label for="first" class="form-label">First name</label>
    <input type="text" class="form-control" id="first">
  </div>
  <div class="col-md-6">
    <label for="last" class="form-label">Last name</label>
    <input type="text" class="form-control" id="last">
  </div>
  <div class="col-12">
    <label for="addr" class="form-label">Address</label>
    <input type="text" class="form-control" id="addr" placeholder="221B Baker Street">
  </div>
  <div class="col-md-8">
    <label for="city" class="form-label">City</label>
    <input type="text" class="form-control" id="city">
  </div>
  <div class="col-md-4">
    <label for="pin" class="form-label">PIN code</label>
    <input type="text" class="form-control" id="pin">
  </div>
</form>

row g-3 on the form and col-* classes on each group place the fields side by side from md up, and stack them on phones.

Validation feedback

HTML + Bootstrap
<form class="p-3 needs-validation" novalidate style="max-width: 24rem" id="signup">
  <div class="mb-3">
    <label for="user" class="form-label">Username</label>
    <input type="text" class="form-control" id="user" required minlength="3">
    <div class="invalid-feedback">Choose a username of at least 3 characters.</div>
    <div class="valid-feedback">Looks good!</div>
  </div>
  <div class="mb-3">
    <label for="mail" class="form-label">Email</label>
    <input type="email" class="form-control" id="mail" required>
    <div class="invalid-feedback">Enter a valid email address.</div>
  </div>
  <button class="btn btn-primary" type="submit">Create account</button>
  <p class="mt-3 text-success" id="done"></p>
</form>
<script>
  const form = document.querySelector("#signup");
  form.addEventListener("submit", (e) => {
    e.preventDefault();
    form.classList.add("was-validated");          // show the green and red states
    if (form.checkValidity()) document.querySelector("#done").textContent = "Account created.";
  });
</script>

Press Create account with the fields empty. novalidate turns off the browser's own pop-up messages, the HTML attributes (required, minlength, type="email") still decide what's valid, and adding was-validated to the form reveals Bootstrap's styled invalid-feedback and valid-feedback messages.

Finished this lesson?Mark it complete to earn +20 XP and move your progress on.