Focus, Transition, Cursor e Hover CSS: guia com exemplos interativos
Passe o mouse sobre um botão de qualquer site profissional. Ele muda de cor, talvez suba um pouquinho, e a setinha do mouse vira uma mãozinha. Clique em um campo de formulário e a borda se acende. Nada disso é enfeite: são sinais que dizem ao usuário “isso aqui é clicável” ou “você está digitando neste campo”. Uma página sem esses sinais parece morta, mesmo com um visual bonito.
Neste artigo você vai aprender as quatro ferramentas do CSS que dão vida à interface: as pseudo-classes :hover e :focus, a propriedade transition e a propriedade cursor. E pode testar tudo aqui mesmo, porque os exemplos são de verdade.
O que é uma pseudo-classe?
Até agora selecionamos elementos pelo que eles são: uma tag (p), uma classe (.card), um ID (#promo). Uma pseudo-classe seleciona um elemento pelo estado em que ele está: com o mouse em cima, selecionado, já visitado… Ela é escrita com dois-pontos logo depois do seletor, sem espaço:
:hover — quando o mouse passa por cima
O :hover é ativado enquanto o ponteiro do mouse está sobre o elemento. Você escreve o estilo normal e, separado, o estilo do estado hover:
.botao {
background-color: #1a73c9; /* estado normal */
color: #fff;
}
.botao:hover {
background-color: #f68e36; /* com o mouse em cima */
color: #2b2d42;
}Repare que o :hover só precisa trazer o que muda. A cor do texto, o padding e todo o resto continuam vindo da regra .botao.
O hover não precisa mudar o próprio elemento
Um truque muito usado: passar o mouse em um elemento e alterar outro que está dentro dele. Basta colocar o hover no pai e escrever o filho depois, com espaço:
/* mouse no card → o título dele muda de cor */
.card:hover h4 {
color: #b85309;
}:focus — quando o elemento está selecionado
O :focus é ativado quando um elemento recebe o foco: você clicou em um campo para digitar ou chegou nele apertando a tecla Tab. Ele vale para elementos interativos: input, textarea, select, button e links.
.campo {
border: 2px solid #fab875;
}
.campo:focus {
outline: none; /* remove o contorno padrão */
border-color: #1a73c9;
box-shadow: 0 0 0 4px rgba(54, 158, 246, 0.3); /* "brilho" em volta */
}Nunca remova o foco sem colocar outro no lugar
Por padrão, o navegador desenha um contorno (outline) em volta do elemento focado. Muita gente acha feio e escreve outline: none… e para por aí. O problema: quem navega pelo teclado — pessoas com deficiência motora, usuários de leitores de tela, ou simplesmente quem prefere o Tab — perde completamente a noção de onde está na página.
A regra é simples: se tirar o outline, coloque outro indicador visível (borda, sombra, cor de fundo). No exemplo acima, o box-shadow faz esse papel.
:focus-visible. Essa variação só mostra o indicador quando o foco veio do teclado, e não do clique do mouse. É a forma moderna de ter botões limpos para quem usa mouse sem prejudicar quem usa Tab:.botao:focus-visible {
outline: 3px solid #1a73c9;
outline-offset: 4px;
}transition — a mudança suave
Até aqui, as mudanças acontecem de uma vez, num “estalo”. A propriedade transition faz a mudança acontecer aos poucos, ao longo de um tempo. Compare:
O CSS dos dois botões é idêntico, com uma única diferença: a linha do transition.
.botao {
background-color: #1a73c9;
color: #fff;
transition: background-color 0.4s ease, color 0.4s ease, transform 0.4s ease;
}
.botao:hover {
background-color: #f68e36;
color: #2b2d42;
transform: translateY(-4px); /* sobe 4px */
}.botao), não no :hover. Assim a animação acontece nos dois sentidos: quando o mouse entra e quando sai. Se você colocar só no :hover, a volta será instantânea.A sintaxe do transition
- Propriedade: qual propriedade vai animar (
background-color,transform,color…). Useallpara animar todas, mas prefira listar só as que mudam. - Duração: quanto tempo leva, em segundos (
0.3s) ou milissegundos (300ms). Para interfaces, entre 0.2s e 0.4s costuma ficar natural. Acima de 0.6s o site parece lento. - Função de tempo: o ritmo da animação, explicado logo abaixo. Se omitir, vale
ease. - Atraso (delay): quanto esperar antes de começar. Se omitir, vale
0s.
Para animar mais de uma propriedade com tempos diferentes, separe com vírgula:
transition: background-color 0.3s ease, transform 0.2s ease-out;As funções de tempo (timing functions)
Todas as bolinhas abaixo levam o mesmo tempo para chegar ao fim. O que muda é o ritmo: onde elas aceleram e onde freiam.
| Valor | Ritmo | Sensação |
|---|---|---|
linear | Velocidade constante | Mecânica, de robô |
ease | Acelera rápido e freia devagar (padrão) | Natural, serve para quase tudo |
ease-in | Começa devagar e termina rápido | Bom para coisas que saem da tela |
ease-out | Começa rápido e termina devagar | Bom para coisas que entram ou respondem ao usuário |
ease-in-out | Devagar nas duas pontas | Suave, elegante |
O que dá e o que não dá para animar
O transition só funciona entre valores numéricos ou cores, porque o navegador precisa calcular os “passos do meio”. Cores, tamanhos, opacidade, sombras e transform animam bem. Já trocar a fonte de Arial para Verdana não anima: não existe “meia fonte”. Nesses casos a mudança acontece de uma vez, mesmo com transition.
transform e opacity. Para mover um elemento, transform: translateY(-4px) é muito mais leve para o navegador do que mudar margin-top ou top, que obrigam a recalcular o layout da página inteira.cursor — o formato do ponteiro
A propriedade cursor define qual ícone o mouse mostra quando está sobre o elemento. Ela é a forma mais direta de dizer ao usuário o que acontece se ele clicar. Passe o mouse em cada caixa:
Os mais usados no dia a dia:
.card-clicavel {
cursor: pointer; /* mãozinha: "pode clicar aqui" */
}
button:disabled {
cursor: not-allowed; /* círculo cortado: "não dá para clicar" */
opacity: 0.5;
}
abbr[title] {
cursor: help; /* interrogação: tem uma explicação no title */
}<a href>) já ganham a mãozinha automaticamente. Mas se você transformar uma <div> em algo clicável, coloque cursor: pointer. E o contrário também vale: não coloque mãozinha em algo que não faz nada ao ser clicado — isso frustra o usuário.Juntando tudo: um card de cardápio interativo
Agora as quatro ferramentas trabalhando juntas. Passe o mouse no card e no botão, e experimente também chegar no botão com a tecla Tab:
Cappuccino
Café, leite vaporizado e canela.
R$ 9,50O que cada uma faz no card:
- :hover no card faz ele subir, ganhar sombra e trocar a cor da borda; no botão, troca a cor de fundo;
- transition deixa essas mudanças suaves, na ida e na volta;
- cursor: pointer fica só no botão, que é o que realmente faz algo ao ser clicado;
- :focus-visible mostra um contorno no botão para quem navega pelo teclado.
Código completo do exemplo
Salve os dois arquivos na mesma pasta e abra o index.html no navegador.
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cafeteria Grão Dourado</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<main>
<h1>☕ Cardápio</h1>
<div class="card">
<h4>Espresso</h4>
<p>Café curto e intenso.</p>
<span class="preco">R$ 6,00</span>
<button type="button" class="botao">Pedir</button>
</div>
<div class="card">
<h4>Cappuccino</h4>
<p>Café, leite vaporizado e canela.</p>
<span class="preco">R$ 9,50</span>
<button type="button" class="botao">Pedir</button>
</div>
<div class="card">
<h4>Bolo de cenoura</h4>
<p>Volta amanhã!</p>
<span class="preco">R$ 7,00</span>
<button type="button" class="botao" disabled>Esgotado</button>
</div>
<form class="contato">
<h2>Receba nossas promoções</h2>
<label for="email">Seu e-mail</label>
<input type="email" id="email" class="campo" placeholder="voce@email.com">
<button type="submit" class="botao">Quero receber</button>
</form>
</main>
</body>
</html>style.css/* ===== Página ===== */
body {
margin: 0;
font-family: Arial, sans-serif;
background-color: #f8f9fa;
color: #2b2d42;
}
main {
max-width: 480px;
margin: 0 auto;
padding: 24px 16px;
}
h1, h2 {
color: #1a73c9;
}
/* ===== Cards ===== */
.card {
background-color: #ffffff;
border: 2px solid #fab875;
border-radius: 12px;
padding: 20px;
margin-bottom: 20px;
transition: transform 0.25s ease, /* TRANSITION */
box-shadow 0.25s ease,
border-color 0.25s ease;
}
.card h4 {
margin: 0 0 4px;
color: #1a73c9;
font-size: 1.15em;
transition: color 0.25s ease;
}
.card p {
margin: 0 0 12px;
color: #5c6075;
}
.preco {
font-weight: bold;
color: #1a73c9;
margin-right: 12px;
}
.card:hover { /* HOVER */
transform: translateY(-6px);
box-shadow: 0 12px 24px rgba(43, 45, 66, 0.18);
border-color: #f68e36;
}
.card:hover h4 { /* HOVER no pai muda o filho */
color: #b85309;
}
/* ===== Botões ===== */
.botao {
padding: 10px 22px;
border: none;
border-radius: 8px;
background-color: #1a73c9;
color: #ffffff;
font-size: 16px;
font-weight: bold;
cursor: pointer; /* CURSOR */
transition: background-color 0.3s ease, color 0.3s ease, transform 0.2s ease-out;
}
.botao:hover {
background-color: #f68e36;
color: #2b2d42;
transform: translateY(-2px);
}
.botao:focus-visible { /* FOCO pelo teclado */
outline: 3px solid #1a73c9;
outline-offset: 3px;
}
.botao:disabled {
background-color: #c3c7d0;
cursor: not-allowed; /* CURSOR de bloqueado */
transform: none;
}
/* ===== Formulário ===== */
.contato {
margin-top: 40px;
}
label {
font-weight: bold;
}
.campo {
width: 100%;
box-sizing: border-box;
margin: 6px 0 12px;
padding: 12px 14px;
border: 2px solid #fab875;
border-radius: 8px;
font-size: 16px;
font-family: inherit;
transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.campo:focus { /* FOCUS */
outline: none;
border-color: #1a73c9;
box-shadow: 0 0 0 4px rgba(54, 158, 246, 0.3);
}Resumo rápido
| Recurso | O que faz | Exemplo |
|---|---|---|
| :hover | Estilo enquanto o mouse está sobre o elemento | .botao:hover { … } |
| :focus | Estilo quando o elemento está selecionado (clique ou Tab) | input:focus { … } |
| :focus-visible | Foco só quando vem do teclado | .card:focus-visible { … } |
| transition | Faz a mudança de estilo acontecer aos poucos | transition: color 0.3s ease; |
| cursor | Define o ícone do ponteiro sobre o elemento | cursor: pointer; |
Desafio para praticar
- Crie três botões: um que muda de cor no hover, um que cresce (
transform: scale(1.1)) e um que ganha sombra. Todos comtransitionde 0.3s. - Teste as cinco funções de tempo no botão que cresce. Qual parece mais natural para você?
- Monte um formulário com três campos e navegue entre eles usando apenas a tecla Tab. Dá para ver claramente onde você está? Se não, crie um estilo de
:focus. - Adicione um botão desabilitado com
cursor: not-allowede confira se o hover dele está desligado.
Washington Paiva — instrutor de Desenvolvimento de Sistemas · washington.pro.br
Compartilhe:



Publicar comentário