Creating Floating Label/Placeholder for Input with ReactJS
Tags: web, react, tutorial, beginners
Published: 2020-08-19 17:35:09

# - What is a float label?

These days I was working in a project that the inputs had a different behavior, while empty they had a normal placeholder but when filled, the placeholder moved above the typed text, something that looks very simple but that would make a difference in the page layout.

Example: 

<img src="https://dev-to-uploads.s3.amazonaws.com/i/3f3xmx9tb3310r7wsl1c.gif" width=600 />

After some research I decided to share my learning and help you put that finishing touch on your projects.

# - How to do?

### Creating a new project

First of all I will create a new project in React with yarn:

```bash 
$ yarn create react-app float-input
```

After cleaning up the code that the command did for us, I created  a div that contains an input and a label like this:

```jsx
<div id="float-label">
  <input type="email" />

  <label htmlFor="email">
    E-mail
  </label>
</div>
```

Now let's stylize with `css`, feel free to style it the way you prefer, in my case I did the following:

```css
#float-label {
  display: flex;
  flex-direction: column;
  min-width: 350px;
}

#float-label input {
  width: 100%;
  height: 56px;
  padding: 14px 16px 0 10px;
  outline: 0;
  border: 1px solid #ddd;
  border-radius: 4px;
  background: #fff;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 16px;
}

#float-label label {
  font-size: 16px;
  font-family: Arial, Helvetica, sans-serif;
  padding: 0 12px;
  color: #999;
  pointer-events: none;
}
```

Our input now looks like this:

<img src="https://dev-to-uploads.s3.amazonaws.com/i/b2ybaoyspaq2wnxjrjed.png" width=400/>

### Doing animation with CSS

Now we start with the "magic", which consists of a _transition_ and the behavior of _position absolute_, which has the axes referring to the parent element, if it is _position relative_.

First we add _position relative_ to the `css` of our ` div`:

```css
#float-label {
  ...

  position: relative;
}
```

Now we add _position absolute_ to our `label` and a _transform_ to center our `label`, as if it were a placeholder for our `input`:

```css
#float-label label {
  ...
  
  position: absolute;
  transform: translate(0, 26px) scale(1);
}
```

We have the following result:

<img src="https://dev-to-uploads.s3.amazonaws.com/i/1c81x1ze8ioj92mw5nov.png" width=400/>

Now we are going to do the animation with a _transition_ and use the `focus-within` to apply the translate effect to change the position and scale in our` label`:

```css
#float-label label {
  ...
  
  transform-origin: top left;
  transition: all 0.2s ease-out;
}

#float-label:focus-within label {
  transform: translate(0, 12px) scale(0.75);
}
```

We now have the following result but still with a small problem that we are going to fix:

<img src="https://dev-to-uploads.s3.amazonaws.com/i/c73bl7gaeygkwckllkri.gif" width=600/>

### Doings changes in ReactJS

First we add a className to our `label`, which will depend directly on a variable that we will create in the state of our React component through the `useState` hook:

```jsx
const [isActive, setIsActive] = useState(false);

return(
...
  <label className={ isActive ? "Active" : ""} htmlFor="email" >
  E-mail
  </label>
...
);
```

To change our state variable we will create a function that handles what was typed in our input:

```jsx
const [value, setValue] = useState('');

function handleTextChange(text) {
  setValue(text);

  if (text !== '') {
    setIsActive(true);
  } else {
    setIsActive(false);
  }
}

return(
...
<input
  type="email"
  value={value}
  onChange={(e) => handleTextChange(e.target.value)}
/>
);
```

The function is called whenever we type something in the `input` and is responsible for changing our value and checking if the text in the input is actually a word.

Finally, we stylized our Active class in our `css` with the same code used before to make our `label` change position:

```css
#float-label .Active {
  transform: translate(0, 12px) scale(0.75);
}
```

And our animation is ready! Tell me below if you liked and if you managed to do it :)

<img src="https://dev-to-uploads.s3.amazonaws.com/i/3f3xmx9tb3310r7wsl1c.gif" width=600 />

Remembering that if you know a better way to do this same functionality, feel free to share too!

Based on: https://velhobit.com.br/design/como-fazer-efeito-float-label-animado-com-css3-puro.html