DEV Community

Rafael Domingues
Rafael Domingues

Posted on

8 1

Criando um input com label flutuante no ReactJS

O que é um label flutuante?

Esses dias eu estava trabalhando em um projeto e me deparei com o design dos inputs, que tinham um placeholder enquanto vazios e quando preenchidos o placeholder ficava acima do texto digitado, algo bem simples mas que faria uma diferença no layout da página.

Exemplo:

Depois de pesquisar um pouco decidi fazer um pequeno post e compartilhar para quem sabe ajudar a dar um toque a mais no design dos seus Inputs. Vamos lá!

Como fazer?

Primeiramente vou criar um novo projeto do React com yarn.



$ yarn create react-app float-input


Enter fullscreen mode Exit fullscreen mode

Depois de limpar o código que o react criou sozinho vou criar uma div contendo um elemento input e um elemento label, da seguinte forma:



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

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


Enter fullscreen mode Exit fullscreen mode

E agora vou estilizar um pouco com css, fique a vontade para estilizar da forma que preferir, no meu caso fiz o seguinte:



#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;
}


Enter fullscreen mode Exit fullscreen mode

Por fim nosso label e nosso input estão aparecendo assim na página:

Agora começamos com a "mágica", que consiste em uma transition e o comportamento do absolute, que tem os eixos referentes ao elemento pai, caso esse seja relative.

Primeiro adicionamos position relative ao css da nossa div pai:



#float-label {
  ...

  position: relative;
}


Enter fullscreen mode Exit fullscreen mode

Agora adicionamos position absolute ao nosso label e um transform para centralizar nosso label, como se ele fosse um placeholder para nosso input:



#float-label label {
  ...

  position: absolute;
  transform: translate(0, 26px) scale(1);
}


Enter fullscreen mode Exit fullscreen mode

Temos o seguinte resultado:

Agora vamos fazer a animação com um transition e uso do focus-within para aplicar o efeito de translate para mudar a posição e scale na nossa label:



#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);
}


Enter fullscreen mode Exit fullscreen mode

Temos agora o seguinte resultado mas ainda com um pequeno problema que já vamos corrigir:

Para corrigir esse problema eu encontrei a seguinte solução:

Primeiro adicionamos um className ao nosso label, que vai depender diretamente de uma variável que vamos criar no estado do nosso componente React através do hook useState:



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

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


Enter fullscreen mode Exit fullscreen mode

Para alterar essa nossa variável do estado criaremos uma função que lida com o que foi digitado no nosso input:



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)}
/>
);


Enter fullscreen mode Exit fullscreen mode

A função é chamada sempre que digitamos algo no input e é responsável por mudar nosso value e verificar se o texto no input é de fato alguma palavra.

Por fim, estilizamos nossa classe Active no nosso css com o mesmo código utilizado antes para fazer nosso label mudar de posição, ficando assim:



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


Enter fullscreen mode Exit fullscreen mode

E nossa animação está pronta! Me diz ai embaixo o que você achou e se conseguiu fazer ai :)

Lembrando que se conhecer uma forma melhor de fazer esta mesma funcionalidade, fique a vontade para compartilhar também!

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

Image of Stellar post

Check out Episode 1: How a Hackathon Project Became a Web3 Startup 🚀

Ever wondered what it takes to build a web3 startup from scratch? In the Stellar Dev Diaries series, we follow the journey of a team of developers building on the Stellar Network as they go from hackathon win to getting funded and launching on mainnet.

Read more

Top comments (0)

Image of Stellar post

Check out Episode 1: How a Hackathon Project Became a Web3 Startup 🚀

Ever wondered what it takes to build a web3 startup from scratch? In the Stellar Dev Diaries series, we follow the journey of a team of developers building on the Stellar Network as they go from hackathon win to getting funded and launching on mainnet.

Read more

👋 Kindness is contagious

Please show some love ❤️ or share a kind word in the comments if you found this useful!

Got it!