10 / 30
All 30 in 30 Tailwind CSS Login Forms
- 01Tailwind Split-Screen Brand Hero Login Form
- 02Tailwind Multi-Tenant Workspace Account Switcher
- 03Tailwind Floating Label Login Form with peer Variants
- 04Tailwind Web3 Wallet Connect Login Grid
- 05Tailwind Minimalist Fintech Login Card with Layered Shadow
- 06Tailwind OAuth Social Login Form with Brand SVG Buttons
- 07Tailwind Passwordless Magic Link Login with data-state Machine
- 08Tailwind Aurora Glow Login Card with Drifting Blur Blobs
- 09Tailwind Neon Synthwave Arcade Login Form
- 10Tailwind Sliding Login and Sign Up Panel with peer-checked
- 11Tailwind 3D Flip Login Card with Password Reset Back Face
- 12Tailwind Terminal CLI Prompt Login Form
- 13Tailwind Floating Pill Login Widget Docked Over App Content
- 14Tailwind Gradient Border Login Card with background-clip
- 15Tailwind Slide-Over Side Panel Login without JavaScript
- 16Tailwind Social-First Sign Up with Brand-Compliant Buttons
- 17Tailwind Animated Mascot Login that Covers Its Eyes
- 18Tailwind Accessible Compact Login Modal with Scale-In
- 19Tailwind Glassmorphism Login Card with backdrop-filter
- 20Tailwind Multi-Step Login Wizard with Radio-Driven Track
- 21Tailwind Animated Conic Gradient Border Login Card
- 22Tailwind Secure Vault Login with user-invalid Error State
- 23Tailwind Neo-Brutalist Login Form with Hard Offset Shadow
- 24Tailwind Show Hide Password Toggle with aria-pressed
- 25Tailwind OTP Code Input Grid with Auto-Advance
- 26Tailwind Password Strength Meter with data-score Variants
- 27Tailwind Numeric PIN Pad Login for Kiosks and POS
- 28Tailwind Inline Form Validation with user-valid and user-invalid
- 29Tailwind Particle Constellation Login over Canvas
- 30Tailwind Biometric Face ID Prompt with Pulse Ripples
Tailwind Sliding Login and Sign Up Panel with peer-checked
One window, two workflows: Login and Sign Up sit side by side and a gradient overlay glides across to reveal whichever you need. The classic dual-panel auth, driven by a single focusable checkbox — and the port's win is that the whole state machine is now four peer-checked: class lists instead of six descendant selectors.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="tlf-10 w-full min-h-svh grid place-items-center bg-tlf10-stage font-tlf10-sans p-6">
<div class="relative w-[min(760px,100%)] min-h-[560px] md:min-h-[460px] bg-white rounded-[20px] overflow-hidden shadow-[0_30px_70px_-42px_oklch(0.25_0.06_265/0.55)]">
<input type="checkbox" id="tlf-10-mode" aria-label="Switch between login and sign up" class="peer sr-only">
<form novalidate class="absolute top-0 left-0 w-full md:w-1/2 h-full flex flex-col justify-center gap-3 p-8 pb-[150px] md:p-10 md:pb-10 z-2 transition-opacity duration-400 peer-checked:opacity-0 peer-checked:z-1 motion-reduce:transition-none">
<h2 class="mb-1 text-[23px] font-bold text-tlf10-ink">Sign in</h2>
<input type="email" placeholder="Email" autocomplete="email" required class="h-12 px-3.5 rounded-xl text-[14.5px] text-tlf10-ink bg-tlf10-field border-[1.5px] border-tlf10-edge transition-[border-color,box-shadow] duration-150 placeholder:text-tlf10-ph focus-visible:outline-none focus-visible:border-tlf10-acc focus-visible:ring-4 focus-visible:ring-tlf10-halo">
<input type="password" placeholder="Password" autocomplete="current-password" required class="h-12 px-3.5 rounded-xl text-[14.5px] text-tlf10-ink bg-tlf10-field border-[1.5px] border-tlf10-edge transition-[border-color,box-shadow] duration-150 placeholder:text-tlf10-ph focus-visible:outline-none focus-visible:border-tlf10-acc focus-visible:ring-4 focus-visible:ring-tlf10-halo">
<button type="submit" class="mt-1 h-12 rounded-xl border-0 cursor-pointer bg-tlf10-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-tlf10-ring motion-reduce:transition-none motion-reduce:active:scale-100">Log in</button>
</form>
<form novalidate class="absolute top-0 right-0 w-full md:w-1/2 h-full flex flex-col justify-center gap-3 p-8 pb-[150px] md:p-10 md:pb-10 opacity-0 z-1 transition-opacity duration-400 peer-checked:opacity-100 peer-checked:z-2 motion-reduce:transition-none">
<h2 class="mb-1 text-[23px] font-bold text-tlf10-ink">Create account</h2>
<input type="text" placeholder="Full name" autocomplete="name" required class="h-12 px-3.5 rounded-xl text-[14.5px] text-tlf10-ink bg-tlf10-field border-[1.5px] border-tlf10-edge transition-[border-color,box-shadow] duration-150 placeholder:text-tlf10-ph focus-visible:outline-none focus-visible:border-tlf10-acc focus-visible:ring-4 focus-visible:ring-tlf10-halo">
<input type="email" placeholder="Email" autocomplete="email" required class="h-12 px-3.5 rounded-xl text-[14.5px] text-tlf10-ink bg-tlf10-field border-[1.5px] border-tlf10-edge transition-[border-color,box-shadow] duration-150 placeholder:text-tlf10-ph focus-visible:outline-none focus-visible:border-tlf10-acc focus-visible:ring-4 focus-visible:ring-tlf10-halo">
<input type="password" placeholder="Password" autocomplete="new-password" required class="h-12 px-3.5 rounded-xl text-[14.5px] text-tlf10-ink bg-tlf10-field border-[1.5px] border-tlf10-edge transition-[border-color,box-shadow] duration-150 placeholder:text-tlf10-ph focus-visible:outline-none focus-visible:border-tlf10-acc focus-visible:ring-4 focus-visible:ring-tlf10-halo">
<button type="submit" class="mt-1 h-12 rounded-xl border-0 cursor-pointer bg-tlf10-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-tlf10-ring motion-reduce:transition-none motion-reduce:active:scale-100">Sign up</button>
</form>
<div class="absolute bottom-0 left-0 w-full h-[150px] md:top-0 md:bottom-auto md:left-auto md:right-0 md:w-1/2 md:h-full z-3 overflow-hidden text-white rounded-t-3xl md:rounded-[120px_20px_20px_120px] bg-[linear-gradient(135deg,oklch(0.55_0.19_264),oklch(0.5_0.2_300))] transition-[translate,border-radius] duration-500 ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:md:-translate-x-full peer-checked:md:rounded-[20px_120px_120px_20px] peer-focus-visible:outline-3 peer-focus-visible:-outline-offset-4 peer-focus-visible:outline-white peer-checked:[&>div:first-child]:-translate-y-full peer-checked:md:[&>div:first-child]:-translate-x-full peer-checked:md:[&>div:first-child]:translate-y-0 peer-checked:[&>div:last-child]:translate-y-0 peer-checked:md:[&>div:last-child]:translate-x-0 motion-reduce:transition-none">
<div class="absolute inset-0 flex flex-col items-center justify-center gap-3 p-6 md:p-10 text-center transition-[translate] duration-500 ease-[cubic-bezier(0.4,0,0.2,1)] motion-reduce:transition-none">
<h3 class="text-xl md:text-2xl font-bold">New here?</h3>
<p class="hidden md:block max-w-[240px] text-sm/[1.5] text-tlf10-panelink">Create an account and start your free trial.</p>
<label for="tlf-10-mode" class="grid place-items-center min-h-11 mt-1.5 px-7 rounded-full border-[1.5px] border-white cursor-pointer text-sm font-semibold transition-colors duration-150 hover:bg-white hover:text-tlf10-acc">Sign up</label>
</div>
<div class="absolute inset-0 flex flex-col items-center justify-center gap-3 p-6 md:p-10 text-center translate-y-full md:translate-y-0 md:translate-x-full transition-[translate] duration-500 ease-[cubic-bezier(0.4,0,0.2,1)] motion-reduce:transition-none">
<h3 class="text-xl md:text-2xl font-bold">One of us?</h3>
<p class="hidden md:block max-w-[240px] text-sm/[1.5] text-tlf10-panelink">Sign in to pick up right where you left off.</p>
<label for="tlf-10-mode" class="grid place-items-center min-h-11 mt-1.5 px-7 rounded-full border-[1.5px] border-white cursor-pointer text-sm font-semibold transition-colors duration-150 hover:bg-white hover:text-tlf10-acc">Log in</label>
</div>
</div>
</div>
</section><section class="tlf-10 w-full min-h-svh grid place-items-center bg-tlf10-stage font-tlf10-sans p-6">
<div class="relative w-[min(760px,100%)] min-h-[560px] md:min-h-[460px] bg-white rounded-[20px] overflow-hidden shadow-[0_30px_70px_-42px_oklch(0.25_0.06_265/0.55)]">
<input type="checkbox" id="tlf-10-mode" aria-label="Switch between login and sign up" class="peer sr-only">
<form novalidate class="absolute top-0 left-0 w-full md:w-1/2 h-full flex flex-col justify-center gap-3 p-8 pb-[150px] md:p-10 md:pb-10 z-2 transition-opacity duration-400 peer-checked:opacity-0 peer-checked:z-1 motion-reduce:transition-none">
<h2 class="mb-1 text-[23px] font-bold text-tlf10-ink">Sign in</h2>
<input type="email" placeholder="Email" autocomplete="email" required class="h-12 px-3.5 rounded-xl text-[14.5px] text-tlf10-ink bg-tlf10-field border-[1.5px] border-tlf10-edge transition-[border-color,box-shadow] duration-150 placeholder:text-tlf10-ph focus-visible:outline-none focus-visible:border-tlf10-acc focus-visible:ring-4 focus-visible:ring-tlf10-halo">
<input type="password" placeholder="Password" autocomplete="current-password" required class="h-12 px-3.5 rounded-xl text-[14.5px] text-tlf10-ink bg-tlf10-field border-[1.5px] border-tlf10-edge transition-[border-color,box-shadow] duration-150 placeholder:text-tlf10-ph focus-visible:outline-none focus-visible:border-tlf10-acc focus-visible:ring-4 focus-visible:ring-tlf10-halo">
<button type="submit" class="mt-1 h-12 rounded-xl border-0 cursor-pointer bg-tlf10-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-tlf10-ring motion-reduce:transition-none motion-reduce:active:scale-100">Log in</button>
</form>
<form novalidate class="absolute top-0 right-0 w-full md:w-1/2 h-full flex flex-col justify-center gap-3 p-8 pb-[150px] md:p-10 md:pb-10 opacity-0 z-1 transition-opacity duration-400 peer-checked:opacity-100 peer-checked:z-2 motion-reduce:transition-none">
<h2 class="mb-1 text-[23px] font-bold text-tlf10-ink">Create account</h2>
<input type="text" placeholder="Full name" autocomplete="name" required class="h-12 px-3.5 rounded-xl text-[14.5px] text-tlf10-ink bg-tlf10-field border-[1.5px] border-tlf10-edge transition-[border-color,box-shadow] duration-150 placeholder:text-tlf10-ph focus-visible:outline-none focus-visible:border-tlf10-acc focus-visible:ring-4 focus-visible:ring-tlf10-halo">
<input type="email" placeholder="Email" autocomplete="email" required class="h-12 px-3.5 rounded-xl text-[14.5px] text-tlf10-ink bg-tlf10-field border-[1.5px] border-tlf10-edge transition-[border-color,box-shadow] duration-150 placeholder:text-tlf10-ph focus-visible:outline-none focus-visible:border-tlf10-acc focus-visible:ring-4 focus-visible:ring-tlf10-halo">
<input type="password" placeholder="Password" autocomplete="new-password" required class="h-12 px-3.5 rounded-xl text-[14.5px] text-tlf10-ink bg-tlf10-field border-[1.5px] border-tlf10-edge transition-[border-color,box-shadow] duration-150 placeholder:text-tlf10-ph focus-visible:outline-none focus-visible:border-tlf10-acc focus-visible:ring-4 focus-visible:ring-tlf10-halo">
<button type="submit" class="mt-1 h-12 rounded-xl border-0 cursor-pointer bg-tlf10-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-tlf10-ring motion-reduce:transition-none motion-reduce:active:scale-100">Sign up</button>
</form>
<div class="absolute bottom-0 left-0 w-full h-[150px] md:top-0 md:bottom-auto md:left-auto md:right-0 md:w-1/2 md:h-full z-3 overflow-hidden text-white rounded-t-3xl md:rounded-[120px_20px_20px_120px] bg-[linear-gradient(135deg,oklch(0.55_0.19_264),oklch(0.5_0.2_300))] transition-[translate,border-radius] duration-500 ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:md:-translate-x-full peer-checked:md:rounded-[20px_120px_120px_20px] peer-focus-visible:outline-3 peer-focus-visible:-outline-offset-4 peer-focus-visible:outline-white peer-checked:[&>div:first-child]:-translate-y-full peer-checked:md:[&>div:first-child]:-translate-x-full peer-checked:md:[&>div:first-child]:translate-y-0 peer-checked:[&>div:last-child]:translate-y-0 peer-checked:md:[&>div:last-child]:translate-x-0 motion-reduce:transition-none">
<div class="absolute inset-0 flex flex-col items-center justify-center gap-3 p-6 md:p-10 text-center transition-[translate] duration-500 ease-[cubic-bezier(0.4,0,0.2,1)] motion-reduce:transition-none">
<h3 class="text-xl md:text-2xl font-bold">New here?</h3>
<p class="hidden md:block max-w-[240px] text-sm/[1.5] text-tlf10-panelink">Create an account and start your free trial.</p>
<label for="tlf-10-mode" class="grid place-items-center min-h-11 mt-1.5 px-7 rounded-full border-[1.5px] border-white cursor-pointer text-sm font-semibold transition-colors duration-150 hover:bg-white hover:text-tlf10-acc">Sign up</label>
</div>
<div class="absolute inset-0 flex flex-col items-center justify-center gap-3 p-6 md:p-10 text-center translate-y-full md:translate-y-0 md:translate-x-full transition-[translate] duration-500 ease-[cubic-bezier(0.4,0,0.2,1)] motion-reduce:transition-none">
<h3 class="text-xl md:text-2xl font-bold">One of us?</h3>
<p class="hidden md:block max-w-[240px] text-sm/[1.5] text-tlf10-panelink">Sign in to pick up right where you left off.</p>
<label for="tlf-10-mode" class="grid place-items-center min-h-11 mt-1.5 px-7 rounded-full border-[1.5px] border-white cursor-pointer text-sm font-semibold transition-colors duration-150 hover:bg-white hover:text-tlf10-acc">Log in</label>
</div>
</div>
</div>
</section>@import "tailwindcss";
@theme {
--color-tlf10-stage: #eef0f6;
--color-tlf10-stage: oklch(0.95 0.008 270);
--color-tlf10-ink: #161c2e;
--color-tlf10-ink: oklch(0.23 0.04 270);
--color-tlf10-ph: #8e96ad;
--color-tlf10-ph: oklch(0.65 0.025 270);
--color-tlf10-edge: #d7dbe6;
--color-tlf10-edge: oklch(0.87 0.01 270);
--color-tlf10-field: #fafbfe;
--color-tlf10-field: oklch(0.99 0.003 270);
--color-tlf10-acc: #5560d4;
--color-tlf10-acc: oklch(0.55 0.19 264);
--color-tlf10-halo: #c5caf2;
--color-tlf10-halo: oklch(0.55 0.19 264 / 0.16);
--color-tlf10-ring: #9ba3e8;
--color-tlf10-ring: oklch(0.55 0.19 264 / 0.5);
--color-tlf10-panelink: #eae6ff;
--color-tlf10-panelink: oklch(0.93 0.03 290);
--font-tlf10-sans: 'Outfit', system-ui, sans-serif;
}
.tlf-10 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tlf10-stage: #eef0f6;
--color-tlf10-stage: oklch(0.95 0.008 270);
--color-tlf10-ink: #161c2e;
--color-tlf10-ink: oklch(0.23 0.04 270);
--color-tlf10-ph: #8e96ad;
--color-tlf10-ph: oklch(0.65 0.025 270);
--color-tlf10-edge: #d7dbe6;
--color-tlf10-edge: oklch(0.87 0.01 270);
--color-tlf10-field: #fafbfe;
--color-tlf10-field: oklch(0.99 0.003 270);
--color-tlf10-acc: #5560d4;
--color-tlf10-acc: oklch(0.55 0.19 264);
--color-tlf10-halo: #c5caf2;
--color-tlf10-halo: oklch(0.55 0.19 264 / 0.16);
--color-tlf10-ring: #9ba3e8;
--color-tlf10-ring: oklch(0.55 0.19 264 / 0.5);
--color-tlf10-panelink: #eae6ff;
--color-tlf10-panelink: oklch(0.93 0.03 290);
--font-tlf10-sans: 'Outfit', system-ui, sans-serif;
}
.tlf-10 {
width: 100%;
min-height: 100svh;
}Setup — do this once per project
Skip this if your project already runs Tailwind v4.
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<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.
npm install tailwindcss @tailwindcss/vite
npm install tailwindcss @tailwindcss/vite// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})Any v4 setup works — Vite, PostCSS or the CLI. Nothing in this demo is bundler-specific.
@import "tailwindcss";
@theme {
--color-tlf10-stage: #eef0f6;
--color-tlf10-stage: oklch(0.95 0.008 270);
--color-tlf10-ink: #161c2e;
--color-tlf10-ink: oklch(0.23 0.04 270);
--color-tlf10-ph: #8e96ad;
--color-tlf10-ph: oklch(0.65 0.025 270);
--color-tlf10-edge: #d7dbe6;
--color-tlf10-edge: oklch(0.87 0.01 270);
--color-tlf10-field: #fafbfe;
--color-tlf10-field: oklch(0.99 0.003 270);
--color-tlf10-acc: #5560d4;
--color-tlf10-acc: oklch(0.55 0.19 264);
--color-tlf10-halo: #c5caf2;
--color-tlf10-halo: oklch(0.55 0.19 264 / 0.16);
--color-tlf10-ring: #9ba3e8;
--color-tlf10-ring: oklch(0.55 0.19 264 / 0.5);
--color-tlf10-panelink: #eae6ff;
--color-tlf10-panelink: oklch(0.93 0.03 290);
--font-tlf10-sans: 'Outfit', system-ui, sans-serif;
}
.tlf-10 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-tlf10-stage: #eef0f6;
--color-tlf10-stage: oklch(0.95 0.008 270);
--color-tlf10-ink: #161c2e;
--color-tlf10-ink: oklch(0.23 0.04 270);
--color-tlf10-ph: #8e96ad;
--color-tlf10-ph: oklch(0.65 0.025 270);
--color-tlf10-edge: #d7dbe6;
--color-tlf10-edge: oklch(0.87 0.01 270);
--color-tlf10-field: #fafbfe;
--color-tlf10-field: oklch(0.99 0.003 270);
--color-tlf10-acc: #5560d4;
--color-tlf10-acc: oklch(0.55 0.19 264);
--color-tlf10-halo: #c5caf2;
--color-tlf10-halo: oklch(0.55 0.19 264 / 0.16);
--color-tlf10-ring: #9ba3e8;
--color-tlf10-ring: oklch(0.55 0.19 264 / 0.5);
--color-tlf10-panelink: #eae6ff;
--color-tlf10-panelink: oklch(0.93 0.03 290);
--font-tlf10-sans: 'Outfit', system-ui, sans-serif;
}
.tlf-10 {
width: 100%;
min-height: 100svh;
}<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=Outfit:wght@400;500;600;700&display=swap">
<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=Outfit:wght@400;500;600;700&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- The
@media (max-width:768px)block that re-pointed the slide from horizontal to vertical becomesmd:prefixes on the same utilities — and, as in demo 01, the mobile arrangement is now the base state. Nine lines of override CSS disappear. peer-checked:[&>div:first-child]:-translate-y-fullis the port's ugliest line and worth keeping honest about: two overlay panels whose animation is driven by a distant sibling's state is the exact case where a child DC or a small component wrapper beats a class list.peer-focus-visible:outline-3 peer-focus-visible:-outline-offset-4keeps the original's inset ring, which matters more than usual here: the focused element is invisible, so the ring must appear on the thing that moves.- UI change from the CSS original: Outfit replaces the system stack, fields went 46px → 48px and the ghost labels gained
min-h-11, the placeholder grey lifted tooklch(0.65), and the mobile overlay is now 150px tall (was 130px) so the 44px target fits with real padding.
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 Sliding Login and Sign Up Panel with peer-checked
Source: https://codefronts.com/components/tailwind-css-login-forms/tailwind-sliding-login-signup-panel-peer-checked/
One window, two workflows: Login and Sign Up sit side by side and a gradient overlay glides across to reveal whichever you need. The classic dual-panel auth, driven by a single focusable checkbox — and the port's win is that the whole state machine is now four peer-checked: class lists instead of six descendant selectors.
## HTML
```html
<section class="tlf-10 w-full min-h-svh grid place-items-center bg-tlf10-stage font-tlf10-sans p-6">
<div class="relative w-[min(760px,100%)] min-h-[560px] md:min-h-[460px] bg-white rounded-[20px] overflow-hidden shadow-[0_30px_70px_-42px_oklch(0.25_0.06_265/0.55)]">
<input type="checkbox" id="tlf-10-mode" aria-label="Switch between login and sign up" class="peer sr-only">
<form novalidate class="absolute top-0 left-0 w-full md:w-1/2 h-full flex flex-col justify-center gap-3 p-8 pb-[150px] md:p-10 md:pb-10 z-2 transition-opacity duration-400 peer-checked:opacity-0 peer-checked:z-1 motion-reduce:transition-none">
<h2 class="mb-1 text-[23px] font-bold text-tlf10-ink">Sign in</h2>
<input type="email" placeholder="Email" autocomplete="email" required class="h-12 px-3.5 rounded-xl text-[14.5px] text-tlf10-ink bg-tlf10-field border-[1.5px] border-tlf10-edge transition-[border-color,box-shadow] duration-150 placeholder:text-tlf10-ph focus-visible:outline-none focus-visible:border-tlf10-acc focus-visible:ring-4 focus-visible:ring-tlf10-halo">
<input type="password" placeholder="Password" autocomplete="current-password" required class="h-12 px-3.5 rounded-xl text-[14.5px] text-tlf10-ink bg-tlf10-field border-[1.5px] border-tlf10-edge transition-[border-color,box-shadow] duration-150 placeholder:text-tlf10-ph focus-visible:outline-none focus-visible:border-tlf10-acc focus-visible:ring-4 focus-visible:ring-tlf10-halo">
<button type="submit" class="mt-1 h-12 rounded-xl border-0 cursor-pointer bg-tlf10-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-tlf10-ring motion-reduce:transition-none motion-reduce:active:scale-100">Log in</button>
</form>
<form novalidate class="absolute top-0 right-0 w-full md:w-1/2 h-full flex flex-col justify-center gap-3 p-8 pb-[150px] md:p-10 md:pb-10 opacity-0 z-1 transition-opacity duration-400 peer-checked:opacity-100 peer-checked:z-2 motion-reduce:transition-none">
<h2 class="mb-1 text-[23px] font-bold text-tlf10-ink">Create account</h2>
<input type="text" placeholder="Full name" autocomplete="name" required class="h-12 px-3.5 rounded-xl text-[14.5px] text-tlf10-ink bg-tlf10-field border-[1.5px] border-tlf10-edge transition-[border-color,box-shadow] duration-150 placeholder:text-tlf10-ph focus-visible:outline-none focus-visible:border-tlf10-acc focus-visible:ring-4 focus-visible:ring-tlf10-halo">
<input type="email" placeholder="Email" autocomplete="email" required class="h-12 px-3.5 rounded-xl text-[14.5px] text-tlf10-ink bg-tlf10-field border-[1.5px] border-tlf10-edge transition-[border-color,box-shadow] duration-150 placeholder:text-tlf10-ph focus-visible:outline-none focus-visible:border-tlf10-acc focus-visible:ring-4 focus-visible:ring-tlf10-halo">
<input type="password" placeholder="Password" autocomplete="new-password" required class="h-12 px-3.5 rounded-xl text-[14.5px] text-tlf10-ink bg-tlf10-field border-[1.5px] border-tlf10-edge transition-[border-color,box-shadow] duration-150 placeholder:text-tlf10-ph focus-visible:outline-none focus-visible:border-tlf10-acc focus-visible:ring-4 focus-visible:ring-tlf10-halo">
<button type="submit" class="mt-1 h-12 rounded-xl border-0 cursor-pointer bg-tlf10-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-tlf10-ring motion-reduce:transition-none motion-reduce:active:scale-100">Sign up</button>
</form>
<div class="absolute bottom-0 left-0 w-full h-[150px] md:top-0 md:bottom-auto md:left-auto md:right-0 md:w-1/2 md:h-full z-3 overflow-hidden text-white rounded-t-3xl md:rounded-[120px_20px_20px_120px] bg-[linear-gradient(135deg,oklch(0.55_0.19_264),oklch(0.5_0.2_300))] transition-[translate,border-radius] duration-500 ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:md:-translate-x-full peer-checked:md:rounded-[20px_120px_120px_20px] peer-focus-visible:outline-3 peer-focus-visible:-outline-offset-4 peer-focus-visible:outline-white peer-checked:[&>div:first-child]:-translate-y-full peer-checked:md:[&>div:first-child]:-translate-x-full peer-checked:md:[&>div:first-child]:translate-y-0 peer-checked:[&>div:last-child]:translate-y-0 peer-checked:md:[&>div:last-child]:translate-x-0 motion-reduce:transition-none">
<div class="absolute inset-0 flex flex-col items-center justify-center gap-3 p-6 md:p-10 text-center transition-[translate] duration-500 ease-[cubic-bezier(0.4,0,0.2,1)] motion-reduce:transition-none">
<h3 class="text-xl md:text-2xl font-bold">New here?</h3>
<p class="hidden md:block max-w-[240px] text-sm/[1.5] text-tlf10-panelink">Create an account and start your free trial.</p>
<label for="tlf-10-mode" class="grid place-items-center min-h-11 mt-1.5 px-7 rounded-full border-[1.5px] border-white cursor-pointer text-sm font-semibold transition-colors duration-150 hover:bg-white hover:text-tlf10-acc">Sign up</label>
</div>
<div class="absolute inset-0 flex flex-col items-center justify-center gap-3 p-6 md:p-10 text-center translate-y-full md:translate-y-0 md:translate-x-full transition-[translate] duration-500 ease-[cubic-bezier(0.4,0,0.2,1)] motion-reduce:transition-none">
<h3 class="text-xl md:text-2xl font-bold">One of us?</h3>
<p class="hidden md:block max-w-[240px] text-sm/[1.5] text-tlf10-panelink">Sign in to pick up right where you left off.</p>
<label for="tlf-10-mode" class="grid place-items-center min-h-11 mt-1.5 px-7 rounded-full border-[1.5px] border-white cursor-pointer text-sm font-semibold transition-colors duration-150 hover:bg-white hover:text-tlf10-acc">Log in</label>
</div>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tlf10-stage: #eef0f6;
--color-tlf10-stage: oklch(0.95 0.008 270);
--color-tlf10-ink: #161c2e;
--color-tlf10-ink: oklch(0.23 0.04 270);
--color-tlf10-ph: #8e96ad;
--color-tlf10-ph: oklch(0.65 0.025 270);
--color-tlf10-edge: #d7dbe6;
--color-tlf10-edge: oklch(0.87 0.01 270);
--color-tlf10-field: #fafbfe;
--color-tlf10-field: oklch(0.99 0.003 270);
--color-tlf10-acc: #5560d4;
--color-tlf10-acc: oklch(0.55 0.19 264);
--color-tlf10-halo: #c5caf2;
--color-tlf10-halo: oklch(0.55 0.19 264 / 0.16);
--color-tlf10-ring: #9ba3e8;
--color-tlf10-ring: oklch(0.55 0.19 264 / 0.5);
--color-tlf10-panelink: #eae6ff;
--color-tlf10-panelink: oklch(0.93 0.03 290);
--font-tlf10-sans: 'Outfit', system-ui, sans-serif;
}
.tlf-10 {
width: 100%;
min-height: 100svh;
}
```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 Sliding Login and Sign Up Panel with peer-checked
Source: https://codefronts.com/components/tailwind-css-login-forms/tailwind-sliding-login-signup-panel-peer-checked/
One window, two workflows: Login and Sign Up sit side by side and a gradient overlay glides across to reveal whichever you need. The classic dual-panel auth, driven by a single focusable checkbox — and the port's win is that the whole state machine is now four peer-checked: class lists instead of six descendant selectors.
## HTML
```html
<section class="tlf-10 w-full min-h-svh grid place-items-center bg-tlf10-stage font-tlf10-sans p-6">
<div class="relative w-[min(760px,100%)] min-h-[560px] md:min-h-[460px] bg-white rounded-[20px] overflow-hidden shadow-[0_30px_70px_-42px_oklch(0.25_0.06_265/0.55)]">
<input type="checkbox" id="tlf-10-mode" aria-label="Switch between login and sign up" class="peer sr-only">
<form novalidate class="absolute top-0 left-0 w-full md:w-1/2 h-full flex flex-col justify-center gap-3 p-8 pb-[150px] md:p-10 md:pb-10 z-2 transition-opacity duration-400 peer-checked:opacity-0 peer-checked:z-1 motion-reduce:transition-none">
<h2 class="mb-1 text-[23px] font-bold text-tlf10-ink">Sign in</h2>
<input type="email" placeholder="Email" autocomplete="email" required class="h-12 px-3.5 rounded-xl text-[14.5px] text-tlf10-ink bg-tlf10-field border-[1.5px] border-tlf10-edge transition-[border-color,box-shadow] duration-150 placeholder:text-tlf10-ph focus-visible:outline-none focus-visible:border-tlf10-acc focus-visible:ring-4 focus-visible:ring-tlf10-halo">
<input type="password" placeholder="Password" autocomplete="current-password" required class="h-12 px-3.5 rounded-xl text-[14.5px] text-tlf10-ink bg-tlf10-field border-[1.5px] border-tlf10-edge transition-[border-color,box-shadow] duration-150 placeholder:text-tlf10-ph focus-visible:outline-none focus-visible:border-tlf10-acc focus-visible:ring-4 focus-visible:ring-tlf10-halo">
<button type="submit" class="mt-1 h-12 rounded-xl border-0 cursor-pointer bg-tlf10-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-tlf10-ring motion-reduce:transition-none motion-reduce:active:scale-100">Log in</button>
</form>
<form novalidate class="absolute top-0 right-0 w-full md:w-1/2 h-full flex flex-col justify-center gap-3 p-8 pb-[150px] md:p-10 md:pb-10 opacity-0 z-1 transition-opacity duration-400 peer-checked:opacity-100 peer-checked:z-2 motion-reduce:transition-none">
<h2 class="mb-1 text-[23px] font-bold text-tlf10-ink">Create account</h2>
<input type="text" placeholder="Full name" autocomplete="name" required class="h-12 px-3.5 rounded-xl text-[14.5px] text-tlf10-ink bg-tlf10-field border-[1.5px] border-tlf10-edge transition-[border-color,box-shadow] duration-150 placeholder:text-tlf10-ph focus-visible:outline-none focus-visible:border-tlf10-acc focus-visible:ring-4 focus-visible:ring-tlf10-halo">
<input type="email" placeholder="Email" autocomplete="email" required class="h-12 px-3.5 rounded-xl text-[14.5px] text-tlf10-ink bg-tlf10-field border-[1.5px] border-tlf10-edge transition-[border-color,box-shadow] duration-150 placeholder:text-tlf10-ph focus-visible:outline-none focus-visible:border-tlf10-acc focus-visible:ring-4 focus-visible:ring-tlf10-halo">
<input type="password" placeholder="Password" autocomplete="new-password" required class="h-12 px-3.5 rounded-xl text-[14.5px] text-tlf10-ink bg-tlf10-field border-[1.5px] border-tlf10-edge transition-[border-color,box-shadow] duration-150 placeholder:text-tlf10-ph focus-visible:outline-none focus-visible:border-tlf10-acc focus-visible:ring-4 focus-visible:ring-tlf10-halo">
<button type="submit" class="mt-1 h-12 rounded-xl border-0 cursor-pointer bg-tlf10-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-tlf10-ring motion-reduce:transition-none motion-reduce:active:scale-100">Sign up</button>
</form>
<div class="absolute bottom-0 left-0 w-full h-[150px] md:top-0 md:bottom-auto md:left-auto md:right-0 md:w-1/2 md:h-full z-3 overflow-hidden text-white rounded-t-3xl md:rounded-[120px_20px_20px_120px] bg-[linear-gradient(135deg,oklch(0.55_0.19_264),oklch(0.5_0.2_300))] transition-[translate,border-radius] duration-500 ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:md:-translate-x-full peer-checked:md:rounded-[20px_120px_120px_20px] peer-focus-visible:outline-3 peer-focus-visible:-outline-offset-4 peer-focus-visible:outline-white peer-checked:[&>div:first-child]:-translate-y-full peer-checked:md:[&>div:first-child]:-translate-x-full peer-checked:md:[&>div:first-child]:translate-y-0 peer-checked:[&>div:last-child]:translate-y-0 peer-checked:md:[&>div:last-child]:translate-x-0 motion-reduce:transition-none">
<div class="absolute inset-0 flex flex-col items-center justify-center gap-3 p-6 md:p-10 text-center transition-[translate] duration-500 ease-[cubic-bezier(0.4,0,0.2,1)] motion-reduce:transition-none">
<h3 class="text-xl md:text-2xl font-bold">New here?</h3>
<p class="hidden md:block max-w-[240px] text-sm/[1.5] text-tlf10-panelink">Create an account and start your free trial.</p>
<label for="tlf-10-mode" class="grid place-items-center min-h-11 mt-1.5 px-7 rounded-full border-[1.5px] border-white cursor-pointer text-sm font-semibold transition-colors duration-150 hover:bg-white hover:text-tlf10-acc">Sign up</label>
</div>
<div class="absolute inset-0 flex flex-col items-center justify-center gap-3 p-6 md:p-10 text-center translate-y-full md:translate-y-0 md:translate-x-full transition-[translate] duration-500 ease-[cubic-bezier(0.4,0,0.2,1)] motion-reduce:transition-none">
<h3 class="text-xl md:text-2xl font-bold">One of us?</h3>
<p class="hidden md:block max-w-[240px] text-sm/[1.5] text-tlf10-panelink">Sign in to pick up right where you left off.</p>
<label for="tlf-10-mode" class="grid place-items-center min-h-11 mt-1.5 px-7 rounded-full border-[1.5px] border-white cursor-pointer text-sm font-semibold transition-colors duration-150 hover:bg-white hover:text-tlf10-acc">Log in</label>
</div>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tlf10-stage: #eef0f6;
--color-tlf10-stage: oklch(0.95 0.008 270);
--color-tlf10-ink: #161c2e;
--color-tlf10-ink: oklch(0.23 0.04 270);
--color-tlf10-ph: #8e96ad;
--color-tlf10-ph: oklch(0.65 0.025 270);
--color-tlf10-edge: #d7dbe6;
--color-tlf10-edge: oklch(0.87 0.01 270);
--color-tlf10-field: #fafbfe;
--color-tlf10-field: oklch(0.99 0.003 270);
--color-tlf10-acc: #5560d4;
--color-tlf10-acc: oklch(0.55 0.19 264);
--color-tlf10-halo: #c5caf2;
--color-tlf10-halo: oklch(0.55 0.19 264 / 0.16);
--color-tlf10-ring: #9ba3e8;
--color-tlf10-ring: oklch(0.55 0.19 264 / 0.5);
--color-tlf10-panelink: #eae6ff;
--color-tlf10-panelink: oklch(0.93 0.03 290);
--font-tlf10-sans: 'Outfit', system-ui, sans-serif;
}
.tlf-10 {
width: 100%;
min-height: 100svh;
}
```How this works
The checkbox hack becomes peer. One <input type="checkbox" class="peer sr-only"> holds the mode. Every element that reacts carries its own peer-checked: utilities — the overlay slides, its two panels swap, the two forms trade opacity and stacking order. The state is readable from each element rather than reconstructed from a stylesheet.
The toggles are labels, so keyboard works. The checkbox is sr-only, never hidden: it stays focusable, Space flips the mode, and peer-focus-visible: on the overlay draws an inset ring so the focus is visible on the element the user is actually looking at.
Everything moves on translate. The panel slide, the panel swap and the radius morph are transform and border-radius only — two forms absolutely positioned in one stage, nothing in the layout thread.
Make it yours
- Overlay colours: the one
bg-[linear-gradient(...)]utility. - Slide feel:
duration-500and the shared cubic-bezier. - Copy: the two panel
<div>s are plain markup — swap in your own benefits text. - Split: the overlay is
w-1/2; change it and the translate distance stays-translate-x-full.
Gotchas — read before shipping
sr-only, nothidden, on the toggle.display:noneremoves it from the tab order and the mode switch becomes mouse-only.- The revealed form needs the higher
z-index, or the overlay eats clicks on fields that look interactive — hencepeer-checked:z-2paired withpeer-checked:z-1. peerreaches later siblings only, so the checkbox must be the first child of the stage — which is also why the overlay and both forms sit as siblings rather than nested.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
:checked sibling state and transform transitions are universally supported; the floor is Tailwind v4's generated sheet.