Six floating label fields in Tailwind: an outlined field with the label on the border, a filled field, an underline with a growing line, a textarea, a dark search field with an icon and an email field with validation.
The classic floating label built with the peer modifier: the input has placeholder=" " so peer-placeholder-shown tells whether it is empty, and the label sits inside the field until focus or text lifts it onto the border.
A filled field with a tinted background and a strong bottom border, the label resting in the middle and shrinking to the top on focus. Extra top padding on the input leaves room for the raised label.
A minimal underline field where a coloured line grows from the left on focus. The line is an aria-hidden span after the input, scaled from 0 to full width with peer-focus:scale-x-100.
The same peer technique on a textarea, which also supports placeholder-shown. The label floats to the top padding instead of onto the border, which suits tall fields, and the focus ring is a soft violet glow.
A rounded search field on a dark surface with a leading icon. The label starts beside the icon and floats onto the border; its background matches the field so the border appears to break around it.
An email field that turns red only after something has been typed and the value is invalid, using the arbitrary peer variant peer-[:not(:placeholder-shown):invalid]. An error line appears in words, so the state is not shown by colour alone.
Put peer on the input and the label after it. Give the input placeholder=" "; then peer-placeholder-shown: styles the label while the field is empty and peer-focus: lifts it on focus.
Variant order does the work
Tailwind emits focus styles after placeholder-shown styles, so peer-focus:top-0 wins over peer-placeholder-shown:top-1/2 without any extra specificity.
Keep the real label
The floating text is a real label with for, so the field keeps its accessible name; pointer-events-none lets clicks pass through to the input.
Validation after typing
peer-[:not(:placeholder-shown):invalid]: shows errors only once something has been typed, and the error appears in words, not colour alone.
Frequently asked questions
Does this need JavaScript?
No. All six fields work with CSS only.
Why placeholder with a space?
The :placeholder-shown selector only works when a placeholder exists; a single space is invisible.
Is there a CSS version?
Yes, see the CSS floating label inputs collection.