Floating label input is an element that visually combines an input label and the input itself into a single element. Label switches from placeholder mode to label when input is focused or has content in it. This concept has been first introduced by Matt D. Smith in 2013 and it has become a widespread pattern since then, even becoming a standard element in Google's Material Design.
There are several reasons why this pattern in being used even today:
- It saves space
- Looks clean and it makes scanning the form easier
- Looks amazing with smooth transitions
- Accessible
But there are also a few things that both developer and designer need to be aware of:
- Cannot use both label and placeholder - label also takes place of a placeholder.
- Browser support - depending on the implementation, you either need to use Javascript (performance concerns, JS dependency, etc.) or more modern CSS (doesn't support Edge and IE browsers).
- Label becomes smaller on input focus and if it has value - it can be harder to read.
Requirements and specification
For this example, we will implement this input without the use of Javascript and use modern CSS syntax. That means that Edge and Internet Explorer browsers won't fully support the visual features and transitions, but it will remain usable.
Our implementation is going to follow the design that's been optimized for high quality UX and is based on user research.
Transitions (animations) need to be smooth and make use of hardware acceleration where possible.
We also want to make the input accessible and preserve the native tab navigation.
Accessible markup
<div class="floating">
<input id="inputId" class="floating__input" name="input name" placeholder="Placeholder" />
<label for="inputId" class="floating__label" data-content="Placeholder">
<span class="hidden--visually">Placeholder</span>
</label>
</div>
We are going to use a wrapper element <div class="floating">
just to wrap the input-label pairs into a single container and to handle spacing between the inputs. The wrapper element is not required, but it makes styling the group easier.
We are also using accessible hiding of elements with <span class="hidden--visually">
. I've covered this method of hiding elements in one of my previous articles.
Styling
The code required for styling this element is around 80-95 lines of code, so I decided to focus on explaining only specific, more complex, parts. Entire HTML and CSS code can be seen in the Codepen example below.
Styling implementation details:
- We are using
:placeholder-shown
CSS selector andplaceholder
HTML attribute to let the browser do the logic of detecting when the label should be resized to a smaller size or displayed at full size - We are using CSS variables to easily change the color scheme
- We are using
:focus
CSS selector to allow keyboard tab interaction along with the regular click(or touch) interaction
CSS transitions and animations need to be smooth, so we are going to use translate3d
and scale3d
to add support for hardware acceleration to our animations. Most of the other CSS-only solutions use absolute position CSS attributes like top
and left
for transitions that need to be avoided due to poor performance. I've covered this topic more in-depth in one of my previous articles.
Improving CSS performance and file size - an in-depth guide
Adrian Bece for PROTOTYP ・ Oct 16 '19
Some of the other CSS-only solutions make use of required
HTML attribute and :valid
or :invalid
selectors to determine when the label needs to be transformed, which is hacky and semantically incorrect. Also, it makes the implementation impossible for non-required inputs.
In our implementation, label transformation logic is shared with placeholder display logic so it makes the code more semantically correct and flexible.
Example & source code
Edge and IE fallback
As mentioned before, we have used modern CSS syntax instead of JavaScript and we got much cleaner and performant markup, but we've also decreased browser support since Edge and Internet Explorer don't support the :placeholder-shown
selector.
Luckily, our example is still usable on those browsers. We only don't show animations and labels are always displayed in their focused state. We can also use Browser-specific selectors (hacky) or make use of Modernizr (Javascript) (if already included in the project) to provide a better fallback for those browsers.
These articles are fueled by coffee. So if you enjoy my work and found it useful, consider buying me a coffee! I would really appreciate it.
Thank you for taking the time to read this post. If you've found this useful, please give it a ❤️ or 🦄, share and comment.
Top comments (5)
No idea :placeholder-shown selector existed :o !
Totally what I was looking for
Thank you!
Happy to help! Thank you
Love this... wonderful job --- any way to get it to work for textareas?
Thank you. I think you could do it with textareas without any issues, you just need to tweak the CSS.
Amazing! Thank you...