DEV Community

Cover image for Let's create a floating label input with HTML and CSS only
Adrian Bece
Adrian Bece

Posted on • Updated on

Let's create a floating label input with HTML and CSS only

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.

Alt Text

Floating label input from Google Material UI docs

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>
Enter fullscreen mode Exit fullscreen mode

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.


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 and placeholder 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.

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.

Alt Text

Our example in Microsoft Edge & IE 11

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.

Buy Me A Coffee

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 (6)

dnavelasquez profile image
Diana Velásquez • Edited

No idea :placeholder-shown selector existed :o !
Totally what I was looking for

Thank you!

adrianbdesigns profile image
Adrian Bece

Happy to help! Thank you

lancelarsen profile image
Lance Larsen

Love this... wonderful job --- any way to get it to work for textareas?

adrianbdesigns profile image
Adrian Bece

Thank you. I think you could do it with textareas without any issues, you just need to tweak the CSS.

lancelarsen profile image
Lance Larsen

Amazing! Thank you...