28 CSS Input Field Designs

Toggle Password

Password field with an eye toggle that swaps `type="password"` ↔ `type="text"`. `aria-pressed` reflects state for screen readers; `autocomplete="new-password"` for sign-up flows.

Light JS MIT licensed

Toggle Password the 27th of 28 designs in the 28 CSS Input Field Designs collection. The design pairs CSS styling with a small amount of JavaScript for interactivity. Copy the HTML, CSS and JavaScript panels below into your project — the JS is self-contained, has zero dependencies, and is safe to drop into any framework (React, Vue, Svelte, plain HTML). The design honours prefers-reduced-motion and uses real semantic markup, so it ships accessibility-ready out of the box.

Live preview

Open in playground

The code

<label class="if-pw">
  <span class="if-pw-label">Password</span>
  <span class="if-pw-wrap">
    <input
      type="password"
      name="pw"
      autocomplete="new-password"
      placeholder="At least 8 characters"
      minlength="8"
      data-if-pw
    />
    <button
      type="button"
      class="if-pw-toggle"
      aria-label="Show password"
      aria-pressed="false"
      data-if-pw-toggle
    >
      <svg class="if-pw-eye" viewBox="0 0 24 24" aria-hidden="true">
        <path d="M2 12s4-7 10-7 10 7 10 7-4 7-10 7-10-7-10-7Z" />
        <circle cx="12" cy="12" r="3" />
      </svg>
      <svg class="if-pw-eye-off" viewBox="0 0 24 24" aria-hidden="true">
        <path
          d="M3 3l18 18M9.9 5.1A10 10 0 0 1 22 12a16 16 0 0 1-2.7 3.7M6.7 6.7A16 16 0 0 0 2 12s4 7 10 7a10 10 0 0 0 4.1-.9"
        />
      </svg>
    </button>
  </span>
</label>
.if-pw {
  display: grid;
  gap: 6px;
  width: 100%;
  max-width: 280px;
  font-size: 11px;
  color: #b8b6d4;
}

.if-pw-label {
  font-weight: 600;
}

.if-pw input {
  width: 100%;
  box-sizing: border-box;
  padding: 11px 14px;
  background: #1a1a22;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 8px;
  color: #f0eeff;
  font-size: 14px;
  outline: none;
  transition: border-color 0.2s;
}

.if-pw input:focus {
  border-color: #c084fc;
}

.if-pw-meter {
  position: relative;
  height: 4px;
  border-radius: 99px;
  background: rgba(255, 255, 255, 0.08);
  overflow: hidden;
}

.if-pw-fill {
  position: absolute;
  inset: 0;
  width: 0;
  background: linear-gradient(90deg, #ef4444, #f59e0b, #22c55e);
  border-radius: inherit;
  transition: width 0.3s ease;
}

.if-pw:has(input:placeholder-shown) .if-pw-fill {
  width: 0;
}

.if-pw:has(input:not(:placeholder-shown):invalid) .if-pw-fill {
  width: 30%;
}

.if-pw:has(input:not(:placeholder-shown):valid) .if-pw-fill {
  width: 65%;
}

.if-pw:has(input:focus:valid) .if-pw-fill {
  width: 100%;
}

.if-pw-hint {
  font-size: 10.5px;
  color: #b8b6d4;
}

.if-pw {
  display: grid;
  gap: 6px;
  width: 100%;
  max-width: 280px;
}

.if-pw-label {
  font-family: "JetBrains Mono", monospace;
  font-size: 10px;
  letter-spacing: 0.12em;
  color: #b8b6d4;
  text-transform: uppercase;
}

.if-pw-wrap {
  display: inline-flex;
  align-items: center;
  padding: 0 6px 0 14px;
  background: #1a1a22;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 10px;
  transition: border-color 0.2s;
}

.if-pw-wrap:focus-within {
  border-color: #7c6cff;
}

.if-pw input {
  flex: 1;
  min-width: 0;
  padding: 12px 0;
  border: 0;
  outline: none;
  background: transparent;
  color: #f0eeff;
  font:
    500 14px/1 system-ui,
    sans-serif;
  letter-spacing: 0.08em;
}

.if-pw input::placeholder {
  color: #b8b6d4;
}

.if-pw-toggle {
  width: 32px;
  height: 32px;
  border: 0;
  cursor: pointer;
  background: transparent;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s;
}

.if-pw-toggle:hover {
  background: rgba(255, 255, 255, 0.05);
}

.if-pw-toggle svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: #b8b6d4;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.if-pw-eye-off {
  display: none;
}

.if-pw-toggle[aria-pressed="true"] .if-pw-eye {
  display: none;
}

.if-pw-toggle[aria-pressed="true"] .if-pw-eye-off {
  display: block;
}

.if-pw-toggle[aria-pressed="true"] svg {
  stroke: #7c6cff;
}
// Toggle Password — swap input type + reflect state via aria-pressed
document.querySelectorAll("[data-if-pw-toggle]").forEach(function (btn) {
  var input = btn.closest(".if-pw-wrap").querySelector("input");
  btn.addEventListener("click", function () {
    var on = btn.getAttribute("aria-pressed") === "true";
    btn.setAttribute("aria-pressed", on ? "false" : "true");
    btn.setAttribute("aria-label", on ? "Show password" : "Hide password");
    input.type = on ? "password" : "text";
  });
});

Search CodeFronts

Loading…