HTML/CSS Form with Floating Labels
Tags: css, html, beginners, webdev
Published: 2021-02-03 11:38:05

Here goes my first post on dev.to. In this article, I am trying to build an HTML/CSS only form with floating labels. You may have seen this "Floating Label forms" on various websites. It is that nifty form interaction where form input fields have labels seated within them until you focus into it. As soon as you focus on the input field, the label pulls a "levitation act", and the input field is revealed. 

Following is the HTML we are working with. I have wrapped the `<input>` element and the `<span>` for label text within the `<label>` element. (Please ignore the `type="button"` for the form button. Just a quick hack to prevent the submit event in the demo.)

```html
<div class="register">
    <form>
        <label for="name">
            <input type="text" id="name" placeholder="Name">
            <span>Name</span>
        </label>
        <label for="email">
            <input type="email" id="email" placeholder="Email">
            <span>Email</span>
        </label>
        <label for="phone">
            <input type="text" id="phone" placeholder="Phone">
            <span>Phone</span>
        </label>
        <button type="button">Register</button>
    </form>
</div>
```

Now let us take a look at our CSS. I have aligned the form to the centre of the page. For the `<form>` element have used `display: flex;` property with `flex-direction: column;`. This gives us stacked form fields.

The `<label>` has a `position:relative:` property. This enables us to place the actual label text within the `<span>` tag with an absolute position placement. I am placing the `<span>` to the top left of the the `<label>`. Then I used CSS transform property to move it 30px down. This gives the appearance that the label is placed within the `<input>` field. I am also setting the `opacity` property of the input placeholder to 0, so that it does not come in the way of our label text.  

```css
*{
    margin:0;
    padding:0;
    box-sizing:border-box;
}
body{
    min-height:100vh;
    display:grid;
    place-content:center;
    font-family:sans-serif;
    color:#6b6b6b;
}
form{
    width:90vw;
    max-width:768px;
    border:1px solid #ddd;
    padding:3vw;
    display:flex;
    flex-direction:column;
    border-radius:5px;
}

label{
    margin-bottom:15px;
    position:relative;
    border-bottom:1px solid #ddd;
}
input{
    width:100%;
    padding:10px 0px;
    margin-top:20px;
    border:none;
    outline:none;
}
input::placeholder{
    opacity:0;
}
span{
    position:absolute;
    top:0;
    left:0;
    transform:translateY(30px);
    font-size:0.825em;
    transition-duration:300ms;
}
button{
    padding:15px 0px; 
    margin-top:20px;
    background:purple;
    color:#fff;
    border:1px solid purple;
    cursor:pointer;
    border-radius:3px;
}
```
This is what we have so far.
![Floating labels form](https://dev-to-uploads.s3.amazonaws.com/i/rg6u2jtko3n6q9pfzhho.png)

Now we will see how to implement the interaction to the label text. For this, we will use 3 CSS pseudo-classes. 

1. `:not`
2. `:focus-within`
3. `:placeholder-shown`

The following CSS adds the interactivity to the label text. 

```css
label:focus-within > span,
input:not(:placeholder-shown) + span{
    color:purple;
    transform:translateY(0px);
}
```
  
With that, we have our CSS only floating label form ready. You can check a live Codepen version here.

{% codepen https://codepen.io/web2feel/pen/zYovYVX %}

<span>Photo by <a href="https://unsplash.com/@alexb?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Alex Blăjan</a> on <a href="https://unsplash.com/s/photos/bouy?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></span>