Bootstrap - Bootstrap 5 Form Validation
Bootstrap 5 comes with a built-in, fully client-side form validation system that leverages HTML5 form validation and adds custom styling for valid and invalid inputs. It’s easy to implement and works for text inputs, selects, checkboxes, radios, and more.
1. Basics of Bootstrap 5 Form Validation
To enable Bootstrap validation:
-
Add the class
.needs-validation
to your<form>
. -
Use
novalidate
to disable default browser validation messages. -
Add the
required
attribute to inputs. -
Use
.valid-feedback
and.invalid-feedback
to display messages.
Example: Basic Validation
<form class="needs-validation" novalidate>
<div class="mb-3">
<label for="username" class="form-label">Username</label>
<input type="text" class="form-control" id="username" placeholder="Username" required>
<div class="valid-feedback">
Looks good!
</div>
<div class="invalid-feedback">
Please enter a username.
</div>
</div>
<div class="mb-3">
<label for="email" class="form-label">Email</label>
<input type="email" class="form-control" id="email" placeholder="Email" required>
<div class="valid-feedback">
Valid email!
</div>
<div class="invalid-feedback">
Please enter a valid email.
</div>
</div>
<button class="btn btn-primary" type="submit">Submit</button>
</form>
2. How Validation Works
-
Invalid input:
.is-invalid
is added automatically. -
Valid input:
.is-valid
is added automatically. -
You can customize feedback messages using
.invalid-feedback
and.valid-feedback
.
3. Custom Validation with JavaScript
Bootstrap recommends the following JS snippet to prevent form submission if invalid:
<script>
(() => {
'use strict'
const forms = document.querySelectorAll('.needs-validation')
Array.from(forms).forEach(form => {
form.addEventListener('submit', event => {
if (!form.checkValidity()) {
event.preventDefault()
event.stopPropagation()
}
form.classList.add('was-validated')
}, false)
})
})()
</script>
Explanation:
-
form.checkValidity()
→ Checks HTML5 constraints. -
.was-validated
→ Triggers Bootstrap styling. -
Prevents form submission when invalid.
4. Validating Different Input Types
a) Text
<input type="text" class="form-control" required>
<div class="invalid-feedback">This field is required.</div>
b) Email
<input type="email" class="form-control" required>
<div class="invalid-feedback">Enter a valid email.</div>
c) Password
<input type="password" class="form-control" required minlength="6">
<div class="invalid-feedback">Password must be at least 6 characters.</div>
d) URL / Number / Date
<input type="url" class="form-control" required>
<input type="number" class="form-control" min="1" max="100" required>
<input type="date" class="form-control" required>
5. Checkbox & Radio Validation
-
Add
required
to at least one checkbox or radio in a group. -
Use
.invalid-feedback
to show a message.
Checkbox Example
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" value="" id="terms" required>
<label class="form-check-label" for="terms">
Accept terms and conditions
</label>
<div class="invalid-feedback">
You must agree before submitting.
</div>
</div>
Radio Example
<div class="form-check">
<input class="form-check-input" type="radio" name="gender" id="male" value="male" required>
<label class="form-check-label" for="male">Male</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="gender" id="female" value="female">
<label class="form-check-label" for="female">Female</label>
<div class="invalid-feedback">
Please select a gender.
</div>
</div>
6. Select and Floating Label Validation
Select
<div class="form-floating mb-3">
<select class="form-select" id="floatingSelect" required>
<option value="">Choose...</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</select>
<label for="floatingSelect">Select an option</label>
<div class="invalid-feedback">Please select a valid option.</div>
</div>
Floating Labels
Floating labels work seamlessly with validation—just include .invalid-feedback
.
7. Tooltips for Validation
Bootstrap 5 allows you to use tooltips instead of messages.
<form class="needs-validation" novalidate>
<div class="mb-3 position-relative">
<input type="text" class="form-control" placeholder="Username" required>
<div class="invalid-tooltip">
Username is required.
</div>
</div>
<button class="btn btn-primary" type="submit">Submit</button>
</form>
-
.invalid-tooltip
appears as a tooltip rather than below the input. -
Useful for compact forms.
8. Full Example: Bootstrap 5 Form Validation
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bootstrap 5 Form Validation</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="p-4">
<h3>Bootstrap 5 Form Validation</h3>
<form class="needs-validation" novalidate>
<div class="mb-3">
<label for="username" class="form-label">Username</label>
<input type="text" class="form-control" id="username" placeholder="Username" required>
<div class="invalid-feedback">Please enter a username.</div>
</div>
<div class="mb-3">
<label for="email" class="form-label">Email</label>
<input type="email" class="form-control" id="email" placeholder="Email" required>
<div class="invalid-feedback">Please enter a valid email.</div>
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input type="password" class="form-control" id="password" placeholder="Password" required minlength="6">
<div class="invalid-feedback">Password must be at least 6 characters.</div>
</div>
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" value="" id="terms" required>
<label class="form-check-label" for="terms">Accept terms</label>
<div class="invalid-feedback">You must agree before submitting.</div>
</div>
<button class="btn btn-primary" type="submit">Submit</button>
</form>
<script>
(() => {
'use strict'
const forms = document.querySelectorAll('.needs-validation')
Array.from(forms).forEach(form => {
form.addEventListener('submit', event => {
if (!form.checkValidity()) {
event.preventDefault()
event.stopPropagation()
}
form.classList.add('was-validated')
}, false)
})
})()
</script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>