16 Tailwind CSS Floating Label Inputs

15 Pure Tailwind1 Tailwind + JSPublished

16 Tailwind CSS floating label inputs for login and password fields, checkout address forms, search bars, select menus, and auto-growing textareas — spanning the pure peer pattern, Material outlined and filled fields, validation states, Chrome autofill fixes, ARIA-audited accessibility, icon-inside layouts, dark mode with light-dark(), and no-zoom mobile sizing. Scoped under .tfl-NN for no-collision pasting, prefers-reduced-motion guarded, framework-agnostic.

Related30 Tailwind CSS Login Forms47 Tailwind CSS Toggles & Switches28 Tailwind CSS Input Fields16 CSS Floating Label Inputs

Premium upgradePartner: Untitled UI

Affiliate link

Building a whole Tailwind app, not just this component?

You just browsed 16 Tailwind floating label inputs. Untitled UI Pro unlocks 5,000+ components and sections and 250+ page examples for React, styled with Tailwind CSS v4. One licence is a one-time $349 with lifetime updates; teams start at $999.

Get Untitled UI Pro

Untitled UI React. We may earn a commission, at no extra cost to you.

01. Tailwind Staggered Letter-Cascade Floating Label (opens in a new tab)

Published

Pure Tailwind
Each letter of the label rises on its own, a left-to-right wave: one *: class list styles every letter span, *:[transition-delay:calc(var(--i)*30ms)] staggers them, and group-focus-within: + group-has-[input:not(:placeholder-shown)]: fire the float. The real label text sits in an sr-only span so screen readers hear a word, not letters.

04. Pure Tailwind Floating Label Input (No JavaScript) (opens in a new tab)

Published

Pure Tailwind
The canonical floating label in its native Tailwind form: peer on the input, and peer-focus: plus peer-[:not(:placeholder-shown)]: on the label. The label floats with translate-y-[calc(-50%_-_13px)] scale-72 — transform-only, zero listeners, zero hydration. Every other demo in the collection builds on this one.

05. Tailwind Floating Label with Chrome Autofill Fix (opens in a new tab)

Published

Pure Tailwind
Chrome autofills and the label crashes through the value — unless peer-autofill: joins the float. The port adds peer-[:-webkit-autofill]: as its own utility (so an unknown selector can never kill the list), re-skins the yellow wash with autofill:shadow-[inset_0_0_0_1000px_…], and floats the label out of the field into an eyebrow above it.

06. Tailwind Floating Label Validation States (Error + Success) (opens in a new tab)

Published

Pure Tailwind
CSS-only validation that waits for the user: peer-user-invalid: turns border, label and message red only after interaction, has-[input:user-invalid]:animate-tfl06-shake nudges the field, and has-[input:user-valid]:after:opacity-100 reveals a check chip. Native constraint attributes do all the checking; the label flips on a 3D rotateX as it floats.
Newsletter

Enjoying these demos? Get new ones by email.

A short email when a new collection ships. Unsubscribe any time.

at

Almost there: check your inbox to confirm.Manage

07. Accessible Tailwind Floating Label Input (ARIA + WCAG) (opens in a new tab)

Published

Pure Tailwind
The floating label audited: real for/id binding, aria-describedby hints, a required marker that isn't colour-only, AA contrast in both label states, and a thick focus-visible:outline-3 outline-offset-3 ring. The float barely shrinks (scale-85), bolds instead, and grows an accent tick via peer-focus:before:w-3 — low-vision users never lose it.

08. Tailwind Floating Label for Select Dropdowns (opens in a new tab)

Published

Pure Tailwind
<select> has no placeholder, so the port uses the constraint API: a required select with an empty first option is :invalid until a real choice is made, and peer-valid: floats the label into a solid accent pill on the top border. The chevron is a rotated border square that flips with peer-focus:rotate-225.

09. Tailwind Material Design Outlined Text Field (opens in a new tab)

Published

Pure Tailwind
The Google-style outlined field: on focus the label glides up onto the border and the outline 'opens' a notch around it. The notch is the label's own bg-white px-[5px] erasing the border behind it — no fieldset, no legend, no JS measuring. Focus thickens the edge with focus:shadow-[inset_0_0_0_1px_…], so the text never shifts.

10. Tailwind Filled & Underline Floating Label Input (opens in a new tab)

Published

Pure Tailwind
The calm, editorial filled field: a tinted box with only a bottom border, where focus sweeps an accent underline from the centre outward (after:scale-x-0 focus-within:after:scale-x-100) and the label performs a blink-swap — fading out mid-field and re-materialising in its floated spot via animate-tfl10-swap.

12. Tailwind Input with Icon Inside and Floating Label (opens in a new tab)

Published

Pure Tailwind
Search, email and username fields where the inline SVG icon never collides with the label: at rest the label sits beside the icon; on focus the icon spins out (group-focus-within:-rotate-25 group-focus-within:opacity-0) and the label slides left and up into its place with translate-x-[-30px]. One focus-within:text-tfl12-acc on the field tints icon, border and label together.

13. Responsive Tailwind Floating Label for Mobile (No iOS Zoom) (opens in a new tab)

Published

Pure Tailwind
The mobile survival kit, now sized to the form rather than the screen: the form is an @container, and heights, paddings, type and the float distance are clamp()s over cqi container units. Input text is floored at 16px so iOS Safari never zoom-jumps, every target is ≥48px, and a tinted highlight lane gives the floated label its own track.

14. Tailwind Auto-Growing Textarea with Floating Label (opens in a new tab)

Published

Pure Tailwind
Floating labels on multi-line input, solved: the label anchors to the textarea's first text line (top-[26px], not top-1/2), floats out into a corner-tab chip on the top-left edge, and the field grows with its content via v4's field-sizing-content between min-h-30 and max-h-80 — no autosize library, no listeners.
Newsletter

Enjoying these demos? Get new ones by email.

A short email when a new collection ships. Unsubscribe any time.

at

Almost there: check your inbox to confirm.Manage

15. Tailwind Password Input with Show/Hide Toggle and Floating Label (opens in a new tab)

Published

Tailwind + JS
The login-form workhorse, finished: a floating-label password field with a 44px eye <button> whose icons swap via group-aria-pressed/eye:, plus the strength meter the CSS original only described — four segments lit by group-data-[strength=N]/pw: variants. The script flips attributes; every visual lives in utilities. The label springs with an overshoot bezier.

16. Tailwind Multi-Column Form Grid with Floating Labels (opens in a new tab)

Published

Pure Tailwind
A checkout address form laying floating-label fields onto a six-track grid: col-span-3 pairs, a full-width street, and a col-span-2 City/State/ZIP row. Named container queries (@container/form + @max-[26rem]/form:) re-flow it by the form's own width, and floated labels snap to uppercase micro-legends that unify the grid.
FAQ

Frequently asked questions

How does a Tailwind floating label work without any JavaScript?
The mechanism is the peer class plus sibling state variants — no script runs at all. You mark the <input> as peer, then style the label with two variants: peer-placeholder-shown: (the resting state, label sitting inside the field) and peer-focus: (the floated state, label small and lifted). The trick that makes it purely CSS is giving the input a single-space placeholder, placeholder=" ". That keeps :placeholder-shown true only while the field is genuinely empty, so the label drops when there is a value and floats when the field is focused or filled. Demo 04 is the canonical form of this. Because everything is a state variant compiled to a real CSS selector, the label animates on focus, blur, autofill and back-button restore with zero runtime cost — the browser drives it entirely through the :placeholder-shown and :focus pseudo-classes.
Why does my floating label sit on top of the value after Chrome autofills the field?
This is the most common floating-label bug and it is not your CSS logic — it is timing. Chrome's autofill writes a value into the input without firing the events that change :placeholder-shown in the frame you expect, and the browser's own autofill styling repaints the field. Your label is still in its resting peer-placeholder-shown: position, so it crashes straight through the autofilled text. The fix is to add the autofill state as a second trigger for the floated position. Demo 05 does exactly this: it joins peer-autofill: to the same rules that peer-focus: already carries, so an autofilled field lifts the label just like a focused or typed-in one. Pair it with the usual peer-placeholder-shown: resting rule and the label now knows three ways to be "occupied": focused, filled by typing, or filled by autofill. Test it by saving a login and reloading — the label should already be floated on paint.
How do I make a floating label accessible to screen readers?
A floated label is still a real label — it must be programmatically bound, not just visually associated. Demo 07 wires it correctly: the <label> carries a for that matches the input's id, so clicking the label focuses the field and assistive tech announces the name. Hint and error text live in their own element referenced by aria-describedby, so the description is read after the label rather than being lost as decoration. Two things to watch. First, never rely on the placeholder as the accessible name — the single-space placeholder the float mechanism needs is intentionally empty, so the <label> must carry the text. Second, do not animate the label so small it fails contrast or so fast it violates reduced-motion expectations; keep the floated size legible and gate any transition behind motion-reduce:. The label element stays in the DOM the whole time, so its accessible name is stable whether floated or resting.
Can I use a floating label on a select dropdown the same way?
Not with the placeholder trick, because <select> has no placeholder attribute — :placeholder-shown never applies, so the usual peer-placeholder-shown: rule has nothing to hook onto. Demo 08 solves it with the constraint-validation API instead. The select is marked required and its first <option> is an empty-value placeholder option, which means the control is :invalid while nothing real is chosen and :valid once the user picks an option. You then drive the label from validity: a peer-invalid: variant holds the resting position, and the field floating up on peer-focus: or once it becomes peer-valid:. The one gotcha is that a native select is always "filled" visually, so you must keep that first empty option present and never give it a real value — otherwise the field reads as valid immediately and the label floats before the user has chosen anything.
How do I stop iOS from zooming in when the user taps a floating label input?
iOS Safari auto-zooms whenever a focused input's font size is below 16px, which yanks the whole layout around and is jarring on a form. The rule is simply that the input's rendered font size must be at least 16px at the moment of focus — a 14px field will zoom no matter what else you do. Demo 13 sets the field type at 16px and, crucially, sizes the form to itself with @container rather than the viewport, so the breakpoints that shrink padding and spacing on a narrow screen never drag the input's font below the zoom threshold. Keep any responsive type scaling on the label and surrounding chrome, not on the input text. If you must show a visually smaller field, scale it with the box and letter-spacing but hold the font-size at 16px. This also means testing on a real device or the iOS simulator — desktop Chrome will never reproduce the zoom, so a passing desktop check tells you nothing here.
How do I show error and success states on a floating label without JavaScript?
Demo 06 does this with the user-interaction validity pseudo-classes, which are the key to not shouting at someone mid-typing. A plain :invalid selector is true the instant an empty required field renders, so a naive rule paints every field red before the user has touched anything. Instead it uses peer-user-invalid: and peer-user-valid:, which only apply after the field has been interacted with and blurred. So the border, the floated label and the helper message all turn red on peer-user-invalid: once the user leaves an invalid field, and green on peer-user-valid: when the value satisfies the field's pattern or type. Wire the message element through aria-describedby so the state change is announced, not just coloured. The whole thing is CSS driven by the input's own constraint attributes — required, type="email", pattern — so there is no validation code to keep in sync.
How do I keep a floating label from colliding with an icon inside the input?
The collision happens because both the icon and the label want the same left edge of the field. Demo 12 fixes the geometry rather than fighting it. The inline SVG icon is absolutely positioned inside the field and given a fixed lane, and the input gets left padding equal to that lane so the typed text starts clear of the icon. The label is then offset by the same amount at rest — its peer-placeholder-shown: position starts to the right of the icon, aligned with where the text will be, so nothing overlaps. When the field floats, the label lifts to the top edge on peer-focus: and can slide back to the box's real left edge, since the icon lane no longer matters up there. Mark the decorative icon aria-hidden so it is not announced. The reusable lesson: pad the input for the icon, offset the resting label by the same distance, and let the floated label ignore the lane entirely.
When should I not use a floating label input?
Floating labels are elegant but they trade away persistent guidance, so skip them where the field needs a hint the user must see while typing. Because the label doubles as the placeholder, once the field is focused the resting text is gone — if you also need format help like "MM/YY" or "include a country code", that has to live in a separate aria-describedby hint, not the label, or the user loses it exactly when they need it. They also compress the label into a small floated size, so long labels truncate; a field that needs a full sentence of context is better with a static label above it. And on a dense multi-column form like the checkout grid in demo 16, sixteen animating labels can read as busy — a plain top-aligned label scans faster there. Rule of thumb: use floating labels for short, self-explanatory fields (email, name, password) where the space saving matters, and fall back to a static <label> above the field whenever the label is long or the field needs ongoing formatting guidance.

Related collections

15 CSS 3D Tilt Hover Cards preview

15 CSS 3D Tilt Hover Cards

15 mouse-aware 3D tilt hover cards — e-commerce product spotlight, glassmorphism parallax team card, interactive pricing tier, holographic NFT collectible, pop-out mascot, dark tech grid with border glow, media player album art, blog article preview, cyberpunk neon glow, dashboard KPI widget, minimalist real estate, flip-to-back tilt, mobile app showcase, course learning card, and a Pure CSS touch-friendly tilt. Vanilla JS writes --rx/--ry/--mx/--my; all rendering stays in CSS on the GPU.

24 CSS Animated Cards preview

24 CSS Animated Cards

24 hand-coded CSS animated card patterns organised by what triggers the motion, not by card style. Scroll and entrance triggers: staggered grid reveals, @starting-style mount-in, scroll-driven scale and fade on animation-timeline: view(), View Transitions API card-to-detail morphs, blur-to-sharp lazy image loading, and FLIP re-layout when a filter changes. State-change triggers: add-to-cart success morph, like and save particle burst, expand and collapse to intrinsic height with calc-size(), swipe-to-dismiss on Pointer Events, and skeleton-to-loaded crossfade. Data-driven triggers: count-up KPI metrics, SVG sparkline draw-on-enter, and progress ring fill on load. Ambient idle loops: breathing glow, floating drift, animated gradient mesh backgrounds, conic rotating borders, auto-cycling testimonial decks, and live status pulses. Plus four hover patterns where the effect is the topic itself: cursor spotlight, holographic foil glare, corner ribbon slide, and horizontal accordion expand. Every card is scoped under a .ac-NN prefix for no-collision pasting, guards prefers-reduced-motion, animates compositor-only properties, and ports unchanged to React, Vue, Svelte, Astro, Next.js and Tailwind.

22 CSS Avatars preview

22 CSS Avatars

22 hand-coded CSS avatars for chat apps, team dashboards, comment threads, account menus, and social profiles. Covers circular and squircle shapes, gradient and conic story rings, hexagon clip-path crops, online status dots, notification count badges, verified checkmarks, stacked facepiles with plus-N overflow, initials fallbacks for users without photos, broken-image recovery, avatar pickers, and a size scale system where the ring, badge, and status dot all scale from a single custom property.

Search CodeFronts

Loading…