Open demo

CSS code

HTML
<div class="gl">
  <div class="gl-blob gl-b1" aria-hidden="true"></div><div class="gl-blob gl-b2" aria-hidden="true"></div><div class="gl-blob gl-b3" aria-hidden="true"></div>
  <form class="gl-card" action="#" method="post" onsubmit="event.preventDefault()">
    <h1>Sign in</h1>
    <p class="gl-sub">Welcome back — we kept your seat warm.</p>
    <label class="gl-label" for="gl-email">Email</label>
    <input class="gl-input" type="email" id="gl-email" name="email" placeholder="[email protected]" autocomplete="username" required>
    <label class="gl-label" for="gl-password">Password</label>
    <input class="gl-input" type="password" id="gl-password" name="password" placeholder="Your password" autocomplete="current-password" required>
    <button class="gl-btn" type="submit">Enter dashboard</button>
    <p class="gl-alt">First time here? <a href="#">Create an account</a></p>
  </form>
</div>
CSS
/* Glass login: a translucent card with backdrop-filter blur over three slowly drifting colour blobs. */
.gl{--gl-bg:#0b0f1e;--gl-text:#eef0f6;--gl-muted:#aab0c4;--gl-line:rgba(255,255,255,.42);
  position:relative;overflow:hidden;min-height:100vh;display:flex;align-items:center;justify-content:center;padding:24px;
  background:var(--gl-bg);color:var(--gl-text);font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif}
.gl h1,.gl p{margin:0}
.gl-blob{position:absolute;border-radius:50%;filter:blur(90px);opacity:.55;pointer-events:none}
.gl-b1{width:420px;height:420px;background:#6d28d9;top:-120px;left:-80px;animation:gl-drift 14s ease-in-out infinite alternate}
.gl-b2{width:380px;height:380px;background:#0ea5e9;bottom:-100px;right:-60px;animation:gl-drift 17s ease-in-out infinite alternate-reverse}
.gl-b3{width:260px;height:260px;background:#db2777;bottom:20%;left:12%;animation:gl-drift 21s ease-in-out infinite alternate}
@keyframes gl-drift{to{transform:translate(60px,40px) scale(1.15)}}
.gl-card{position:relative;z-index:1;width:100%;max-width:380px;padding:44px 38px;border-radius:22px;background:rgba(255,255,255,.07);
  border:1px solid rgba(255,255,255,.16);-webkit-backdrop-filter:blur(22px);backdrop-filter:blur(22px);box-shadow:0 24px 60px rgba(0,0,0,.45)}
.gl h1{font-size:1.55rem;letter-spacing:-.02em;text-align:center;margin-bottom:6px}
.gl-sub{text-align:center;color:var(--gl-muted);font-size:.9rem;margin-bottom:30px!important}
.gl-label{display:block;font-size:.8rem;font-weight:600;color:#c8cddd;margin-bottom:7px}
.gl-input{display:block;width:100%;padding:12px 14px;margin-bottom:18px;border-radius:11px;border:1px solid var(--gl-line);background:rgba(255,255,255,.06);
  color:#fff;font:inherit;font-size:.95rem;transition:border-color .15s,background-color .15s,box-shadow .15s}
.gl-input::placeholder{color:#9ba1b5}
.gl-input:focus{outline:none;border-color:rgba(255,255,255,.85);background:rgba(255,255,255,.1);box-shadow:0 0 0 3px rgba(255,255,255,.18)}
.gl-btn{width:100%;padding:13px;border:0;border-radius:11px;font:inherit;font-weight:700;font-size:.95rem;cursor:pointer;color:#0b0f1e;
  background:linear-gradient(90deg,#e0e7ff,#fff);transition:transform .12s,box-shadow .15s;margin-top:6px}
.gl-btn:hover{transform:translateY(-1px);box-shadow:0 10px 26px rgba(255,255,255,.18)}
.gl-alt{margin-top:22px!important;text-align:center;font-size:.85rem;color:var(--gl-muted)}
.gl-alt a{color:#fff;font-weight:600;text-decoration:none;border-bottom:1px solid rgba(255,255,255,.5)}
.gl-alt a:hover{border-bottom-color:#fff}
.gl a:focus-visible,.gl-btn:focus-visible{outline:2px solid #fff;outline-offset:3px;border-radius:3px}
.gl-btn:focus-visible{border-radius:11px}
@media (prefers-reduced-motion:reduce){.gl-blob{animation:none}.gl-input,.gl-btn{transition:none}.gl-btn:hover{transform:none}}

Bootstrap 5 code

Requires: Bootstrap 5.3.8 CSS

HTML
<div class="gl position-relative overflow-hidden d-flex align-items-center justify-content-center">
  <div class="gl-blob gl-b1 position-absolute" aria-hidden="true"></div><div class="gl-blob gl-b2 position-absolute" aria-hidden="true"></div><div class="gl-blob gl-b3 position-absolute" aria-hidden="true"></div>
  <form class="card position-relative w-100" action="#" method="post" onsubmit="event.preventDefault()">
    <div class="card-body">
      <h1 class="text-center">Sign in</h1>
      <p class="gl-sub text-center">Welcome back — we kept your seat warm.</p>
      <div class="gl-field">
        <label class="form-label" for="gl-email">Email</label>
        <input class="form-control" type="email" id="gl-email" name="email" placeholder="[email protected]" autocomplete="username" required>
      </div>
      <div class="gl-field">
        <label class="form-label" for="gl-password">Password</label>
        <input class="form-control" type="password" id="gl-password" name="password" placeholder="Your password" autocomplete="current-password" required>
      </div>
      <button class="btn btn-gl w-100" type="submit">Enter dashboard</button>
      <p class="gl-alt text-center mb-0">First time here? <a href="#">Create an account</a></p>
    </div>
  </form>
</div>
CSS
/* Bootstrap .card made translucent through --bs-card-* variables, dark .form-control fields and a gradient .btn. */
.gl{--gl-muted:#aab0c4;
  --bs-body-font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  min-height:100vh;padding:24px;background:#0b0f1e;color:#eef0f6;font-family:var(--bs-body-font-family);line-height:normal}
.gl-blob{border-radius:50%;filter:blur(90px);opacity:.55;pointer-events:none}
.gl-b1{width:420px;height:420px;background:#6d28d9;top:-120px;left:-80px;animation:gl-drift 14s ease-in-out infinite alternate}
.gl-b2{width:380px;height:380px;background:#0ea5e9;bottom:-100px;right:-60px;animation:gl-drift 17s ease-in-out infinite alternate-reverse}
.gl-b3{width:260px;height:260px;background:#db2777;bottom:20%;left:12%;animation:gl-drift 21s ease-in-out infinite alternate}
@keyframes gl-drift{to{transform:translate(60px,40px) scale(1.15)}}
.gl .card{--bs-card-bg:rgba(255,255,255,.07);--bs-card-border-color:rgba(255,255,255,.16);--bs-card-border-radius:22px;
  --bs-card-spacer-y:44px;--bs-card-spacer-x:38px;--bs-card-color:#eef0f6;z-index:1;max-width:380px;
  -webkit-backdrop-filter:blur(22px);backdrop-filter:blur(22px);box-shadow:0 24px 60px rgba(0,0,0,.45)}
.gl h1{font-size:1.55rem;letter-spacing:-.02em;font-weight:700;margin-bottom:6px}
.gl-field{margin-bottom:18px}
.gl-sub{color:var(--gl-muted);font-size:.9rem;margin-bottom:30px}
.gl .form-label{font-size:.8rem;font-weight:600;color:#c8cddd;margin-bottom:7px}
.gl .form-control{padding:12px 14px;border-radius:11px;border-color:rgba(255,255,255,.42);background-color:rgba(255,255,255,.06);
  color:#fff;font-size:.95rem;line-height:1.2}
.gl .form-control::placeholder{color:#9ba1b5}
.gl .form-control:focus{border-color:rgba(255,255,255,.85);background-color:rgba(255,255,255,.1);color:#fff;box-shadow:0 0 0 3px rgba(255,255,255,.18)}
.gl .btn-gl{--bs-btn-color:#0b0f1e;--bs-btn-hover-color:#0b0f1e;--bs-btn-active-color:#0b0f1e;--bs-btn-border-width:0;
  --bs-btn-padding-y:13px;--bs-btn-font-size:.95rem;--bs-btn-font-weight:700;--bs-btn-border-radius:11px;--bs-btn-line-height:1.2;
  --bs-btn-focus-box-shadow:none;margin-top:6px;background:linear-gradient(90deg,#e0e7ff,#fff);transition:transform .12s,box-shadow .15s}
.gl .btn-gl:hover{transform:translateY(-1px);box-shadow:0 10px 26px rgba(255,255,255,.18)}
.gl-alt{color:var(--gl-muted);font-size:.85rem;margin-top:22px}
.gl-alt a{color:#fff;font-weight:600;text-decoration:none;border-bottom:1px solid rgba(255,255,255,.5)}
.gl-alt a:hover{border-bottom-color:#fff}
.gl a:focus-visible,.gl .btn-gl:focus-visible{outline:2px solid #fff;outline-offset:3px;border-radius:3px}
.gl .btn-gl:focus-visible{border-radius:11px}
@media (prefers-reduced-motion:reduce){.gl-blob{animation:none}.gl .form-control,.gl .btn-gl{transition:none}.gl .btn-gl:hover{transform:none}}

Tailwind 4 code

Requires: Tailwind CSS 4

HTML
<div class="relative flex min-h-screen items-center justify-center overflow-hidden bg-gl-bg p-6 font-[-apple-system,BlinkMacSystemFont,'Segoe_UI',Roboto,Helvetica,Arial,sans-serif] leading-[normal] text-[#eef0f6]">
  <div class="pointer-events-none absolute -top-[120px] -left-20 size-[420px] rounded-full bg-[#6d28d9] opacity-55 blur-[90px] motion-safe:animate-gl-drift" aria-hidden="true"></div>
  <div class="pointer-events-none absolute -right-[60px] -bottom-[100px] size-[380px] rounded-full bg-[#0ea5e9] opacity-55 blur-[90px] motion-safe:animate-[gl-drift_17s_ease-in-out_infinite_alternate-reverse]" aria-hidden="true"></div>
  <div class="pointer-events-none absolute bottom-[20%] left-[12%] size-[260px] rounded-full bg-[#db2777] opacity-55 blur-[90px] motion-safe:animate-[gl-drift_21s_ease-in-out_infinite_alternate]" aria-hidden="true"></div>
  <form class="relative z-10 w-full max-w-[380px] rounded-[22px] border border-white/16 bg-white/7 px-[38px] py-11 shadow-[0_24px_60px_rgba(0,0,0,.45)] backdrop-blur-[22px]" action="#" method="post" onsubmit="event.preventDefault()">
    <h1 class="mb-1.5 text-center text-[1.55rem] font-bold tracking-[-.02em]">Sign in</h1>
    <p class="mb-[30px] text-center text-[.9rem] text-gl-muted">Welcome back — we kept your seat warm.</p>
    <label class="mb-[7px] block text-[.8rem] font-semibold text-[#c8cddd]" for="gl-email">Email</label>
    <input class="mb-[18px] block w-full rounded-[11px] border border-white/42 bg-white/6 px-3.5 py-3 text-[.95rem] text-white transition-[border-color,background-color,box-shadow] duration-150 placeholder:text-[#9ba1b5] focus:border-white/85 focus:bg-white/10 focus:shadow-[0_0_0_3px_rgba(255,255,255,.18)] focus:outline-none motion-reduce:transition-none" type="email" id="gl-email" name="email" placeholder="[email protected]" autocomplete="username" required>
    <label class="mb-[7px] block text-[.8rem] font-semibold text-[#c8cddd]" for="gl-password">Password</label>
    <input class="mb-[18px] block w-full rounded-[11px] border border-white/42 bg-white/6 px-3.5 py-3 text-[.95rem] text-white transition-[border-color,background-color,box-shadow] duration-150 placeholder:text-[#9ba1b5] focus:border-white/85 focus:bg-white/10 focus:shadow-[0_0_0_3px_rgba(255,255,255,.18)] focus:outline-none motion-reduce:transition-none" type="password" id="gl-password" name="password" placeholder="Your password" autocomplete="current-password" required>
    <button class="mt-1.5 w-full cursor-pointer rounded-[11px] bg-linear-90 from-[#e0e7ff] to-white p-[13px] text-[.95rem] font-bold text-gl-bg transition-[transform,box-shadow] duration-150 hover:-translate-y-px hover:shadow-[0_10px_26px_rgba(255,255,255,.18)] focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-white motion-reduce:transition-none motion-reduce:hover:translate-y-0" type="submit">Enter dashboard</button>
    <p class="mt-[22px] text-center text-[.85rem] text-gl-muted">First time here? <a class="rounded-[3px] border-b border-white/50 font-semibold text-white hover:border-white focus-visible:outline-2 focus-visible:outline-offset-3 focus-visible:outline-white" href="#">Create an account</a></p>
  </form>
</div>
CSS
@theme {
  --color-gl-bg: #0b0f1e;
  --color-gl-muted: #aab0c4;
  --animate-gl-drift: gl-drift 14s ease-in-out infinite alternate;
  @keyframes gl-drift { to { transform: translate(60px, 40px) scale(1.15); } }
}

About this set

A dark sign-in screen with a frosted glass card floating over three large blurred colour blobs in violet, sky blue and pink. The blobs drift slowly on 14 to 21 second loops, and the card blurs whatever is behind it with backdrop-filter, so the colours move softly through the glass. The card holds a centred heading, a short welcome line, email and password fields with visible labels, a pale gradient Enter dashboard button and a link to create an account. Use it for apps with a dark interface, creative tools or a product launch where the login screen should feel atmospheric. The field borders were lightened from the original so they reach 3:1 against the dark card, and placeholder text was brightened to meet 4.5:1. The drift animation and the button lift on hover stop completely when the visitor prefers reduced motion. The Bootstrap version turns .card translucent through its –bs-card-* variables and restyles .form-control for a dark surface; the Tailwind version defines the drift keyframes in @theme and applies them with motion-safe:.

What’s included

  • Frosted card using backdrop-filter blur over animated colour blobs
  • Blob drift and hover lift disabled under prefers-reduced-motion
  • Dark-surface fields with 3:1 borders and 4.5:1 placeholder text
  • Visible labels and autocomplete attributes on both fields
  • Bootstrap .card made translucent through CSS variables

Accessibility

Both fields have visible labels, the decorative blobs are aria-hidden, and text on the card meets WCAG AA contrast. Inputs brighten their border and gain a ring on focus; the button and link show a 2px white outline on keyboard focus. All animation and transitions stop under prefers-reduced-motion.

Customise it

Change the blob colours on .gl-b1 to .gl-b3 and --gl-line for the field borders. In Tailwind edit the bg-[#...] colours on the three blob divs and the --animate-gl-drift timing in @theme.