Password strength
Provide visual feedback on password strength with segmented meters or progress bars that update as users type.
Overview
Strength meters help users create secure passwords by providing real-time feedback on password complexity. Bootstrap's strength component offers:
- Segmented meter: Four segments that fill based on strength level
- Progress bar variant: A single bar that grows with strength
- Text feedback: Optional text messages for each strength level
- Customizable scoring: Configure minimum length and scoring criteria
- Minimal JavaScript: Lightweight component following Bootstrap patterns
Examples
Segmented
The default strength meter uses four segments that fill progressively as password strength increases. Add data-bs-strength to enable the JavaScript behavior.
<div>
<label for="password1" class="form-label">Password</label>
<input type="password" class="form-control" id="password1" placeholder="Enter password">
<div class="strength" data-bs-strength>
<div class="strength-segment"></div>
<div class="strength-segment"></div>
<div class="strength-segment"></div>
<div class="strength-segment"></div>
</div>
</div> With text feedback
Add a .strength-text element to display strength messages.
<div>
<label for="password2" class="form-label">Password</label>
<input type="password" class="form-control" id="password2" placeholder="Enter password">
<div class="strength" data-bs-strength>
<div class="strength-segment"></div>
<div class="strength-segment"></div>
<div class="strength-segment"></div>
<div class="strength-segment"></div>
</div>
<span class="strength-text"></span>
</div> Progress bar
Use .strength-bar for a single progress bar that grows with password strength.
<div>
<label for="password3" class="form-label">Password</label>
<input type="password" class="form-control" id="password3" placeholder="Enter password">
<div class="strength-bar" data-bs-strength></div>
</div> Static segmented
You can use the component without JavaScript for static displays by setting the data-bs-strength attribute manually.
<div>
<div>Weak</div>
<div class="strength" data-bs-strength="weak">
<div class="strength-segment active"></div>
<div class="strength-segment"></div>
<div class="strength-segment"></div>
<div class="strength-segment"></div>
</div>
</div>
<div>
<div>Fair</div>
<div class="strength" data-bs-strength="fair">
<div class="strength-segment active"></div>
<div class="strength-segment active"></div>
<div class="strength-segment"></div>
<div class="strength-segment"></div>
</div>
</div>
<div>
<div>Good</div>
<div class="strength" data-bs-strength="good">
<div class="strength-segment active"></div>
<div class="strength-segment active"></div>
<div class="strength-segment active"></div>
<div class="strength-segment"></div>
</div>
</div>
<div>
<div>Strong</div>
<div class="strength" data-bs-strength="strong">
<div class="strength-segment active"></div>
<div class="strength-segment active"></div>
<div class="strength-segment active"></div>
<div class="strength-segment active"></div>
</div>
</div> Static progress bar
<div>
<div>Weak</div>
<div class="strength-bar" data-bs-strength="weak"></div>
</div>
<div>
<div>Fair</div>
<div class="strength-bar" data-bs-strength="fair"></div>
</div>
<div>
<div>Good</div>
<div class="strength-bar" data-bs-strength="good"></div>
</div>
<div>
<div>Strong</div>
<div class="strength-bar" data-bs-strength="strong"></div>
</div> Strength criteria
The default scoring algorithm evaluates passwords based on:
| Criteria | Points |
|---|---|
| Meets minimum length (8 characters) | +1 |
| 4+ characters over minimum | +1 |
| Contains lowercase letters | +1 |
| Contains uppercase letters | +1 |
| Contains numbers | +1 |
| Contains special characters | +1 |
| Multiple special characters | +1 |
| 16+ characters | +1 |
| Level | Points |
|---|---|
| Weak | 1-2 |
| Fair | 3-4 |
| Good | 5-6 |
| Strong | 7-8 |
Usage
Via data attributes
Add data-bs-strength to automatically initialize. The component will look for a password input in the same parent container.
<div>
<input type="password" class="form-control">
<div class="strength" data-bs-strength>
<div class="strength-segment"></div>
<div class="strength-segment"></div>
<div class="strength-segment"></div>
<div class="strength-segment"></div>
</div>
</div>Via JavaScript
const element = document.querySelector('.strength')
const strength = new bootstrap.Strength(element, {
input: '#my-password-input',
minLength: 10,
messages: {
weak: 'Too weak',
fair: 'Could be better',
good: 'Good password',
strong: 'Excellent!'
}
})Options
| Name | Type | Default | Description |
|---|---|---|---|
input | string | element | null | Selector or element for the password input. If not provided, looks for input[type="password"] in the parent. |
minLength | number | 8 | Minimum password length for first strength point. |
messages | object | {weak, fair, good, strong} | Custom messages for each strength level. |
weights | object | See below | Point values for each scoring criterion. Set to 0 to disable a criterion. |
thresholds | array | [2, 4, 6] | Score boundaries for strength levels: [weak, fair, good]. Scores above the last value are "strong". |
scorer | function | null | Custom scoring function (password) => number. Overrides built-in scoring when provided. |
Default weights
{
minLength: 1, // Meets minimum length
extraLength: 1, // 4+ characters over minimum
lowercase: 1, // Contains lowercase letters
uppercase: 1, // Contains uppercase letters
numbers: 1, // Contains numbers
special: 1, // Contains special characters
multipleSpecial: 1, // Multiple special characters
longPassword: 1 // 16+ characters
}Custom weights
// Disable uppercase requirement, make special chars worth more
new bootstrap.Strength(element, {
weights: {
uppercase: 0, // Don't require uppercase
special: 2 // Special chars worth 2 points
},
thresholds: [3, 5, 7] // Adjust thresholds for new max score
})Custom scorer
// Fully custom scoring logic
new bootstrap.Strength(element, {
scorer: (password) => {
let score = 0
if (password.length >= 12) score += 4
if (/[!@#$%]/.test(password)) score += 4
return score
},
thresholds: [2, 4, 6]
})Methods
| Method | Description |
|---|---|
getStrength() | Returns the current strength level ('weak', 'fair', 'good', 'strong', or null). |
evaluate() | Manually trigger a password evaluation. |
dispose() | Destroys the component instance. |
const element = document.querySelector('.strength')
const strength = bootstrap.Strength.getOrCreateInstance(element)
// Get current strength
console.log(strength.getStrength()) // 'fair'Events
| Event | Description |
|---|---|
strengthChange.bs.strength | Fired when the strength level changes. Includes strength and score properties. |
const element = document.querySelector('.strength')
element.addEventListener('strengthChange.bs.strength', event => {
console.log('Strength:', event.strength) // 'weak', 'fair', 'good', 'strong'
console.log('Score:', event.score) // 0-8
})CSS-only usage
For simple cases or server-rendered content, you can use the component without JavaScript by manually setting the data-bs-strength attribute and .active classes.
<!-- Set via server-side logic -->
<div class="strength" data-bs-strength="good">
<div class="strength-segment active"></div>
<div class="strength-segment active"></div>
<div class="strength-segment active"></div>
<div class="strength-segment"></div>
</div>Accessibility
- The strength meter is decorative feedback and should be used alongside clear password requirements text
- Consider using
aria-describedbyto associate the password input with requirement text - Screen reader users benefit from the text feedback option which announces strength changes
CSS
Sass variables
$strength-height: .375rem;
$strength-gap: .25rem;
$strength-margin-top: .25rem;
$strength-border-radius: var(--border-radius-pill);
$strength-bg: var(--bg-2);
$strength-transition: background-color .2s ease-in-out, width .3s ease-in-out;
$strength-weak-color: var(--danger-bg);
$strength-fair-color: var(--warning-bg);
$strength-good-color: var(--info-bg);
$strength-strong-color: var(--success-bg);