Floating Label Input
A modern input field where the placeholder smoothly floats up to become a label upon focus.
Preview
Use Cases and Features
The floating label is a modern, space-efficient input form UI widely adopted in Material Design and elsewhere.
-
Space-saving: Since it serves as both a label and a placeholder, it saves vertical space even in limited screen areas.
-
Clarity of input: The label remains visible even while the user is typing or after input is completed, ensuring they always know what the field represents without confusion.
-
Refined interactions: The smooth floating animation of the label upon focus effectively gives the user visual feedback that the field is “ready for input.”
Design and UX Insights
-
Placeholder hack: By leveraging the `:placeholder-shown` pseudo-class, we determine the state (whether input has been provided) entirely with CSS, without using any JavaScript. (*Note: The `placeholder=” ”` attribute in the HTML is a strict requirement for this to work.)
-
Maintaining visibility: When the label floats up, we reduce its text size (`scale(0.75)`) while making it bold (`font-weight: 500`) and applying the theme color to ensure it remains legible.
-
Accessibility: Linking the
labelelement’sforattribute to theinputelement’sidsupports screen readers and focus shifting when the label is clicked. We also apply `pointer-events: none` so the label doesn’t interfere with user interactions.
Customization Guide
You can adjust the following points to match your project’s design system:
-
Coloring: Change the color of `.fli-input:focus` and `.fli-input:focus ~ .fli-label` (currently `#6366f1`) to your brand color.
-
Border radius and shadows: By modifying the
border-radiusandbox-shadowof `.fli-input`, you can create a flatter design or a rounder, more playful look. -
Font size: If you adjust the label’s font size or scaling factor (`scale(0.75)`), be sure to tweak the
paddingof `.fli-input` (especially the top padding) to prevent the label from overlapping the input text.
Implementation Code
<div class="fli-group">
<input type="text" id="username" class="fli-input" placeholder=" " required />
<label for="username" class="fli-label">username</label>
</div>
<style>
.fli-group {
position: relative;
width: 100%;
max-width: 320px;
}
.fli-input {
width: 100%;
padding: 1.5rem 1.25rem 0.5rem;
font-size: 1rem;
font-family: inherit;
color: #0f172a;
background-color: #ffffff;
border: 2px solid #e2e8f0;
border-radius: 0.75rem;
outline: none;
box-sizing: border-box;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -1px rgba(0, 0, 0, 0.03);
}
.fli-input:hover {
border-color: #cbd5e1;
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.05), 0 4px 6px -2px rgba(0, 0, 0, 0.025);
}
.fli-input:focus {
border-color: #6366f1;
box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.15);
background-color: #ffffff;
}
.fli-label {
position: absolute;
top: 1.1rem;
left: 1.25rem;
font-size: 1rem;
color: #64748b;
pointer-events: none;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
transform-origin: left top;
}
/* Inputting or completed status */
.fli-input:focus ~ .fli-label,
.fli-input:not(:placeholder-shown) ~ .fli-label {
transform: translateY(-0.6rem) scale(0.75);
color: #6366f1;
font-weight: 500;
}
/* Out of focus but still input */
.fli-input:not(:focus):not(:placeholder-shown) ~ .fli-label {
color: #475569;
}
</style> Browser Support
-
Chrome: Latest version
-
Safari: Latest version
-
Firefox: Latest version
-
Edge: Latest version
The `:placeholder-shown` pseudo-class is supported in all modern browsers and is safe to use.