Tip 31/7231/72
How to create floating labels
Use `peer` and `placeholder-shown` to create floating labels with TailwindCSS.
<div class="group relative max-w-72 w-full">
<input
type="email"
id="email"
name="email"
class="block peer text-gray-950 w-full px-3.5 h-12 pt-2 text-sm rounded-lg border shadow-sm shadow-gray-950/5 outline-hidden focus:ring-2 focus:ring-primary-600 dark:bg-gray-800/25 dark:border-gray-800 dark:text-white"
placeholder=""
/>
<label
for="email"
class="
absolute block inset-y-0 my-auto left-[15px] h-fit text-sm text-nowrap text-gray-500
-translate-y-2 pointer-events-none transition-transform duration-200 scale-[.8] origin-top-left
peer-focus:-translate-y-2 peer-focus:scale-[.8]
peer-placeholder-shown:scale-100 peer-placeholder-shown:translate-y-0
"
>
Your Email
</label>
</div>
Floating labels are a design pattern where a label starts inside an input field and “floats” above it when the field is focused or has a value. This technique enhances usability by maintaining the label as a visible guide without taking extra space.
Key concepts
- ** Input Field as the “Peer”**: Use the
peer
variant on the input field. This allows sibling elements (like the label) to adapt based on the state of the input. :placeholder-shown
: Thepeer-placeholder-shown
pseudo-class helps detect when the input is empty (placeholder is visible). This is used to position the label inside the field.- Using
peer-focus
:peer-focus
allows the label to respond when the input field is focused. - Styling Transitions: Combine
transform
,scale
, andtranslate
withtransition-transform
to smoothly animate the label’s movement and resizing.
The Core Idea
Here’s how it works in simple terms:
- The input field is styled with peer to share its state.
- The label starts in a “resting” position (inside the input).
- When the input is focused or has a value, the label “floats” up using peer-focus or peer-placeholder-shown.
Example Walkthrough
-
Input Field:
- The input has
peer
utility, so its state can control the label. - Place the input in a
relative
container for proper positioning.
- The input has
-
Label Behavior:
- The label is absolutely positioned over the input.
- It uses
peer-placeholder-shown
to stay in its original position when the input is empty. - When the input is focused,
peer-focus
shifts the label to its “floating” position.
-
Transitions:
- Smooth animations are achieved using utilities like
transition
,duration-200
,translate-y
, andscale
.
- Smooth animations are achieved using utilities like
More Examples
Label that floats above the input
<div class="group relative max-w-72 w-full">
<div class="group relative max-w-72 w-full">
<input
type="email"
id="email"
name="email"
class="block peer text-title w-full px-3.5 h-10 text-sm rounded-lg border outline-hidden focus:ring-2 focus:ring-primary-600 dark:bg-gray-900 dark:border-gray-800"
placeholder=""
/>
<label
for="email"
class="absolute block inset-y-0 px-2 bg-white dark:bg-gray-900 text-sm left-[7px] h-fit text-nowrap my-auto -translate-y-[19px] peer-focus:-translate-y-[19px] text-(--caption-text-color) pointer-events-none transition-transform duration-200 scale-[.8] origin-top-left peer-placeholder-shown:scale-100 peer-focus:scale-[.8] peer-placeholder-shown:translate-y-0">Your Email</label>
</div>
</div>
Floating Label with Bottom Border Input
<div class="group relative max-w-72 w-full">
<input
type="email"
id="email"
name="email"
class="block peer text-gray-950 w-full pb-1 text-sm border-b focus:border-primary-600 outline-hidden dark:bg-gray-900 dark:border-gray-800 dark:text-white"
placeholder=""
/>
<label
for="email"
class="
absolute block bottom-2 left-0 text-sm h-fit text-nowrap text-gray-500
-translate-y-4 pointer-events-none transition-transform duration-150 scale-[.8] origin-top-left
peer-focus:-translate-y-4 peer-focus:scale-[.8]
peer-placeholder-shown:scale-100 peer-placeholder-shown:translate-y-0
"
>
Your Email
</label>
</div>
On this page