30 Tailwind CSS Login Forms
01 / 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 Split-Screen Brand Hero Login Form

The high-conversion SaaS classic: a 50/50 desktop split with an isolated minimal form on one side and a branded panel — headline, testimonial, gradient mesh — on the other. The port's win is the collapse: grid-cols-1 md:grid-cols-[1.05fr_1fr] replaces a media query with a mobile-first default, so the single-column case is what the markup says by default rather than an override at the bottom of a stylesheet.

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-01 w-full min-h-svh grid place-items-center bg-tlf01-stage font-tlf01-sans p-6">
  <div class="w-[min(980px,100%)] grid grid-cols-1 md:grid-cols-[1.05fr_1fr] md:min-h-[580px] bg-white rounded-3xl overflow-hidden shadow-[0_30px_70px_-40px_oklch(0.25_0.06_265/0.5)]">
    <aside aria-hidden="true" class="relative hidden md:flex overflow-hidden bg-tlf01-brand text-white">
      <div class="absolute inset-0 bg-[radial-gradient(60%_55%_at_20%_20%,oklch(0.6_0.2_264/0.55),transparent_60%),radial-gradient(55%_50%_at_85%_30%,oklch(0.62_0.18_200/0.5),transparent_60%),radial-gradient(70%_60%_at_60%_100%,oklch(0.6_0.2_330/0.45),transparent_60%)]"></div>
      <div class="relative flex flex-col justify-between gap-6 p-12">
        <div class="text-xl font-extrabold tracking-tight">&#9670; Northwind</div>
        <p class="text-[27px]/[1.28] font-semibold tracking-tight text-pretty">The workspace where product, design and engineering finally share one source of truth.</p>
        <figure class="flex flex-col gap-3.5">
          <blockquote class="text-[15px]/[1.5] text-tlf01-quote">&ldquo;We cut our release cycle in half the month we switched.&rdquo;</blockquote>
          <figcaption class="flex items-center gap-2.5 text-[13px] text-tlf01-cap">
            <span class="grid place-items-center size-8 rounded-full bg-tlf01-acc text-white text-xs font-bold">AR</span>
            Ana Reyes &middot; VP Eng, Lumen
          </figcaption>
        </figure>
      </div>
    </aside>
    <div class="grid place-items-center p-9 sm:p-12">
      <form novalidate class="w-full max-w-[340px] flex flex-col gap-4">
        <h1 class="text-[28px] font-bold tracking-tight text-tlf01-ink">Welcome back</h1>
        <p class="-mt-2.5 mb-1 text-sm text-tlf01-mut">Sign in to your Northwind workspace.</p>
        <label class="flex flex-col gap-1.5">
          <span class="text-[13px] font-semibold text-tlf01-label">Work email</span>
          <input type="email" name="email" autocomplete="email" placeholder="you@company.com" required class="h-12 px-3.5 rounded-xl bg-tlf01-fieldbg text-[15px] text-tlf01-ink border-[1.5px] border-tlf01-edge transition-[border-color,box-shadow] duration-150 placeholder:text-tlf01-ph focus-visible:outline-none focus-visible:border-tlf01-acc focus-visible:ring-4 focus-visible:ring-tlf01-ring">
        </label>
        <label class="flex flex-col gap-1.5">
          <span class="text-[13px] font-semibold text-tlf01-label">Password</span>
          <input type="password" name="password" autocomplete="current-password" placeholder="&bull;&bull;&bull;&bull;&bull;&bull;&bull;&bull;" required class="h-12 px-3.5 rounded-xl bg-tlf01-fieldbg text-[15px] text-tlf01-ink border-[1.5px] border-tlf01-edge transition-[border-color,box-shadow] duration-150 placeholder:text-tlf01-ph focus-visible:outline-none focus-visible:border-tlf01-acc focus-visible:ring-4 focus-visible:ring-tlf01-ring">
        </label>
        <button type="submit" class="mt-1 h-12 rounded-xl border-0 cursor-pointer bg-tlf01-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-3 focus-visible:outline-tlf01-ring motion-reduce:transition-none motion-reduce:active:scale-100">Sign in</button>
        <p class="text-center text-[13.5px] text-tlf01-mut">New here? <a href="#" class="font-semibold text-tlf01-acc no-underline hover:underline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tlf01-acc">Create an account</a></p>
      </form>
    </div>
  </div>
</section>
@import "tailwindcss";

@theme {
  --color-tlf01-stage: #eef0f5;
  --color-tlf01-stage: oklch(0.95 0.005 265);
  --color-tlf01-brand: #0e1330;
  --color-tlf01-brand: oklch(0.21 0.06 275);
  --color-tlf01-acc: #5a63d8;
  --color-tlf01-acc: oklch(0.58 0.19 264);
  --color-tlf01-ring: #c9cdf4;
  --color-tlf01-ring: oklch(0.58 0.19 264 / 0.22);
  --color-tlf01-ink: #141a2e;
  --color-tlf01-ink: oklch(0.22 0.04 270);
  --color-tlf01-label: #39405a;
  --color-tlf01-label: oklch(0.36 0.04 270);
  --color-tlf01-mut: #626a85;
  --color-tlf01-mut: oklch(0.5 0.03 270);
  --color-tlf01-ph: #a3aac2;
  --color-tlf01-ph: oklch(0.72 0.03 270);
  --color-tlf01-edge: #d6dae6;
  --color-tlf01-edge: oklch(0.87 0.01 270);
  --color-tlf01-fieldbg: #fbfbfe;
  --color-tlf01-fieldbg: oklch(0.99 0.004 270);
  --color-tlf01-quote: #d7ddf5;
  --color-tlf01-quote: oklch(0.89 0.03 270);
  --color-tlf01-cap: #b6bfe2;
  --color-tlf01-cap: oklch(0.79 0.04 270);
  --font-tlf01-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's
   w-full min-h-svh, so the stage is sized before the browser build has compiled. */

.tlf-01 {
  width: 100%;
  min-height: 100svh;
}

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-tlf01-stage: #eef0f5;
  --color-tlf01-stage: oklch(0.95 0.005 265);
  --color-tlf01-brand: #0e1330;
  --color-tlf01-brand: oklch(0.21 0.06 275);
  --color-tlf01-acc: #5a63d8;
  --color-tlf01-acc: oklch(0.58 0.19 264);
  --color-tlf01-ring: #c9cdf4;
  --color-tlf01-ring: oklch(0.58 0.19 264 / 0.22);
  --color-tlf01-ink: #141a2e;
  --color-tlf01-ink: oklch(0.22 0.04 270);
  --color-tlf01-label: #39405a;
  --color-tlf01-label: oklch(0.36 0.04 270);
  --color-tlf01-mut: #626a85;
  --color-tlf01-mut: oklch(0.5 0.03 270);
  --color-tlf01-ph: #a3aac2;
  --color-tlf01-ph: oklch(0.72 0.03 270);
  --color-tlf01-edge: #d6dae6;
  --color-tlf01-edge: oklch(0.87 0.01 270);
  --color-tlf01-fieldbg: #fbfbfe;
  --color-tlf01-fieldbg: oklch(0.99 0.004 270);
  --color-tlf01-quote: #d7ddf5;
  --color-tlf01-quote: oklch(0.89 0.03 270);
  --color-tlf01-cap: #b6bfe2;
  --color-tlf01-cap: oklch(0.79 0.04 270);
  --font-tlf01-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's
   w-full min-h-svh, so the stage is sized before the browser build has compiled. */

.tlf-01 {
  width: 100%;
  min-height: 100svh;
}
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=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap">

What changed in the port

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

  • The @media (max-width:768px) block disappears entirely. One column and hidden on the aside are the base state; md: adds the split. Mobile-first is not a style preference here — it deletes code.
  • focus-visible:ring-4 focus-visible:ring-tlf01-ring replaces a hand-written box-shadow:0 0 0 4px oklch(...), and the ring colour becomes a token every other demo element can reuse — the submit button's outline reads the same one.
  • text-[27px]/[1.28] carries size and line-height in one utility, which is the single biggest readability win of the port on a marketing panel like this.
  • UI change from the CSS original: type moved from 'Segoe UI' to Plus Jakarta Sans, the muted body colour went from #69708a to oklch(0.5 0.03 270) (4.6:1 on the stage, up from 4.1:1), and the testimonial caption from #aeb7dd to oklch(0.79 0.04 270) so it clears 4.5:1 on the deep brand navy.
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 Split-Screen Brand Hero Login Form
Source: https://codefronts.com/components/tailwind-css-login-forms/tailwind-split-screen-brand-hero-login-form/

The high-conversion SaaS classic: a 50/50 desktop split with an isolated minimal form on one side and a branded panel — headline, testimonial, gradient mesh — on the other. The port's win is the collapse: grid-cols-1 md:grid-cols-[1.05fr_1fr] replaces a media query with a mobile-first default, so the single-column case is what the markup says by default rather than an override at the bottom of a stylesheet.
## HTML
```html
<section class="tlf-01 w-full min-h-svh grid place-items-center bg-tlf01-stage font-tlf01-sans p-6">
  <div class="w-[min(980px,100%)] grid grid-cols-1 md:grid-cols-[1.05fr_1fr] md:min-h-[580px] bg-white rounded-3xl overflow-hidden shadow-[0_30px_70px_-40px_oklch(0.25_0.06_265/0.5)]">
    <aside aria-hidden="true" class="relative hidden md:flex overflow-hidden bg-tlf01-brand text-white">
      <div class="absolute inset-0 bg-[radial-gradient(60%_55%_at_20%_20%,oklch(0.6_0.2_264/0.55),transparent_60%),radial-gradient(55%_50%_at_85%_30%,oklch(0.62_0.18_200/0.5),transparent_60%),radial-gradient(70%_60%_at_60%_100%,oklch(0.6_0.2_330/0.45),transparent_60%)]"></div>
      <div class="relative flex flex-col justify-between gap-6 p-12">
        <div class="text-xl font-extrabold tracking-tight">&#9670; Northwind</div>
        <p class="text-[27px]/[1.28] font-semibold tracking-tight text-pretty">The workspace where product, design and engineering finally share one source of truth.</p>
        <figure class="flex flex-col gap-3.5">
          <blockquote class="text-[15px]/[1.5] text-tlf01-quote">&ldquo;We cut our release cycle in half the month we switched.&rdquo;</blockquote>
          <figcaption class="flex items-center gap-2.5 text-[13px] text-tlf01-cap">
            <span class="grid place-items-center size-8 rounded-full bg-tlf01-acc text-white text-xs font-bold">AR</span>
            Ana Reyes &middot; VP Eng, Lumen
          </figcaption>
        </figure>
      </div>
    </aside>
    <div class="grid place-items-center p-9 sm:p-12">
      <form novalidate class="w-full max-w-[340px] flex flex-col gap-4">
        <h1 class="text-[28px] font-bold tracking-tight text-tlf01-ink">Welcome back</h1>
        <p class="-mt-2.5 mb-1 text-sm text-tlf01-mut">Sign in to your Northwind workspace.</p>
        <label class="flex flex-col gap-1.5">
          <span class="text-[13px] font-semibold text-tlf01-label">Work email</span>
          <input type="email" name="email" autocomplete="email" placeholder="you@company.com" required class="h-12 px-3.5 rounded-xl bg-tlf01-fieldbg text-[15px] text-tlf01-ink border-[1.5px] border-tlf01-edge transition-[border-color,box-shadow] duration-150 placeholder:text-tlf01-ph focus-visible:outline-none focus-visible:border-tlf01-acc focus-visible:ring-4 focus-visible:ring-tlf01-ring">
        </label>
        <label class="flex flex-col gap-1.5">
          <span class="text-[13px] font-semibold text-tlf01-label">Password</span>
          <input type="password" name="password" autocomplete="current-password" placeholder="&bull;&bull;&bull;&bull;&bull;&bull;&bull;&bull;" required class="h-12 px-3.5 rounded-xl bg-tlf01-fieldbg text-[15px] text-tlf01-ink border-[1.5px] border-tlf01-edge transition-[border-color,box-shadow] duration-150 placeholder:text-tlf01-ph focus-visible:outline-none focus-visible:border-tlf01-acc focus-visible:ring-4 focus-visible:ring-tlf01-ring">
        </label>
        <button type="submit" class="mt-1 h-12 rounded-xl border-0 cursor-pointer bg-tlf01-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-3 focus-visible:outline-tlf01-ring motion-reduce:transition-none motion-reduce:active:scale-100">Sign in</button>
        <p class="text-center text-[13.5px] text-tlf01-mut">New here? <a href="#" class="font-semibold text-tlf01-acc no-underline hover:underline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-tlf01-acc">Create an account</a></p>
      </form>
    </div>
  </div>
</section>
```
## CSS
```css
@import "tailwindcss";

@theme {
  --color-tlf01-stage: #eef0f5;
  --color-tlf01-stage: oklch(0.95 0.005 265);
  --color-tlf01-brand: #0e1330;
  --color-tlf01-brand: oklch(0.21 0.06 275);
  --color-tlf01-acc: #5a63d8;
  --color-tlf01-acc: oklch(0.58 0.19 264);
  --color-tlf01-ring: #c9cdf4;
  --color-tlf01-ring: oklch(0.58 0.19 264 / 0.22);
  --color-tlf01-ink: #141a2e;
  --color-tlf01-ink: oklch(0.22 0.04 270);
  --color-tlf01-label: #39405a;
  --color-tlf01-label: oklch(0.36 0.04 270);
  --color-tlf01-mut: #626a85;
  --color-tlf01-mut: oklch(0.5 0.03 270);
  --color-tlf01-ph: #a3aac2;
  --color-tlf01-ph: oklch(0.72 0.03 270);
  --color-tlf01-edge: #d6dae6;
  --color-tlf01-edge: oklch(0.87 0.01 270);
  --color-tlf01-fieldbg: #fbfbfe;
  --color-tlf01-fieldbg: oklch(0.99 0.004 270);
  --color-tlf01-quote: #d7ddf5;
  --color-tlf01-quote: oklch(0.89 0.03 270);
  --color-tlf01-cap: #b6bfe2;
  --color-tlf01-cap: oklch(0.79 0.04 270);
  --font-tlf01-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's
   w-full min-h-svh, so the stage is sized before the browser build has compiled. */

.tlf-01 {
  width: 100%;
  min-height: 100svh;
}
```

How this works

The media query becomes a breakpoint prefix. The CSS version ends with @media (max-width:768px){ grid-template-columns:1fr; .brand{display:none} } — the mobile case as an afterthought. Tailwind inverts it: one column and a hidden aside are the base, md: adds the split. The narrow layout is now unmissable in the markup instead of buried 40 lines away.

Each cell still owns its padding. p-12 on the brand body and p-9 sm:p-12 on the form panel, never on the grid itself — so the collapse keeps clean edges, exactly as the original insisted.

The form is unchanged where it matters. Real <form>, wrapping <label>s, type=email / type=password with autocomplete: Tailwind moves style, not semantics, and password managers see the same DOM they did before.

Make it yours

  • Split ratio: edit the one arbitrary value, md:grid-cols-[1.05fr_1fr].
  • Put the brand on the right with md:order-2 on the aside — no direction hacks.
  • Retheme from --color-tlf01-acc: button, links, avatar and focus halo all read it.
  • Drop a real logo or testimonial avatar in — the flex column already reserves the space.

Gotchas — read before shipping

  • Pad the cells, not the grid container, or the mobile collapse inherits a double gutter.
  • Keep the panel a real <form>; a <div> of inputs silently disables autofill and the Enter key.
  • hidden md:flex and not md:block — the aside is a flex parent, and hidden resets display, so the responsive utility has to restate the layout mode it wants.

Browser support

ChromeSafariFirefoxEdge
111+16.4+128+111+

Grid, radial gradients and :focus-visible are Baseline since 2022; the floor quoted here is Tailwind v4's own generated sheet (cascade layers, @property, color-mix()).

Techniques used in this demo

Search CodeFronts

Loading…