Bootstrap 5 Inline Form Validation
Bootstrap 5 inline form validation provides immediate visual feedback directly beside or beneath form fields, showing users whether their input is valid or invalid without a page reload. It uses browser-based Constraint Validation API alongside Bootstrap's .was-validated and .is-valid / .is-invalid classes to render green success states or red error states with accompanying feedback text. Use it on any form where reducing submission errors and improving completion rates matters, such as registration flows, checkout pages, or multi-step wizards.
Bootstrap class
.was-validated, .is-valid, .is-invalidCommon use cases
- Email and password fields on a signup form that check format and minimum length before the user submits, reducing server-side validation round trips.
- Checkout address forms that validate postcode format and required fields inline so users can correct mistakes field by field rather than seeing a page-level error list.
- A multi-step onboarding wizard where each step validates its own fields before allowing progression, preventing users from reaching later steps with incomplete data.
- A contact form with a character-limited textarea that turns invalid as soon as the user exceeds the maximum, showing a live character-count message in the feedback slot.
Variants and classes
| Variant | Description and classes |
|---|---|
| Browser-native validation (was-validated) | Adds .was-validated to the form element so all fields automatically show valid or invalid states based on HTML5 constraint attributes like required, minlength, and type.was-validated |
| Programmatic valid state | Manually marks a specific field as passing validation by applying .is-valid directly to the input and showing a .valid-feedback message beneath it.is-valid valid-feedback |
| Programmatic invalid state | Manually marks a specific field as failing validation by applying .is-invalid to the input and displaying a .invalid-feedback message that describes the exact problem.is-invalid invalid-feedback |
| Tooltip feedback | Replaces the block feedback text with a small positioned tooltip bubble by swapping .valid-feedback and .invalid-feedback for .valid-tooltip and .invalid-tooltip, requiring the parent to be position: relative.valid-tooltip invalid-tooltip |
| Input group validation | Applies validation states inside a Bootstrap input group so the feedback message appears cleanly after the grouped addon and input together.input-group has-validation |
Code example
<form class="needs-validation" novalidate>
<div class="mb-3">
<label for="emailAddress" class="form-label">Email address</label>
<input
type="email"
class="form-control"
id="emailAddress"
placeholder="you@example.com"
required
/>
<div class="valid-feedback">Looks good!</div>
<div class="invalid-feedback">Please enter a valid email address.</div>
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input
type="password"
class="form-control"
id="password"
minlength="8"
required
/>
<div class="valid-feedback">Strong password.</div>
<div class="invalid-feedback">Password must be at least 8 characters.</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</label>
<div class="invalid-feedback">You must agree before submitting.</div>
</div>
<button type="submit" class="btn btn-primary">Create account</button>
</form>
<script>
(function () {
'use strict';
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>Live examples
Basic Inline Form Validation
Canvas template variants
Canvas Builder builds pages on the Canvas HTML template, which adds its own styled versions of Bootstrap 5 components. Variants you can ask for in a prompt:
- Canvas Builder applies brand primary and danger colours to the valid and invalid border and icon tints, so validation states match the site's colour palette rather than Bootstrap's default green and red.
- Canvas Builder outputs tooltip-style validation on dense forms (such as inline search or filter bars) and block-style feedback on standard stacked forms, choosing the pattern automatically based on the form layout selected.
- Canvas Builder wraps every validated field in accessible markup including
aria-describedbylinking the input to its feedback element, ensuring screen readers announce the error message when the field receives focus.
Best practices
Add novalidate to suppress browser tooltips
Always add the novalidate attribute to your form element when using Bootstrap validation; this disables the browser's own styled tooltip popups while still allowing checkValidity() to work, giving Bootstrap full control over how errors appear.
Validate on blur for long forms
Triggering validation only on form submit can frustrate users in long forms; add a blur event listener to each input that adds .is-valid or .is-invalid immediately after the user leaves the field, so errors surface before they reach the submit button.
Use has-validation on input groups
When an input is wrapped in a .input-group, add .has-validation to the group container; without it, the rounded corner CSS on the addon element overlaps the invalid red border and the layout breaks visually.
Keep feedback messages specific and actionable
Replace vague messages like 'Invalid input' with precise instructions such as 'Phone number must be 10 digits with no spaces'; specific messages reduce re-submission rates because users know exactly what to fix.
FAQ
Why are my .invalid-feedback messages not showing even though I add .is-invalid to the input?
.invalid-feedback element must be an immediate sibling that follows the .is-invalid input in the DOM. Bootstrap's CSS selector .is-invalid ~ .invalid-feedback only targets the next sibling, so any wrapper element between the input and the feedback div will break visibility. If you need a wrapper, apply .is-invalid to the wrapper instead and use the .was-validated parent approach, or adjust the selector in your own stylesheet.How do I change the valid state colour from green to my brand colour?
$form-valid-color and $form-valid-border-color before importing Bootstrap, or write plain CSS targeting .form-control.is-valid and .valid-feedback. For the background icon on the input, override $form-valid-icon with an SVG data URI in your brand colour. If you are not using SASS, a CSS custom property approach works too by reassigning --bs-form-valid-border-color in your root styles.How does Canvas Builder generate inline form validation for a new project?
.needs-validation pattern including the JavaScript submit handler, correctly structured .valid-feedback and .invalid-feedback siblings for each field, and aria-describedby attributes for accessibility. It also replaces Bootstrap's default green and red with your project's brand success and danger colours, so the validation states feel native to your design from the first generated file.