13 / 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 Floating Pill Login Widget Docked Over App Content
An ultra-compact login widget that floats above app content like a modular control card — fully pill-shaped, docked bottom-centre, ideal for mobile web overlays. The port's practical win is the safe-area dock: bottom-[calc(2rem+env(safe-area-inset-bottom,0px))] is one arbitrary value instead of a variable plus a fallback chain.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<section class="tlf-13 relative w-full min-h-svh overflow-hidden grid place-items-center bg-tlf13-stage font-tlf13-sans p-6">
<div aria-hidden="true" class="absolute inset-0 grid place-items-center text-[38px] font-extrabold tracking-wide text-tlf13-ghost bg-[repeating-linear-gradient(45deg,oklch(0.92_0.02_290)_0_24px,oklch(0.94_0.015_290)_24px_48px)]">your app content</div>
<form novalidate class="absolute left-1/2 -translate-x-1/2 bottom-[calc(2rem+env(safe-area-inset-bottom,0px))] flex flex-wrap items-center gap-2 w-[min(480px,calc(100%-32px))] p-2 pl-4 max-[520px]:p-3 rounded-full max-[520px]:rounded-[26px] bg-white/85 backdrop-blur-xl border border-white/70 shadow-[0_20px_50px_-18px_oklch(0.3_0.08_300/0.45)]">
<span aria-hidden="true" class="flex-none text-xl text-tlf13-acc">◐</span>
<label class="flex-1 min-w-0 max-[520px]:basis-full pr-1.5 border-r border-tlf13-rule max-[520px]:border-r-0 max-[520px]:border-b max-[520px]:border-tlf13-rule max-[520px]:pb-1"><span class="sr-only">Email</span>
<input type="email" autocomplete="email" placeholder="Email" required class="w-full h-11 px-1.5 rounded-full bg-transparent border-0 text-[14.5px] text-tlf13-ink transition-shadow duration-150 placeholder:text-tlf13-ph focus-visible:outline-none focus-visible:ring-3 focus-visible:ring-tlf13-halo"></label>
<label class="flex-1 min-w-0 max-[520px]:basis-full"><span class="sr-only">Password</span>
<input type="password" autocomplete="current-password" placeholder="Password" required class="w-full h-11 px-1.5 rounded-full bg-transparent border-0 text-[14.5px] text-tlf13-ink transition-shadow duration-150 placeholder:text-tlf13-ph focus-visible:outline-none focus-visible:ring-3 focus-visible:ring-tlf13-halo"></label>
<button type="submit" aria-label="Sign in" class="flex-none grid place-items-center size-11 max-[520px]:ml-auto rounded-full border-0 cursor-pointer bg-tlf13-acc text-white text-[19px] transition-[filter,scale] duration-150 hover:brightness-110 active:scale-95 focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tlf13-ring motion-reduce:transition-none motion-reduce:active:scale-100"><span aria-hidden="true">→</span></button>
</form>
</section><section class="tlf-13 relative w-full min-h-svh overflow-hidden grid place-items-center bg-tlf13-stage font-tlf13-sans p-6">
<div aria-hidden="true" class="absolute inset-0 grid place-items-center text-[38px] font-extrabold tracking-wide text-tlf13-ghost bg-[repeating-linear-gradient(45deg,oklch(0.92_0.02_290)_0_24px,oklch(0.94_0.015_290)_24px_48px)]">your app content</div>
<form novalidate class="absolute left-1/2 -translate-x-1/2 bottom-[calc(2rem+env(safe-area-inset-bottom,0px))] flex flex-wrap items-center gap-2 w-[min(480px,calc(100%-32px))] p-2 pl-4 max-[520px]:p-3 rounded-full max-[520px]:rounded-[26px] bg-white/85 backdrop-blur-xl border border-white/70 shadow-[0_20px_50px_-18px_oklch(0.3_0.08_300/0.45)]">
<span aria-hidden="true" class="flex-none text-xl text-tlf13-acc">◐</span>
<label class="flex-1 min-w-0 max-[520px]:basis-full pr-1.5 border-r border-tlf13-rule max-[520px]:border-r-0 max-[520px]:border-b max-[520px]:border-tlf13-rule max-[520px]:pb-1"><span class="sr-only">Email</span>
<input type="email" autocomplete="email" placeholder="Email" required class="w-full h-11 px-1.5 rounded-full bg-transparent border-0 text-[14.5px] text-tlf13-ink transition-shadow duration-150 placeholder:text-tlf13-ph focus-visible:outline-none focus-visible:ring-3 focus-visible:ring-tlf13-halo"></label>
<label class="flex-1 min-w-0 max-[520px]:basis-full"><span class="sr-only">Password</span>
<input type="password" autocomplete="current-password" placeholder="Password" required class="w-full h-11 px-1.5 rounded-full bg-transparent border-0 text-[14.5px] text-tlf13-ink transition-shadow duration-150 placeholder:text-tlf13-ph focus-visible:outline-none focus-visible:ring-3 focus-visible:ring-tlf13-halo"></label>
<button type="submit" aria-label="Sign in" class="flex-none grid place-items-center size-11 max-[520px]:ml-auto rounded-full border-0 cursor-pointer bg-tlf13-acc text-white text-[19px] transition-[filter,scale] duration-150 hover:brightness-110 active:scale-95 focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tlf13-ring motion-reduce:transition-none motion-reduce:active:scale-100"><span aria-hidden="true">→</span></button>
</form>
</section>@import "tailwindcss";
@theme {
--color-tlf13-stage: #eceaf5;
--color-tlf13-stage: oklch(0.93 0.015 290);
--color-tlf13-ghost: #b8b2cf;
--color-tlf13-ghost: oklch(0.76 0.03 290);
--color-tlf13-ink: #241b3a;
--color-tlf13-ink: oklch(0.26 0.05 295);
--color-tlf13-ph: #857ca3;
--color-tlf13-ph: oklch(0.58 0.04 295);
--color-tlf13-rule: #ddd7ec;
--color-tlf13-rule: oklch(0.88 0.02 295);
--color-tlf13-acc: #7a5ae0;
--color-tlf13-acc: oklch(0.56 0.2 290);
--color-tlf13-halo: #c4b4f5;
--color-tlf13-halo: oklch(0.56 0.2 290 / 0.3);
--color-tlf13-ring: #ac95f0;
--color-tlf13-ring: oklch(0.56 0.2 290 / 0.55);
--font-tlf13-sans: 'Figtree', system-ui, sans-serif;
}
.tlf-13 {
width: 100%;
min-height: 100svh;
}
/* Safari < 16.4 backdrop-filter prefix. */
.tlf-13 form {
-webkit-backdrop-filter: blur(24px);
}@import "tailwindcss";
@theme {
--color-tlf13-stage: #eceaf5;
--color-tlf13-stage: oklch(0.93 0.015 290);
--color-tlf13-ghost: #b8b2cf;
--color-tlf13-ghost: oklch(0.76 0.03 290);
--color-tlf13-ink: #241b3a;
--color-tlf13-ink: oklch(0.26 0.05 295);
--color-tlf13-ph: #857ca3;
--color-tlf13-ph: oklch(0.58 0.04 295);
--color-tlf13-rule: #ddd7ec;
--color-tlf13-rule: oklch(0.88 0.02 295);
--color-tlf13-acc: #7a5ae0;
--color-tlf13-acc: oklch(0.56 0.2 290);
--color-tlf13-halo: #c4b4f5;
--color-tlf13-halo: oklch(0.56 0.2 290 / 0.3);
--color-tlf13-ring: #ac95f0;
--color-tlf13-ring: oklch(0.56 0.2 290 / 0.55);
--font-tlf13-sans: 'Figtree', system-ui, sans-serif;
}
.tlf-13 {
width: 100%;
min-height: 100svh;
}
/* Safari < 16.4 backdrop-filter prefix. */
.tlf-13 form {
-webkit-backdrop-filter: blur(24px);
}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-tlf13-stage: #eceaf5;
--color-tlf13-stage: oklch(0.93 0.015 290);
--color-tlf13-ghost: #b8b2cf;
--color-tlf13-ghost: oklch(0.76 0.03 290);
--color-tlf13-ink: #241b3a;
--color-tlf13-ink: oklch(0.26 0.05 295);
--color-tlf13-ph: #857ca3;
--color-tlf13-ph: oklch(0.58 0.04 295);
--color-tlf13-rule: #ddd7ec;
--color-tlf13-rule: oklch(0.88 0.02 295);
--color-tlf13-acc: #7a5ae0;
--color-tlf13-acc: oklch(0.56 0.2 290);
--color-tlf13-halo: #c4b4f5;
--color-tlf13-halo: oklch(0.56 0.2 290 / 0.3);
--color-tlf13-ring: #ac95f0;
--color-tlf13-ring: oklch(0.56 0.2 290 / 0.55);
--font-tlf13-sans: 'Figtree', system-ui, sans-serif;
}
.tlf-13 {
width: 100%;
min-height: 100svh;
}
/* Safari < 16.4 backdrop-filter prefix. */
.tlf-13 form {
-webkit-backdrop-filter: blur(24px);
}@import "tailwindcss";
@theme {
--color-tlf13-stage: #eceaf5;
--color-tlf13-stage: oklch(0.93 0.015 290);
--color-tlf13-ghost: #b8b2cf;
--color-tlf13-ghost: oklch(0.76 0.03 290);
--color-tlf13-ink: #241b3a;
--color-tlf13-ink: oklch(0.26 0.05 295);
--color-tlf13-ph: #857ca3;
--color-tlf13-ph: oklch(0.58 0.04 295);
--color-tlf13-rule: #ddd7ec;
--color-tlf13-rule: oklch(0.88 0.02 295);
--color-tlf13-acc: #7a5ae0;
--color-tlf13-acc: oklch(0.56 0.2 290);
--color-tlf13-halo: #c4b4f5;
--color-tlf13-halo: oklch(0.56 0.2 290 / 0.3);
--color-tlf13-ring: #ac95f0;
--color-tlf13-ring: oklch(0.56 0.2 290 / 0.55);
--font-tlf13-sans: 'Figtree', system-ui, sans-serif;
}
.tlf-13 {
width: 100%;
min-height: 100svh;
}
/* Safari < 16.4 backdrop-filter prefix. */
.tlf-13 form {
-webkit-backdrop-filter: blur(24px);
}<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=Figtree:wght@400;500;600;700;800&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=Figtree:wght@400;500;600;700;800&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
max-[520px]:variants are the right tool for a viewport-docked widget, and the wrong one for a component that could live in a sidebar — compare demo 02's container-query cousins in the breadcrumb collection. Knowing which is which is most of responsive Tailwind.- The divider between the two fields is a
border-rthat becomes aborder-bunder the breakpoint, which is three utilities instead of two rules in two media blocks. ring-3rather thanoutlineon the inner fields, specifically because rings render inside the element and cannot be clipped by the pill's radius.- UI change from the CSS original: Figtree replaces the system stack, the fields grew to 44px (was 44px with 8px padding, now a true
size-11target including the button), the placeholder darkened from#9a92b4tooklch(0.58 0.04 295), and glass opacity went 82% → 85% so the 14.5px field text stays AA over the striped app texture.
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 Floating Pill Login Widget Docked Over App Content
Source: https://codefronts.com/components/tailwind-css-login-forms/tailwind-floating-pill-login-widget/
An ultra-compact login widget that floats above app content like a modular control card — fully pill-shaped, docked bottom-centre, ideal for mobile web overlays. The port's practical win is the safe-area dock: bottom-[calc(2rem+env(safe-area-inset-bottom,0px))] is one arbitrary value instead of a variable plus a fallback chain.
## HTML
```html
<section class="tlf-13 relative w-full min-h-svh overflow-hidden grid place-items-center bg-tlf13-stage font-tlf13-sans p-6">
<div aria-hidden="true" class="absolute inset-0 grid place-items-center text-[38px] font-extrabold tracking-wide text-tlf13-ghost bg-[repeating-linear-gradient(45deg,oklch(0.92_0.02_290)_0_24px,oklch(0.94_0.015_290)_24px_48px)]">your app content</div>
<form novalidate class="absolute left-1/2 -translate-x-1/2 bottom-[calc(2rem+env(safe-area-inset-bottom,0px))] flex flex-wrap items-center gap-2 w-[min(480px,calc(100%-32px))] p-2 pl-4 max-[520px]:p-3 rounded-full max-[520px]:rounded-[26px] bg-white/85 backdrop-blur-xl border border-white/70 shadow-[0_20px_50px_-18px_oklch(0.3_0.08_300/0.45)]">
<span aria-hidden="true" class="flex-none text-xl text-tlf13-acc">◐</span>
<label class="flex-1 min-w-0 max-[520px]:basis-full pr-1.5 border-r border-tlf13-rule max-[520px]:border-r-0 max-[520px]:border-b max-[520px]:border-tlf13-rule max-[520px]:pb-1"><span class="sr-only">Email</span>
<input type="email" autocomplete="email" placeholder="Email" required class="w-full h-11 px-1.5 rounded-full bg-transparent border-0 text-[14.5px] text-tlf13-ink transition-shadow duration-150 placeholder:text-tlf13-ph focus-visible:outline-none focus-visible:ring-3 focus-visible:ring-tlf13-halo"></label>
<label class="flex-1 min-w-0 max-[520px]:basis-full"><span class="sr-only">Password</span>
<input type="password" autocomplete="current-password" placeholder="Password" required class="w-full h-11 px-1.5 rounded-full bg-transparent border-0 text-[14.5px] text-tlf13-ink transition-shadow duration-150 placeholder:text-tlf13-ph focus-visible:outline-none focus-visible:ring-3 focus-visible:ring-tlf13-halo"></label>
<button type="submit" aria-label="Sign in" class="flex-none grid place-items-center size-11 max-[520px]:ml-auto rounded-full border-0 cursor-pointer bg-tlf13-acc text-white text-[19px] transition-[filter,scale] duration-150 hover:brightness-110 active:scale-95 focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tlf13-ring motion-reduce:transition-none motion-reduce:active:scale-100"><span aria-hidden="true">→</span></button>
</form>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tlf13-stage: #eceaf5;
--color-tlf13-stage: oklch(0.93 0.015 290);
--color-tlf13-ghost: #b8b2cf;
--color-tlf13-ghost: oklch(0.76 0.03 290);
--color-tlf13-ink: #241b3a;
--color-tlf13-ink: oklch(0.26 0.05 295);
--color-tlf13-ph: #857ca3;
--color-tlf13-ph: oklch(0.58 0.04 295);
--color-tlf13-rule: #ddd7ec;
--color-tlf13-rule: oklch(0.88 0.02 295);
--color-tlf13-acc: #7a5ae0;
--color-tlf13-acc: oklch(0.56 0.2 290);
--color-tlf13-halo: #c4b4f5;
--color-tlf13-halo: oklch(0.56 0.2 290 / 0.3);
--color-tlf13-ring: #ac95f0;
--color-tlf13-ring: oklch(0.56 0.2 290 / 0.55);
--font-tlf13-sans: 'Figtree', system-ui, sans-serif;
}
.tlf-13 {
width: 100%;
min-height: 100svh;
}
/* Safari < 16.4 backdrop-filter prefix. */
.tlf-13 form {
-webkit-backdrop-filter: blur(24px);
}
```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 Floating Pill Login Widget Docked Over App Content
Source: https://codefronts.com/components/tailwind-css-login-forms/tailwind-floating-pill-login-widget/
An ultra-compact login widget that floats above app content like a modular control card — fully pill-shaped, docked bottom-centre, ideal for mobile web overlays. The port's practical win is the safe-area dock: bottom-[calc(2rem+env(safe-area-inset-bottom,0px))] is one arbitrary value instead of a variable plus a fallback chain.
## HTML
```html
<section class="tlf-13 relative w-full min-h-svh overflow-hidden grid place-items-center bg-tlf13-stage font-tlf13-sans p-6">
<div aria-hidden="true" class="absolute inset-0 grid place-items-center text-[38px] font-extrabold tracking-wide text-tlf13-ghost bg-[repeating-linear-gradient(45deg,oklch(0.92_0.02_290)_0_24px,oklch(0.94_0.015_290)_24px_48px)]">your app content</div>
<form novalidate class="absolute left-1/2 -translate-x-1/2 bottom-[calc(2rem+env(safe-area-inset-bottom,0px))] flex flex-wrap items-center gap-2 w-[min(480px,calc(100%-32px))] p-2 pl-4 max-[520px]:p-3 rounded-full max-[520px]:rounded-[26px] bg-white/85 backdrop-blur-xl border border-white/70 shadow-[0_20px_50px_-18px_oklch(0.3_0.08_300/0.45)]">
<span aria-hidden="true" class="flex-none text-xl text-tlf13-acc">◐</span>
<label class="flex-1 min-w-0 max-[520px]:basis-full pr-1.5 border-r border-tlf13-rule max-[520px]:border-r-0 max-[520px]:border-b max-[520px]:border-tlf13-rule max-[520px]:pb-1"><span class="sr-only">Email</span>
<input type="email" autocomplete="email" placeholder="Email" required class="w-full h-11 px-1.5 rounded-full bg-transparent border-0 text-[14.5px] text-tlf13-ink transition-shadow duration-150 placeholder:text-tlf13-ph focus-visible:outline-none focus-visible:ring-3 focus-visible:ring-tlf13-halo"></label>
<label class="flex-1 min-w-0 max-[520px]:basis-full"><span class="sr-only">Password</span>
<input type="password" autocomplete="current-password" placeholder="Password" required class="w-full h-11 px-1.5 rounded-full bg-transparent border-0 text-[14.5px] text-tlf13-ink transition-shadow duration-150 placeholder:text-tlf13-ph focus-visible:outline-none focus-visible:ring-3 focus-visible:ring-tlf13-halo"></label>
<button type="submit" aria-label="Sign in" class="flex-none grid place-items-center size-11 max-[520px]:ml-auto rounded-full border-0 cursor-pointer bg-tlf13-acc text-white text-[19px] transition-[filter,scale] duration-150 hover:brightness-110 active:scale-95 focus-visible:outline-3 focus-visible:outline-offset-2 focus-visible:outline-tlf13-ring motion-reduce:transition-none motion-reduce:active:scale-100"><span aria-hidden="true">→</span></button>
</form>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tlf13-stage: #eceaf5;
--color-tlf13-stage: oklch(0.93 0.015 290);
--color-tlf13-ghost: #b8b2cf;
--color-tlf13-ghost: oklch(0.76 0.03 290);
--color-tlf13-ink: #241b3a;
--color-tlf13-ink: oklch(0.26 0.05 295);
--color-tlf13-ph: #857ca3;
--color-tlf13-ph: oklch(0.58 0.04 295);
--color-tlf13-rule: #ddd7ec;
--color-tlf13-rule: oklch(0.88 0.02 295);
--color-tlf13-acc: #7a5ae0;
--color-tlf13-acc: oklch(0.56 0.2 290);
--color-tlf13-halo: #c4b4f5;
--color-tlf13-halo: oklch(0.56 0.2 290 / 0.3);
--color-tlf13-ring: #ac95f0;
--color-tlf13-ring: oklch(0.56 0.2 290 / 0.55);
--font-tlf13-sans: 'Figtree', system-ui, sans-serif;
}
.tlf-13 {
width: 100%;
min-height: 100svh;
}
/* Safari < 16.4 backdrop-filter prefix. */
.tlf-13 form {
-webkit-backdrop-filter: blur(24px);
}
```How this works
Centring is left-1/2 plus a negative translate. Not margin:auto, which does not centre an absolutely positioned element of intrinsic width. This is the same line the CSS original insisted on, now two utilities.
The breakpoint is a max-width variant. Tailwind v4's max-[520px]: lets this component keep its narrow behaviour in class lists rather than a trailing media block — and because the widget is docked to the viewport rather than sized by a container, a viewport breakpoint (not a container query) is the honest tool here.
Focus rings must not be clipped. The pill has no overflow-hidden; the field rings are inset ring-3s that render inside the padding, so nothing is cut off by the 9999px radius.
Make it yours
- Dock: swap the
bottom-…utility fortop-6for a header pill. - Accent:
--color-tlf13-accdrives the badge, the go button and all three focus rings. - Pill → card: lower
rounded-fulltorounded-3xl. - Add a signed-in avatar chip in place of the badge glyph — the flex row already has the slot.
Gotchas — read before shipping
- Don't put
overflow-hiddenon the pill: the radius will clip the inner focus rings and keyboard users lose the indicator. - The go button is icon-only, so it needs
aria-label— the arrow glyph isaria-hiddenand announces nothing. env(safe-area-inset-bottom)only resolves on a page withviewport-fit=cover; the,0pxfallback inside thecalc()is what keeps the dock correct everywhere else.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
env() safe-area insets are iOS 11+/Chrome 69+; backdrop-filter ships prefixed for older Safari in the stylesheet.