Microinterações: o que acontece entre os estados importa
Por que os 200ms de feedback de um botão determinam se um produto parece cuidadoso ou descuidado e como construir isso com código.
Tem uma interação que me incomodou por semanas antes de entender por quê.
Era um botão simples. Clicável, funcional, sem erros. Mas cada vez que eu interagia com ele, alguma coisa parecia descalibrada. O produto funcionava, mas não sentia bem.
Meses depois, trabalhando em outro projeto, vi a diferença com clareza: o primeiro botão mudava de cor instantaneamente. O segundo tinha uma transição de 140ms com uma curva de aceleração cuidadosa. A mesma ação, a mesma cor final mas experiências completamente diferentes.
Essa diferença tem nome: microinteração.
O que é uma microinteração
Microinterações são momentos de design contidos em um único evento: o hover num botão, o clique que confirma uma ação, o toggle que muda de estado, o feedback quando um formulário é enviado.
Dan Saffer, que escreveu o livro de referência sobre o tema, define assim:
“Microinteractions are the details of a product. They are the trigger, the rules, the feedback, and the loop.”
Quatro componentes:
- Trigger — o que inicia a interação (clique, hover, evento do sistema)
- Regras — o que acontece quando o trigger é ativado
- Feedback — o que o usuário vê, ouve ou sente em resposta
- Loop — o que acontece se a interação se repete
A maioria dos bugs de microinteração não está no trigger nem nas regras. Está no feedback. É a parte que o dev entrega funcional e o designer entrega sem especificação suficiente.
O custo do zero
A tentação mais comum no desenvolvimento é transition: none. É seguro, rápido, sem risco de quebrar. Mas tem um custo invisível: o usuário perde o sinal de que algo aconteceu.
Veja a diferença — passe o mouse em cada botão:
O primeiro parece quebrado. O segundo parece lento demais. O terceiro sente correto.
O código que gera essa diferença:
/* Sem transição — evitar */
button { background: #1F3A36; }
button:hover { background: #2D524C; }
/* Pesado demais — evitar */
button {
transition: all 500ms ease;
}
/* Calibrado — usar */
button {
transition: background-color 140ms cubic-bezier(0.4, 0, 0.2, 1),
transform 140ms cubic-bezier(0.4, 0, 0.2, 1);
}
button:hover {
background: #2D524C;
transform: translateY(-1px);
}
Dois princípios aqui: especificidade (transicionar propriedades nomeadas, não all) e timing (hover deve responder entre 100–200ms para parecer imediato mas visível).
Feedback que comunica estado
Um dos usos mais poderosos de microinterações é comunicar mudança de estado. Não apenas “isso aconteceu” mas “isso agora é diferente”.
O exemplo clássico é o botão de like. Clique:
A animação do coração usa transform: scale() com keyframes que sobem além de 1 antes de assentar. Esse overshoot é intencional: comunica energia, não só mudança.
@keyframes heartpop {
0% { transform: scale(1); }
35% { transform: scale(1.4); }
70% { transform: scale(0.9); }
100% { transform: scale(1); }
}
.liked .heart {
animation: heartpop 380ms cubic-bezier(0.36, 0.07, 0.19, 0.97);
fill: #e53e3e;
stroke: #e53e3e;
}
Validação inline
Formulários são onde microinterações salvam ou destroem a experiência. Mover o feedback de “depois de submeter” para “enquanto o usuário digita” muda fundamentalmente a relação com o formulário.
Digite um e-mail abaixo:
O estado do campo muda com base no input sem submeter o formulário, sem mensagem de erro intrusiva. O verde não aparece antes de o usuário terminar de digitar (debounce de 600ms).
const validate = debounce((value: string) => {
const isValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
const hasEnoughChars = value.length > 4;
input.classList.toggle('valid', isValid);
input.classList.toggle('invalid', !isValid && hasEnoughChars);
}, 600);
input.addEventListener('input', (e) => {
input.classList.remove('valid', 'invalid');
validate((e.target as HTMLInputElement).value);
});
A chave aqui é não punir cedo. Só mostrar estado inválido depois que o usuário digitou o suficiente para ter a intenção de um endereço completo.
O que faz uma microinteração boa
Depois de construir e estudar centenas delas, reduzo a três critérios:
Timing honesto. Hover: 100–200ms. Transições de estado: 200–350ms. Feedback de sistema (loading, sucesso): 300–500ms. Acima de 500ms, o usuário começa a questionar se o clique foi registrado.
Easing com propósito. ease-in-out é genérico. Use curvas com intenção: cubic-bezier(0.4, 0, 0.2, 1) para a maioria das transições de estado, cubic-bezier(0.34, 1.56, 0.64, 1) para elementos que “chegam” com energia, cubic-bezier(0.25, 0.46, 0.45, 0.94) para saídas rápidas.
Feedback proporcional. Uma microinteração que desvia mais atenção do que a ação principal está errada. O feedback deve ser perceptível, não dominante.
Ferramentas para construir
CSS nativo é o ponto de partida. Transitions e animations cobrem 80% dos casos sem nenhuma dependência. O esforço vale porque força você a pensar nas propriedades exatas que estão mudando.
Framer Motion (React) é o padrão da indústria para animações declarativas. A API de variants e o AnimatePresence resolvem os casos que CSS não cobre bem: elementos que entram e saem do DOM.
<motion.button
whileHover={{ scale: 1.02, y: -1 }}
whileTap={{ scale: 0.97 }}
transition={{ type: "spring", stiffness: 400, damping: 25 }}
>
Confirmar
</motion.button>
AutoAnimate resolve uma categoria específica: animar listas quando itens são adicionados, removidos ou reordenados. Uma linha de código, zero configuração.
import autoAnimate from '@formkit/auto-animate';
autoAnimate(document.querySelector('#list'));
GSAP quando a complexidade pede. Timelines, sequências, animações baseadas em scroll. A curva de aprendizado é real, mas o controle também.
O detalhe é o design
Existe uma citação de Charles Eames que cabe aqui: “The details are not the details. They make the design.”
Microinterações são onde a maioria dos produtos para de investir. É compreensível: elas não aparecem no roadmap, não têm métrica de negócio direta, e o esforço parece desproporcional ao tamanho visual da mudança.
Mas é exatamente onde os usuários sentem a diferença entre um produto que foi construído e um produto que foi cuidado.
Um botão com 140ms de transição calibrada não muda a conversão de forma mensurável. Mas acumule isso por toda a interface, e você tem um produto que parece caro, que parece confiável, que parece feito por pessoas que se importaram.
Esse julgamento acontece em 200 milissegundos. E é completamente correto.