Form Labels animations

Labels on forms are needed but they take up a lot of room. Some people like to use placeholder only to explain how to use a form. The problem with this is not everyone can remember exactly what the placeholder said. It might be because the formatting that should be used was part of the placeholder or maybe the user has not the sharpest of memory. I think of myself as having a good memory and every once in a while I’ve forgotten what was supposed to be in the form. Why make it harder then needed?

But having big labels hanging around doesn’t always look great. Well, here’s an idea; use the label as a placeholder and move it over while the user is typing in the field and hid it once they are done. Great. And here’s one better, let’s do it without JavaScript. Completely in CSS!

HTML code

The Form below is a standard form. Nothing fancy. The required attribute is needed so we we can hid the label once the input is valid.

One drawback I’ve found is we can’t use the email type as an input. The reason is if the put in a bad email address the label will move back into the input, and since it’s not valid both the incorrect input and the label will be visible. So it’s a tradeoff.

<form action="#">
    <div class="textInput">
        <input id="firstName" name="firstName" type="text" required>
        <label for="firstName">First name</label>
    <div class="textInput">
        <input id="lastName" name="lastName" type="text" required>
        <label for="lastName">Last name</label>
    <div class="textInput">
        <input id="email" name="email" type="text" required>
        <label for="email">Email Address</label>

CSS Code

Some of the CSS has nothing to do with what we’re doing with the labels. I’ve still adding that CSS here but I’ll just ignore it in the explanation. At the bottom of the article is a Codepen with all this code in place. Please comment out lines to view what each does.

By changing the box-sizing to border-box, I’m fixing an issue that happens were the ends of the input and labels don’t line up.

* {
    box-sizing: border-box;

A little styling for the form.

/* For the whole form */
form {
  margin: 10px auto;
  width: 60%;

We’re going to a use an absolute position for the label. By default it’ll be relative to the window, since we want to adjust it based on the input element we’ll make the div around each input and label pair to be position: relative so that any children of the div can have it’s position based on the div.

/* For each div surrounding the label and input */
div.textInput {
    position: relative;                 
    margin: 10px;
    font-family: 'Karla', sans-serif;

For the input itself, we’re making the background to none so we can see the label behind the input. We’re also making sure the input is in front of the label.

/* For the Text Inputs */
div.textInput input {
    width: 100%;
    padding: 10px 10px 10px 10px;
    background: none;               // removing the background of the input
    border: 2px solid #EB06F4;
    border-radius: 5px;
    z-index: 1;                     // Making sure the input is in front of the label
    color: #3A023C;

As mentioned, we’re positioning the label as absolute so that we can adjust the top, bottom and left to put the label directly behind the input, since the input doesn’t have a background, we’ll see the label in the placeholder position.

The transition property means that any changes to the top will take 0.2s to happen. Otherwise it would jump into place.

div.textInput label {
    position: absolute;               // Marks the element so we can adjust where it's placed
    transition: top 0.2s;             // Any adjustments we make to the top take 0.2s
    top: 0px;
    bottom: 0;
    left: 0px;
    width: 100%;
    padding: 7px 6px;
    color: #3A023C;

Here’s where we get rid of the label. If the input becomes valid, the background turns a color blocking our view.

div.textInput input:valid {
    background: #FCF5FC;

This is making sure the label is behind the input.

div.textInput input:valid + label {
    z-index: -1;

When the user is typing into the field we need to adjust the spacing of the field a bit.

div.textInput input:focus {
    padding: 4px 10px 20px 10px;

While the user is typing we are moving the label to a different position. Also handling some extra styling.

div.textInput input:focus + label {
    top: 100%;
    margin-top: -20px;
    font-size: 70%;
    padding: 1px 16px;
    background: #EB06F4;
    color: #FCF5FC;
    text-transform: uppercase;
    z-index: 2;
    border-radius: 0 0 5px 5px;

Some simple CSS for the Button.

/* For the Button */
button {
    width: 100%;
    padding: 5px;
    background: #EB06F4;
    border: 1px solid #830888;
    color: #FCF5FC;
    border-radius: 5px;
button:hover {
    background: #830888;

CodePen Example

See the Pen Form Label Animation by Russ Eby (@RussEby) on CodePen.


CSS Tricks Floating Labels - This is the post this CSS is based on; which is based on other articles listed at the bottom of the CSS Tricks article.