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
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>
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;
}
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;
}
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);
}
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);
}
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>
...
);
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)}
/>
);
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);
}
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
Top comments (0)