30 Tailwind CSS Login Forms
18 / 30

All 30 in 30 Tailwind CSS Login Forms

  1. 01Tailwind Split-Screen Brand Hero Login Form
  2. 02Tailwind Multi-Tenant Workspace Account Switcher
  3. 03Tailwind Floating Label Login Form with peer Variants
  4. 04Tailwind Web3 Wallet Connect Login Grid
  5. 05Tailwind Minimalist Fintech Login Card with Layered Shadow
  6. 06Tailwind OAuth Social Login Form with Brand SVG Buttons
  7. 07Tailwind Passwordless Magic Link Login with data-state Machine
  8. 08Tailwind Aurora Glow Login Card with Drifting Blur Blobs
  9. 09Tailwind Neon Synthwave Arcade Login Form
  10. 10Tailwind Sliding Login and Sign Up Panel with peer-checked
  11. 11Tailwind 3D Flip Login Card with Password Reset Back Face
  12. 12Tailwind Terminal CLI Prompt Login Form
  13. 13Tailwind Floating Pill Login Widget Docked Over App Content
  14. 14Tailwind Gradient Border Login Card with background-clip
  15. 15Tailwind Slide-Over Side Panel Login without JavaScript
  16. 16Tailwind Social-First Sign Up with Brand-Compliant Buttons
  17. 17Tailwind Animated Mascot Login that Covers Its Eyes
  18. 18Tailwind Accessible Compact Login Modal with Scale-In
  19. 19Tailwind Glassmorphism Login Card with backdrop-filter
  20. 20Tailwind Multi-Step Login Wizard with Radio-Driven Track
  21. 21Tailwind Animated Conic Gradient Border Login Card
  22. 22Tailwind Secure Vault Login with user-invalid Error State
  23. 23Tailwind Neo-Brutalist Login Form with Hard Offset Shadow
  24. 24Tailwind Show Hide Password Toggle with aria-pressed
  25. 25Tailwind OTP Code Input Grid with Auto-Advance
  26. 26Tailwind Password Strength Meter with data-score Variants
  27. 27Tailwind Numeric PIN Pad Login for Kiosks and POS
  28. 28Tailwind Inline Form Validation with user-valid and user-invalid
  29. 29Tailwind Particle Constellation Login over Canvas
  30. 30Tailwind Biometric Face ID Prompt with Pulse Ripples
Pure TailwindMIT licensed

Tailwind Accessible Compact Login Modal with Scale-In

A light pop-up auth dialog for media and membership sites: a small centred card scales in over blurred page content. Accessibility-first — real dialog semantics, visible focus on every control, and a closed overlay that cannot intercept clicks. The port also states the pattern's limit honestly: CSS gets you the look, <dialog> gets you focus trapping.

Live Demo
Plain CSSTailwind v4
Try it

Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time

Untitled UI React · Affiliate link

Get Untitled UI Pro

The code

<section class="tlf-18 relative w-full min-h-svh overflow-hidden bg-tlf18-stage font-tlf18-sans">
  <input type="checkbox" id="tlf-18-open" checked aria-label="Open login dialog" class="peer sr-only">
  <div class="w-full min-h-svh grid place-items-center gap-4 p-8 text-center">
    <div>
      <p aria-hidden="true" class="text-xs font-semibold uppercase tracking-[0.14em] text-tlf18-mut">Members-only story &middot; 4 min read</p>
      <h1 aria-hidden="true" class="mt-3 mb-5 max-w-[22ch] mx-auto text-[32px]/[1.2] font-semibold text-tlf18-ink font-tlf18-display">The quiet economics of the second-hand book trade</h1>
      <label for="tlf-18-open" class="inline-grid place-items-center min-h-11 px-6 rounded-full cursor-pointer bg-tlf18-acc text-white text-sm font-semibold transition-[filter] duration-150 hover:brightness-110">Log in to read</label>
    </div>
  </div>
  <div class="absolute inset-0 z-5 grid place-items-center p-6 bg-tlf18-scrim opacity-0 pointer-events-none transition-[opacity,backdrop-filter] duration-250 peer-checked:opacity-100 peer-checked:pointer-events-auto peer-checked:backdrop-blur-sm motion-reduce:transition-opacity">
    <label for="tlf-18-open" aria-label="Close dialog" class="absolute inset-0 cursor-pointer"></label>
    <form novalidate role="dialog" aria-modal="true" aria-label="Log in" class="relative w-[min(360px,100%)] flex flex-col gap-3.5 p-8 bg-white rounded-[18px] shadow-[0_30px_70px_-30px_oklch(0.2_0.02_280/0.45)] scale-95 transition-transform duration-250 peer-checked:scale-100 motion-reduce:transition-none">
      <label for="tlf-18-open" aria-label="Close" class="absolute top-2.5 right-2.5 grid place-items-center size-11 rounded-lg cursor-pointer text-2xl leading-none text-tlf18-mut transition-colors duration-150 hover:bg-tlf18-hover hover:text-tlf18-ink">&times;</label>
      <h2 class="text-xl font-semibold text-tlf18-ink font-tlf18-display">Welcome back</h2>
      <p class="-mt-1.5 mb-1 text-[13px] text-tlf18-mut">Members read everything, ad-free.</p>
      <label class="flex flex-col gap-1.5"><span class="text-[13px] font-semibold text-tlf18-label">Email</span>
        <input type="email" autocomplete="email" placeholder="you@company.com" required class="h-12 px-3.5 rounded-xl text-[15px] text-tlf18-ink bg-tlf18-field border-[1.5px] border-tlf18-edge transition-[border-color,box-shadow] duration-150 placeholder:text-tlf18-ph focus-visible:outline-none focus-visible:border-tlf18-acc focus-visible:ring-4 focus-visible:ring-tlf18-halo"></label>
      <label class="flex flex-col gap-1.5"><span class="text-[13px] font-semibold text-tlf18-label">Password</span>
        <input type="password" autocomplete="current-password" placeholder="&bull;&bull;&bull;&bull;&bull;&bull;&bull;&bull;" required class="h-12 px-3.5 rounded-xl text-[15px] text-tlf18-ink bg-tlf18-field border-[1.5px] border-tlf18-edge transition-[border-color,box-shadow] duration-150 placeholder:text-tlf18-ph focus-visible:outline-none focus-visible:border-tlf18-acc focus-visible:ring-4 focus-visible:ring-tlf18-halo"></label>
      <button type="submit" class="mt-1 h-12 rounded-xl border-0 cursor-pointer bg-tlf18-acc text-white text-[15px] font-semibold transition-[filter,scale] duration-150 hover:brightness-110 active:scale-[0.985] focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tlf18-ring motion-reduce:transition-none motion-reduce:active:scale-100">Log in</button>
    </form>
  </div>
</section>
@import "tailwindcss";

@theme {
  --color-tlf18-stage: #f7f5f2;
  --color-tlf18-stage: oklch(0.97 0.006 75);
  --color-tlf18-ink: #1f1d1a;
  --color-tlf18-ink: oklch(0.24 0.012 70);
  --color-tlf18-label: #45413c;
  --color-tlf18-label: oklch(0.4 0.014 70);
  --color-tlf18-mut: #6d6862;
  --color-tlf18-mut: oklch(0.54 0.014 70);
  --color-tlf18-ph: #9b958d;
  --color-tlf18-ph: oklch(0.68 0.014 70);
  --color-tlf18-edge: #e2ded8;
  --color-tlf18-edge: oklch(0.9 0.008 70);
  --color-tlf18-field: #fdfcfb;
  --color-tlf18-field: oklch(0.99 0.003 70);
  --color-tlf18-hover: #f1efec;
  --color-tlf18-hover: oklch(0.95 0.006 70);
  --color-tlf18-acc: #9a3412;
  --color-tlf18-acc: oklch(0.45 0.15 40);
  --color-tlf18-halo: #e8c0a8;
  --color-tlf18-halo: oklch(0.45 0.15 40 / 0.18);
  --color-tlf18-ring: #d09272;
  --color-tlf18-ring: oklch(0.45 0.15 40 / 0.5);
  --color-tlf18-scrim: #1f1d1a;
  --color-tlf18-scrim: oklch(0.24 0.012 70 / 0.42);
  --font-tlf18-display: 'Newsreader', Georgia, serif;
  --font-tlf18-sans: 'DM Sans', system-ui, sans-serif;
}

.tlf-18 {
  width: 100%;
  min-height: 100svh;
}
/* Safari < 16.4 backdrop-filter prefix; applied only while the dialog is open. */

.tlf-18 .peer:checked ~ div > div,
.tlf-18 input:checked ~ div[class*="z-5"] {
  -webkit-backdrop-filter: blur(4px);
}

Setup — do this once per project

Skip this if your project already runs Tailwind v4.

1Load Tailwind
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>

Compiles in the browser — perfect for a CodePen or a quick test, not for production.

2Add the stylesheetRequiredthe @theme block is what makes the custom utilities exist
@import "tailwindcss";

@theme {
  --color-tlf18-stage: #f7f5f2;
  --color-tlf18-stage: oklch(0.97 0.006 75);
  --color-tlf18-ink: #1f1d1a;
  --color-tlf18-ink: oklch(0.24 0.012 70);
  --color-tlf18-label: #45413c;
  --color-tlf18-label: oklch(0.4 0.014 70);
  --color-tlf18-mut: #6d6862;
  --color-tlf18-mut: oklch(0.54 0.014 70);
  --color-tlf18-ph: #9b958d;
  --color-tlf18-ph: oklch(0.68 0.014 70);
  --color-tlf18-edge: #e2ded8;
  --color-tlf18-edge: oklch(0.9 0.008 70);
  --color-tlf18-field: #fdfcfb;
  --color-tlf18-field: oklch(0.99 0.003 70);
  --color-tlf18-hover: #f1efec;
  --color-tlf18-hover: oklch(0.95 0.006 70);
  --color-tlf18-acc: #9a3412;
  --color-tlf18-acc: oklch(0.45 0.15 40);
  --color-tlf18-halo: #e8c0a8;
  --color-tlf18-halo: oklch(0.45 0.15 40 / 0.18);
  --color-tlf18-ring: #d09272;
  --color-tlf18-ring: oklch(0.45 0.15 40 / 0.5);
  --color-tlf18-scrim: #1f1d1a;
  --color-tlf18-scrim: oklch(0.24 0.012 70 / 0.42);
  --font-tlf18-display: 'Newsreader', Georgia, serif;
  --font-tlf18-sans: 'DM Sans', system-ui, sans-serif;
}

.tlf-18 {
  width: 100%;
  min-height: 100svh;
}
/* Safari < 16.4 backdrop-filter prefix; applied only while the dialog is open. */

.tlf-18 .peer:checked ~ div > div,
.tlf-18 input:checked ~ div[class*="z-5"] {
  -webkit-backdrop-filter: blur(4px);
}
3Fonts used by this demooptional — skip if you have your own type stack
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Newsreader:opsz,wght@6..72,400;6..72,600&family=DM+Sans:wght@400;500;600;700&display=swap">

What changed in the port

Which parts became utilities, which stayed CSS, and why.

  • peer-checked:backdrop-blur-sm rather than a permanent blur: the original blurred the page unconditionally, which meant the &ldquo;blurred page&rdquo; look persisted after close.
  • The backdrop is a full-bleed <label> inside the overlay and the card is relative above it, so clicking outside closes while clicking the form does not — no stopPropagation, because there is no script.
  • Two font tokens give the demo a magazine voice (Newsreader headline, DM Sans UI) without a single class-based type rule.
  • UI change from the CSS original: a real article headline replaces the placeholder line so the paywall context reads, the close control went 34px → size-11, the muted grey lifted to oklch(0.54), and the terracotta accent deepened to 0.45 for 4.8:1 against white button text.
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind Accessible Compact Login Modal with Scale-In
Source: https://codefronts.com/components/tailwind-css-login-forms/tailwind-accessible-compact-login-modal/

A light pop-up auth dialog for media and membership sites: a small centred card scales in over blurred page content. Accessibility-first &mdash; real dialog semantics, visible focus on every control, and a closed overlay that cannot intercept clicks. The port also states the pattern's limit honestly: CSS gets you the look, <dialog> gets you focus trapping.
## HTML
```html
<section class="tlf-18 relative w-full min-h-svh overflow-hidden bg-tlf18-stage font-tlf18-sans">
  <input type="checkbox" id="tlf-18-open" checked aria-label="Open login dialog" class="peer sr-only">
  <div class="w-full min-h-svh grid place-items-center gap-4 p-8 text-center">
    <div>
      <p aria-hidden="true" class="text-xs font-semibold uppercase tracking-[0.14em] text-tlf18-mut">Members-only story &middot; 4 min read</p>
      <h1 aria-hidden="true" class="mt-3 mb-5 max-w-[22ch] mx-auto text-[32px]/[1.2] font-semibold text-tlf18-ink font-tlf18-display">The quiet economics of the second-hand book trade</h1>
      <label for="tlf-18-open" class="inline-grid place-items-center min-h-11 px-6 rounded-full cursor-pointer bg-tlf18-acc text-white text-sm font-semibold transition-[filter] duration-150 hover:brightness-110">Log in to read</label>
    </div>
  </div>
  <div class="absolute inset-0 z-5 grid place-items-center p-6 bg-tlf18-scrim opacity-0 pointer-events-none transition-[opacity,backdrop-filter] duration-250 peer-checked:opacity-100 peer-checked:pointer-events-auto peer-checked:backdrop-blur-sm motion-reduce:transition-opacity">
    <label for="tlf-18-open" aria-label="Close dialog" class="absolute inset-0 cursor-pointer"></label>
    <form novalidate role="dialog" aria-modal="true" aria-label="Log in" class="relative w-[min(360px,100%)] flex flex-col gap-3.5 p-8 bg-white rounded-[18px] shadow-[0_30px_70px_-30px_oklch(0.2_0.02_280/0.45)] scale-95 transition-transform duration-250 peer-checked:scale-100 motion-reduce:transition-none">
      <label for="tlf-18-open" aria-label="Close" class="absolute top-2.5 right-2.5 grid place-items-center size-11 rounded-lg cursor-pointer text-2xl leading-none text-tlf18-mut transition-colors duration-150 hover:bg-tlf18-hover hover:text-tlf18-ink">&times;</label>
      <h2 class="text-xl font-semibold text-tlf18-ink font-tlf18-display">Welcome back</h2>
      <p class="-mt-1.5 mb-1 text-[13px] text-tlf18-mut">Members read everything, ad-free.</p>
      <label class="flex flex-col gap-1.5"><span class="text-[13px] font-semibold text-tlf18-label">Email</span>
        <input type="email" autocomplete="email" placeholder="you@company.com" required class="h-12 px-3.5 rounded-xl text-[15px] text-tlf18-ink bg-tlf18-field border-[1.5px] border-tlf18-edge transition-[border-color,box-shadow] duration-150 placeholder:text-tlf18-ph focus-visible:outline-none focus-visible:border-tlf18-acc focus-visible:ring-4 focus-visible:ring-tlf18-halo"></label>
      <label class="flex flex-col gap-1.5"><span class="text-[13px] font-semibold text-tlf18-label">Password</span>
        <input type="password" autocomplete="current-password" placeholder="&bull;&bull;&bull;&bull;&bull;&bull;&bull;&bull;" required class="h-12 px-3.5 rounded-xl text-[15px] text-tlf18-ink bg-tlf18-field border-[1.5px] border-tlf18-edge transition-[border-color,box-shadow] duration-150 placeholder:text-tlf18-ph focus-visible:outline-none focus-visible:border-tlf18-acc focus-visible:ring-4 focus-visible:ring-tlf18-halo"></label>
      <button type="submit" class="mt-1 h-12 rounded-xl border-0 cursor-pointer bg-tlf18-acc text-white text-[15px] font-semibold transition-[filter,scale] duration-150 hover:brightness-110 active:scale-[0.985] focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tlf18-ring motion-reduce:transition-none motion-reduce:active:scale-100">Log in</button>
    </form>
  </div>
</section>
```
## CSS
```css
@import "tailwindcss";

@theme {
  --color-tlf18-stage: #f7f5f2;
  --color-tlf18-stage: oklch(0.97 0.006 75);
  --color-tlf18-ink: #1f1d1a;
  --color-tlf18-ink: oklch(0.24 0.012 70);
  --color-tlf18-label: #45413c;
  --color-tlf18-label: oklch(0.4 0.014 70);
  --color-tlf18-mut: #6d6862;
  --color-tlf18-mut: oklch(0.54 0.014 70);
  --color-tlf18-ph: #9b958d;
  --color-tlf18-ph: oklch(0.68 0.014 70);
  --color-tlf18-edge: #e2ded8;
  --color-tlf18-edge: oklch(0.9 0.008 70);
  --color-tlf18-field: #fdfcfb;
  --color-tlf18-field: oklch(0.99 0.003 70);
  --color-tlf18-hover: #f1efec;
  --color-tlf18-hover: oklch(0.95 0.006 70);
  --color-tlf18-acc: #9a3412;
  --color-tlf18-acc: oklch(0.45 0.15 40);
  --color-tlf18-halo: #e8c0a8;
  --color-tlf18-halo: oklch(0.45 0.15 40 / 0.18);
  --color-tlf18-ring: #d09272;
  --color-tlf18-ring: oklch(0.45 0.15 40 / 0.5);
  --color-tlf18-scrim: #1f1d1a;
  --color-tlf18-scrim: oklch(0.24 0.012 70 / 0.42);
  --font-tlf18-display: 'Newsreader', Georgia, serif;
  --font-tlf18-sans: 'DM Sans', system-ui, sans-serif;
}

.tlf-18 {
  width: 100%;
  min-height: 100svh;
}
/* Safari < 16.4 backdrop-filter prefix; applied only while the dialog is open. */

.tlf-18 .peer:checked ~ div > div,
.tlf-18 input:checked ~ div[class*="z-5"] {
  -webkit-backdrop-filter: blur(4px);
}
```

How this works

Open state lives on a checkbox. The trigger, the × and the backdrop are all labels for the same peer sr-only input, so open and close are keyboard-operable and need no script.

Two properties animate. opacity and scale, from 0.95, on a 250ms curve. That is the whole entrance, and it is deliberately smaller than the flip and slide demos: a dialog that draws attention to its own animation delays the thing the user came for.

Semantics are not the port's business. role="dialog", aria-modal="true" and aria-label ride the same element as the utilities. What Tailwind cannot supply — focus trapping, Escape, returning focus on close — is called out in the gotchas rather than papered over.

Make it yours

  • Enter feel: scale-95 and duration-250.
  • Page blur: peer-checked:backdrop-blur-sm → backdrop-blur-md.
  • Accent: --color-tlf18-acc drives the trigger, the submit and every ring.
  • Swap the demo trigger for your real nav Sign-in control — it is just a <label>.

Gotchas — read before shipping

  • This is a CSS-only modal: it does not trap focus, close on Escape, or restore focus to the trigger. For anything gating content or payment, use <dialog> with showModal() and keep these visuals.
  • Pair opacity-0 with pointer-events-none on the overlay, always.
  • Centre with grid place-items-center rather than margins, so the card stays centred as its content changes height.

Browser support

ChromeSafariFirefoxEdge
111+16.4+128+111+

backdrop-filter ships prefixed for older Safari in the stylesheet; everything else is universally supported.

Techniques used in this demo

Utilitiesfirst-class utility or variant

HTML & JSno Tailwind involved

Search CodeFronts

Loading…