30 Tailwind CSS Login Forms
30 / 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 Biometric Face ID Prompt with Pulse Ripples

A PWA-style face / touch-ID prompt: a large biometric glyph in a circular target with concentric ripples signalling that the app is listening. The port's substantive point is not the animation — it is that the fallback link is mandatory, and the markup says so.

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-30 w-full min-h-svh grid place-items-center bg-tlf30-stage font-tlf30-sans p-6">
  <div class="w-[min(360px,100%)] p-9 text-center bg-tlf30-card border border-tlf30-edge rounded-[22px] text-tlf30-ink shadow-[0_30px_70px_-44px_black]">
    <h1 class="text-[22px] font-bold">Confirm it&rsquo;s you</h1>
    <p class="mt-1.5 mb-7 text-[13.5px]/[1.5] text-tlf30-mut">Use Face ID or your fingerprint to sign in.</p>
    <button type="button" aria-label="Authenticate with biometrics" class="relative grid place-items-center size-26 mx-auto mb-6 rounded-full border-0 cursor-pointer bg-tlf30-wash text-tlf30-acc transition-[background-color,scale] duration-150 hover:bg-tlf30-washhover active:scale-95 focus-visible:outline-3 focus-visible:outline-offset-4 focus-visible:outline-tlf30-ring motion-reduce:transition-colors motion-reduce:active:scale-100">
      <span aria-hidden="true" class="absolute inset-0 rounded-full border-2 border-tlf30-acc opacity-0 animate-tlf30-pulse motion-reduce:animate-none motion-reduce:opacity-40 motion-reduce:-inset-1.5"></span>
      <span aria-hidden="true" class="absolute inset-0 rounded-full border-2 border-tlf30-acc opacity-0 animate-tlf30-pulse [animation-delay:1.2s] motion-reduce:hidden"></span>
      <svg viewBox="0 0 24 24" aria-hidden="true" class="relative size-13"><path fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" d="M5 11a7 7 0 0 1 14 0M7.5 12.5a4.5 4.5 0 0 1 9 0v1.5M12 12v4M9.5 15v1.5M14.5 14.5V17M4.5 14v1"></path></svg>
    </button>
    <p role="status" aria-live="polite" class="mb-5 text-[12.5px] text-tlf30-mut">Waiting for authentication&hellip;</p>
    <a href="#" class="inline-grid place-items-center min-h-11 px-3 text-[13.5px] font-semibold text-tlf30-acc no-underline hover:underline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tlf30-acc">Use passcode instead</a>
  </div>
</section>
@import "tailwindcss";

@theme {
  --color-tlf30-stage: #0f1220;
  --color-tlf30-stage: oklch(0.17 0.025 275);
  --color-tlf30-card: #171a2b;
  --color-tlf30-card: oklch(0.22 0.025 275);
  --color-tlf30-edge: #2b3048;
  --color-tlf30-edge: oklch(0.29 0.028 275);
  --color-tlf30-ink: #e9ecf7;
  --color-tlf30-ink: oklch(0.94 0.01 275);
  --color-tlf30-mut: #a6adc6;
  --color-tlf30-mut: oklch(0.75 0.022 275);
  --color-tlf30-acc: #8ba4f5;
  --color-tlf30-acc: oklch(0.72 0.14 265);
  --color-tlf30-wash: #232a4a;
  --color-tlf30-wash: oklch(0.72 0.14 265 / 0.16);
  --color-tlf30-washhover: #2c3660;
  --color-tlf30-washhover: oklch(0.72 0.14 265 / 0.24);
  --color-tlf30-ring: #adbef8;
  --color-tlf30-ring: oklch(0.72 0.14 265 / 0.6);
  --font-tlf30-sans: 'Sora', system-ui, sans-serif;
  --animate-tlf30-pulse: tlf-30-pulse 2.4s ease-out infinite;
}

@keyframes tlf-30-pulse {
  0% {
    transform: scale(0.7);
    opacity: 0.7;
  }

  80%,
    100% {
    transform: scale(1.5);
    opacity: 0;
  }
}

.tlf-30 {
  width: 100%;
  min-height: 100svh;
  color-scheme: dark;
}

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-tlf30-stage: #0f1220;
  --color-tlf30-stage: oklch(0.17 0.025 275);
  --color-tlf30-card: #171a2b;
  --color-tlf30-card: oklch(0.22 0.025 275);
  --color-tlf30-edge: #2b3048;
  --color-tlf30-edge: oklch(0.29 0.028 275);
  --color-tlf30-ink: #e9ecf7;
  --color-tlf30-ink: oklch(0.94 0.01 275);
  --color-tlf30-mut: #a6adc6;
  --color-tlf30-mut: oklch(0.75 0.022 275);
  --color-tlf30-acc: #8ba4f5;
  --color-tlf30-acc: oklch(0.72 0.14 265);
  --color-tlf30-wash: #232a4a;
  --color-tlf30-wash: oklch(0.72 0.14 265 / 0.16);
  --color-tlf30-washhover: #2c3660;
  --color-tlf30-washhover: oklch(0.72 0.14 265 / 0.24);
  --color-tlf30-ring: #adbef8;
  --color-tlf30-ring: oklch(0.72 0.14 265 / 0.6);
  --font-tlf30-sans: 'Sora', system-ui, sans-serif;
  --animate-tlf30-pulse: tlf-30-pulse 2.4s ease-out infinite;
}

@keyframes tlf-30-pulse {
  0% {
    transform: scale(0.7);
    opacity: 0.7;
  }

  80%,
    100% {
    transform: scale(1.5);
    opacity: 0;
  }
}

.tlf-30 {
  width: 100%;
  min-height: 100svh;
  color-scheme: dark;
}
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=Sora:wght@400;500;600;700&display=swap">

What changed in the port

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

  • [animation-delay:1.2s] is the whole reason two elements read as an endless ripple; an arbitrary property is the right home for it, because a delay tied to one animation's duration is not a design-scale value.
  • The motion-reduce: trio on the first ring (no animation, 40% opacity, expanded inset) is a small piece of design work rather than a switch-off — the prompt still looks like it is listening.
  • The fallback link is the only element in the collection whose justification is entirely non-visual, and it gets a 44px target for the same reason.
  • UI change from the CSS original: Sora replaces the system stack, the muted copy and status text lifted from #9298b3 / #7f86a3 to a single oklch(0.75 0.022 275) token (7.2:1 on the card, up from 3.9:1 on the status line), the accent brightened to 0.72, and the fallback link became a 44px target instead of bare 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 Biometric Face ID Prompt with Pulse Ripples
Source: https://codefronts.com/components/tailwind-css-login-forms/tailwind-biometric-face-id-prompt-pulse-ripples/

A PWA-style face / touch-ID prompt: a large biometric glyph in a circular target with concentric ripples signalling that the app is listening. The port's substantive point is not the animation &mdash; it is that the fallback link is mandatory, and the markup says so.
## HTML
```html
<section class="tlf-30 w-full min-h-svh grid place-items-center bg-tlf30-stage font-tlf30-sans p-6">
  <div class="w-[min(360px,100%)] p-9 text-center bg-tlf30-card border border-tlf30-edge rounded-[22px] text-tlf30-ink shadow-[0_30px_70px_-44px_black]">
    <h1 class="text-[22px] font-bold">Confirm it&rsquo;s you</h1>
    <p class="mt-1.5 mb-7 text-[13.5px]/[1.5] text-tlf30-mut">Use Face ID or your fingerprint to sign in.</p>
    <button type="button" aria-label="Authenticate with biometrics" class="relative grid place-items-center size-26 mx-auto mb-6 rounded-full border-0 cursor-pointer bg-tlf30-wash text-tlf30-acc transition-[background-color,scale] duration-150 hover:bg-tlf30-washhover active:scale-95 focus-visible:outline-3 focus-visible:outline-offset-4 focus-visible:outline-tlf30-ring motion-reduce:transition-colors motion-reduce:active:scale-100">
      <span aria-hidden="true" class="absolute inset-0 rounded-full border-2 border-tlf30-acc opacity-0 animate-tlf30-pulse motion-reduce:animate-none motion-reduce:opacity-40 motion-reduce:-inset-1.5"></span>
      <span aria-hidden="true" class="absolute inset-0 rounded-full border-2 border-tlf30-acc opacity-0 animate-tlf30-pulse [animation-delay:1.2s] motion-reduce:hidden"></span>
      <svg viewBox="0 0 24 24" aria-hidden="true" class="relative size-13"><path fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" d="M5 11a7 7 0 0 1 14 0M7.5 12.5a4.5 4.5 0 0 1 9 0v1.5M12 12v4M9.5 15v1.5M14.5 14.5V17M4.5 14v1"></path></svg>
    </button>
    <p role="status" aria-live="polite" class="mb-5 text-[12.5px] text-tlf30-mut">Waiting for authentication&hellip;</p>
    <a href="#" class="inline-grid place-items-center min-h-11 px-3 text-[13.5px] font-semibold text-tlf30-acc no-underline hover:underline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tlf30-acc">Use passcode instead</a>
  </div>
</section>
```
## CSS
```css
@import "tailwindcss";

@theme {
  --color-tlf30-stage: #0f1220;
  --color-tlf30-stage: oklch(0.17 0.025 275);
  --color-tlf30-card: #171a2b;
  --color-tlf30-card: oklch(0.22 0.025 275);
  --color-tlf30-edge: #2b3048;
  --color-tlf30-edge: oklch(0.29 0.028 275);
  --color-tlf30-ink: #e9ecf7;
  --color-tlf30-ink: oklch(0.94 0.01 275);
  --color-tlf30-mut: #a6adc6;
  --color-tlf30-mut: oklch(0.75 0.022 275);
  --color-tlf30-acc: #8ba4f5;
  --color-tlf30-acc: oklch(0.72 0.14 265);
  --color-tlf30-wash: #232a4a;
  --color-tlf30-wash: oklch(0.72 0.14 265 / 0.16);
  --color-tlf30-washhover: #2c3660;
  --color-tlf30-washhover: oklch(0.72 0.14 265 / 0.24);
  --color-tlf30-ring: #adbef8;
  --color-tlf30-ring: oklch(0.72 0.14 265 / 0.6);
  --font-tlf30-sans: 'Sora', system-ui, sans-serif;
  --animate-tlf30-pulse: tlf-30-pulse 2.4s ease-out infinite;
}

@keyframes tlf-30-pulse {
  0% {
    transform: scale(0.7);
    opacity: 0.7;
  }

  80%,
    100% {
    transform: scale(1.5);
    opacity: 0;
  }
}

.tlf-30 {
  width: 100%;
  min-height: 100svh;
  color-scheme: dark;
}
```

How this works

Two rings, one animation, one delay. Both ripples scale from 0.7 to 1.5 while fading out over 2.4s; the second starts 1.2s in, which is what produces the continuous concentric effect from two elements instead of six.

The target is a real button. <button type="button"> with an aria-label, a 104px circle, and an active:scale-95 press. A decorative <div> here would make the primary action of the screen unreachable by keyboard.

Biometrics are never the only path. The passcode link is not a courtesy — a user with a failed sensor, a bandaged thumb or a borrowed device must be able to get in. It gets a 44px target and full contrast.

Make it yours

  • Accent: --color-tlf30-acc drives the target wash, the glyph, the ripples and the fallback link.
  • Ripple timing: the duration in --animate-tlf30-pulse and the second ring's [animation-delay:1.2s] (keep it at half).
  • Swap the fingerprint glyph for a Face ID mark — it is an inline SVG at size-13.
  • Target size: size-26 on the button.

Gotchas — read before shipping

  • Always ship the non-biometric fallback, and give it a real target size. This is the one requirement of the pattern that is not aesthetic.
  • Under reduced motion, leave a static ring. Removing the ripples entirely makes the prompt look inert, which loses the "listening" signal the animation was carrying.
  • Animate scale and opacity only — a ripple that animates width repaints the button's box every frame.

Browser support

ChromeSafariFirefoxEdge
111+16.4+128+111+

@keyframes scale/opacity ripples and :focus-visible are universally supported; this is a UI shell, with no WebAuthn wired up.

Techniques used in this demo

Utilitiesfirst-class utility or variant

Arbitraryneeds bracket syntax

Search CodeFronts

Loading…