Signup Form with Password Strength Indicator

Ensure account security with a signup form featuring a password strength indicator. Learn how to implement a signup form that provides users with feedback on password strength.

Enhance your website's signup process with a user-friendly form that includes a password strength indicator. This tutorial will guide you through creating and customizing a signup form using HTML, CSS, and JavaScript to provide real-time feedback on password strength.

Step 1: Copy the Code Snippet

  • Start by copying the provided HTML, CSS, and JavaScript code snippets. This includes the structure and basic styles required to create a functional signup form with a password strength indicator.

Step 2: Link CSS

  • Ensure the styles.css file is correctly linked in your HTML document. Add the following <link> tag within the <head> section to import the CSS styles:
  • <link rel="stylesheet" href="styles.css">
  • Also, add the following <script> tag before the closing </body> tag to link your custom JavaScript file:
  • <script src="script.js"></script>

Step 3: Customize and Make it Yours

  • Customize the signup form to match your website's theme and functionality requirements. Modify the HTML structure to include additional fields or elements, adjust CSS styles (styles.css) for colors, sizes, and form element designs, and enhance JavaScript logic (script.js) for more sophisticated password strength evaluation and other form validations.

By following these steps, you can implement and personalize a signup form with a password strength indicator using HTML, CSS, and JavaScript, providing a better user experience on your website.

Code Explanation

HTML Code

<div class="login-card">: A container for the entire login card.
  • <img>: Displays an image at the top of the card.
  • <h2>Sign Up</h2>: The main heading of the card.
  • <h3>Enter your credentials</h3>: A subheading prompting the user to enter their credentials.
  • <form class="login-form">: A form container for the input fields and button.
  • <div class="username">: A container for the email input and spinner.
  • <input>: An input field for the user's email with pre-filled value "joe@gmail.com".
    • autocomplete="off": Disables autocomplete for the input.
    • spellcheck="false": Disables spellcheck.
    • class="control": Applies styles defined for the .control class.
    • type="email": Specifies that the input type is email.
    • placeholder="Email": Placeholder text for the input.
    • value="joe@gmail.com": Pre-filled value in the input field.
  • <div id="spinner" class="spinner"></div>: A spinner element, probably for loading or validation indication.
  • <input>: An input field for the password.
    • spellcheck="false": Disables spellcheck.
    • class="control": Applies styles defined for the .control class.
    • id="password": Sets the ID of the input field.
    • type="password": Specifies that the input type is password.
    • placeholder="Password": Placeholder text for the input.
    • onkeyup="handleChange()": Calls the handleChange function on keyup event to possibly validate or measure password strength.
  • <div id="bars">: A container for a visual password strength indicator bar.
  • <div></div>: An inner div representing the bar itself.
  • <div class="strength" id="strength"></div>: A container for displaying the password strength text.
  • <button class="control" type="button">JOIN NOW</button>: A button to submit the form (type is button instead of submit to prevent default form submission).

CSS Code

Global Styles
* {
  box-sizing: border-box;
}
  • *: Applies box-sizing: border-box to all elements, ensuring padding and border are included in the element's total width and height.
html,
body,
.wrapper {
  height: 100%;
}
  • html, body, .wrapper: Ensures the HTML, body, and wrapper elements take up 100% height.
Keyframes
@keyframes rotate {
  100% {
    background-position: 0% 50%;
  }
}
  • @keyframes rotate: Defines an animation that changes the background position, creating a moving background effect.
Body Styles
body {
  display: grid;
  place-items: center;
  margin: 0;
  background-color: #000000;
  background-image: url("https://raw.githubusercontent.com/frontend-joe/es6-signups/ef99c2e743e35ab2ae93e5fca51777094fe00ec6/signup-2/bbblurry.svg");
  background-repeat: no-repeat;
  background-size: 300vh;
  font-family: "Euclid Circular A";
  color: #868b94;
  animation: rotate 5s infinite alternate linear;
}
  • display: grid; place-items: center;: Centers the content using CSS Grid.
  • background-color: #000000;: Sets the background color to black.
  • background-image: Adds a background image.
  • background-repeat: no-repeat; background-size: 300vh;: Prevents the background image from repeating and sizes it.
  • animation: rotate 5s infinite alternate linear;: Applies the rotate animation.
Button Styles
button {
  background: transparent;
  border: 0;
  cursor: pointer;
}
  • button: Removes default button styles and sets a transparent background.
Control Styles
.control {
  border: 0;
  border-radius: 8px;
  outline: none;
  width: 100%;
  height: 56px;
  padding: 0 16px;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 6px;
  color: #f9f9f9;
  margin: 8px 0;
  font-family: inherit;
  text-align: left;
  font-size: 16px;
  transition: 0.4s;
}
  • .control: Applies styles to input fields and buttons.
  • background: rgba(255, 255, 255, 0.1);: Semi-transparent background.
  • transition: 0.4s;: Adds a smooth transition effect.
Login Card Styles
.login-card {
  width: 400px;
  padding: 100px 30px 32px;
  border-radius: 1.25rem;
  background: rgba(0, 0, 0, 0.7);
  backdrop-filter: blur(26px);
  text-align: center;
}
  • .login-card: Styles the login card container.
  • background: rgba(0, 0, 0, 0.7);: Semi-transparent black background.
  • backdrop-filter: blur(26px);: Blurs the background behind the card.
Heading and Image Styles
.login-card > h2 {
  font-size: 36px;
  font-weight: 600;
  margin: 0 0 6px;
  color: #f9f9f9;
}
.login-card img {
  width: 120px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.4);
  padding: 5px;
  margin-bottom: 20px;
}
.login-card > h3 {
  color: #837f90;
  margin: 0 0 40px;
  font-weight: 500;
  font-size: 1rem;
}
  • .login-card > h2: Styles the main heading.
  • .login-card img: Styles the image.
  • .login-card > h3: Styles the subheading.
Form Styles
.login-form {
  width: 100%;
  margin: 0;
  display: grid;
}
  • .login-form: Styles the form container to use CSS Grid for layout.
Input Placeholder Styles
.login-form input.control::placeholder {
  color: #868b94;
}
  • .login-form input.control::placeholder: Styles the placeholder text color.
Button Styles
.login-form > button.control {
  cursor: pointer;
  width: 100%;
  height: 56px;
  padding: 0 16px;
  background: #f9f9f9;
  color: #000000;
  border: 0;
  font-family: inherit;
  font-size: 1rem;
  font-weight: 600;
  text-align: center;
  letter-spacing: 2px;
  transition: all 0.375s;
}
  • .login-form > button.control: Styles the submit button.
Username Container
.username {
  position: relative;
}
  • .username: Positions the spinner relative to the input field.
Spinner Animation
@keyframes spin {
  100% {
    rotate: 1turn;
  }
}
  • @keyframes spin: Defines a spinning animation.
.spinner {
  position: absolute;
  top: 50%;
  right: 16px;
  translate: 0 -50%;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 3px solid #ccc9e1;
  border-top-color: #8f44fd;
  opacity: 0;
  animation: spin 1s infinite linear;
}
.spinner.visible {
  opacity: 1;
}
  • .spinner: Styles the spinner element.
  • .spinner.visible: Makes the spinner visible.
Indicator and Bars Styles
.indicator {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
#bars {
  margin: 8px 0;
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  height: 6px;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.1);
}
#bars div {
  height: 6px;
  border-radius: 3px;
  transition: 0.4s;
  width: 0%;
}
  • .indicator: Styles the password strength indicator container.
  • #bars: Styles the container for the strength bars.
  • #bars div: Styles the individual strength bars.
Password Strength Colors
#bars.weak div {
  background: #bc2b38;
  width: 33.33%;
}
#bars.medium div {
  background: #d36f30;
  width: 66.66%;
}
#bars.strong div {
  background: #1eb965;
  width: 100%;
}
  • #bars.weak div: Styles the strength bar for weak passwords.
  • #bars.medium div: Styles the strength bar for medium passwords.
  • #bars.strong div: Styles the strength bar for strong passwords.
Strength Text
.strength {
  text-align: left;
  height: 30px;
  text-transform: capitalize;
}
  • .strength: Styles the password strength text.

JavaScript Code

DOM Elements
const bars = document.querySelector("#bars"),
strengthDiv = document.querySelector("#strength"),
passwordInput = document.querySelector("#password");
  • bars: The element representing the visual bars indicates password strength.
  • strengthDiv: The element displaying the text indicating password strength.
  • passwordInput: The input element where the user enters their password.
Strength Levels
const strength = {
  1: "weak",
  2: "medium",
  3: "strong",
};
  • strength: An object mapping strength levels (1 to 3) to corresponding labels ("weak", "medium", "strong").
Indicator Function
const getIndicator = (password, strengthValue) => {
  for (let index = 0; index < password.length; index++) {
    let char = password.charCodeAt(index);
    if (!strengthValue.upper && char >= 65 && char <= 90) {
      strengthValue.upper = true;
    } else if (!strengthValue.numbers && char >= 48 && char <= 57) {
      strengthValue.numbers = true;
    } else if (!strengthValue.lower && char >= 97 && char <= 122) {
      strengthValue.lower = true;
    }
  }
  let strengthIndicator = 0;
  for (let metric in strengthValue) {
    if (strengthValue[metric] === true) {
      strengthIndicator++;
    }
  }
  return strength[strengthIndicator] ?? "";
};
  • getIndicator: A function that evaluates the password to determine its strength based on the presence of uppercase letters, numbers, and lowercase letters.
  • Loops through each character of the password.
  • Uses charCodeAt to get the Unicode value of each character.
  • Checks if the character is an uppercase letter, number, or lowercase letter, and sets the corresponding property in strengthValue to true if found.
  • Counts the number of true values in strengthValue to determine the strength level.
  • Returns the corresponding strength label from the strength object.
Strength Function
const getStrength = (password) => {
  let strengthValue = {
    upper: false,
    numbers: false,
    lower: false,
  };
  return getIndicator(password, strengthValue);
};
  • getStrength: A function that initializes the strengthValue object and calls getIndicator to determine and return the password strength.
Handle Change Function
const handleChange = () => {
  let { value: password } = passwordInput;
  console.log(password);
  const strengthText = getStrength(password);
  bars.classList = "";
  if (strengthText) {
    strengthDiv.innerText = `${strengthText} Password`;
    bars.classList.add(strengthText);
  } else {
    strengthDiv.innerText = "";
  }
};
  • handleChange: A function that handles changes in the password input field.
  • Gets the current value of the password input.
  • Logs the password to the console (for debugging purposes).
  • Calls getStrength to determine the password strength.
  • Resets the bars class list.
  • Updates the strengthDiv text and bars classes based on the password strength.