24 CSS Login Form Designs with Live Demos

Inline Validation

Login form with real-time inline validation. Each field shows a green checkmark when valid and a red icon when invalid, driven by `:valid` / `:invalid` and pseudo-elements — no JavaScript.

Pure CSS MIT licensed

Inline Validation the 22nd of 24 designs in the 24 CSS Login Form Designs with Live Demos collection. The design is implemented in pure CSS — no JavaScript required. Copy the HTML and CSS panels below into your project. Because the demo is pure CSS, it works in any framework or templating engine you happen to use. 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

<form class="lf-val" aria-label="Sign in with inline validation">
  <h2 class="lf-val-title">Sign in</h2>
  <p class="lf-val-sub">Inputs validate as you type</p>
  <label class="lf-val-row">
    <span>Email</span>
    <input type="email" name="email" autocomplete="email" placeholder="[email protected]" required />
  </label>
  <label class="lf-val-row">
    <span>Password</span>
    <input
      type="password"
      name="password"
      autocomplete="current-password"
      placeholder="At least 8 characters"
      minlength="8"
      required
    />
  </label>
  <button type="submit" class="lf-val-btn">Continue</button>
</form>
.lf-val {
  width: 100%;
  max-width: 320px;
  background: #15151d;
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 14px;
  padding: 26px 22px;
  display: grid;
  gap: 12px;
}
.lf-val-title {
  margin: 0;
  font-size: 17px;
  font-weight: 700;
  color: #f0eeff;
}
.lf-val-sub {
  margin: -6px 0 4px;
  font-size: 12px;
  color: #b8b6d4;
}
.lf-val-row {
  display: grid;
  gap: 5px;
  font-size: 11px;
  color: #b8b6d4;
  position: relative;
}
.lf-val-row input {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 8px;
  padding: 10px 38px 10px 12px;
  font-size: 13px;
  color: #f0eeff;
  outline: none;
  transition:
    border-color 0.15s,
    background 0.15s;
}
.lf-val-row input:focus {
  border-color: #7c6cff;
}
.lf-val-row::after {
  content: "";
  position: absolute;
  right: 12px;
  bottom: 12px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: transparent;
  transform: scale(0.5);
  opacity: 0;
  transition:
    transform 0.2s,
    opacity 0.2s,
    background 0.2s;
}
.lf-val-row:has(input:not(:placeholder-shown):invalid) input {
  border-color: rgba(255, 108, 138, 0.6);
}
.lf-val-row:has(input:not(:placeholder-shown):invalid)::after {
  opacity: 1;
  transform: scale(1);
  background: #ff6c8a
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 10 10' fill='none' stroke='white' stroke-width='1.6' stroke-linecap='round'><path d='M2 2 L8 8 M8 2 L2 8'/></svg>")
    center/10px no-repeat;
}
.lf-val-row:has(input:not(:placeholder-shown):valid) input {
  border-color: rgba(46, 184, 138, 0.55);
}
.lf-val-row:has(input:not(:placeholder-shown):valid)::after {
  opacity: 1;
  transform: scale(1);
  background: #2eb88a
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 10 10' fill='none' stroke='white' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M2 5 L4.2 7.2 L8 3'/></svg>")
    center/10px no-repeat;
}
.lf-val-btn {
  margin-top: 4px;
  padding: 11px;
  background: linear-gradient(135deg, #7c6cff, #ff6c8a);
  color: white;
  border: none;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: transform 0.12s;
}
.lf-val-btn:hover {
  transform: translateY(-1px);
}

Search CodeFronts

Loading…