Skip to main content Skip to docs navigation

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.

HTML
<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.

HTML
<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.

HTML
<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.

Weak
Fair
Good
Strong
HTML
<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

Weak
Fair
Good
Strong
HTML
<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:

CriteriaPoints
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
LevelPoints
Weak1-2
Fair3-4
Good5-6
Strong7-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.

HTML
<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

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

NameTypeDefaultDescription
inputstring | elementnullSelector or element for the password input. If not provided, looks for input[type="password"] in the parent.
minLengthnumber8Minimum password length for first strength point.
messagesobject{weak, fair, good, strong}Custom messages for each strength level.
weightsobjectSee belowPoint values for each scoring criterion. Set to 0 to disable a criterion.
thresholdsarray[2, 4, 6]Score boundaries for strength levels: [weak, fair, good]. Scores above the last value are "strong".
scorerfunctionnullCustom scoring function (password) => number. Overrides built-in scoring when provided.

Default weights

JavaScript
{
  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

JavaScript
// 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

JavaScript
// 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

MethodDescription
getStrength()Returns the current strength level ('weak', 'fair', 'good', 'strong', or null).
evaluate()Manually trigger a password evaluation.
dispose()Destroys the component instance.
JavaScript
const element = document.querySelector('.strength')
const strength = bootstrap.Strength.getOrCreateInstance(element)

// Get current strength
console.log(strength.getStrength()) // 'fair'

Events

EventDescription
strengthChange.bs.strengthFired when the strength level changes. Includes strength and score properties.
JavaScript
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.

HTML
<!-- 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-describedby to associate the password input with requirement text
  • Screen reader users benefit from the text feedback option which announces strength changes

CSS

Sass variables

SCSS
$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);