Tema
Hover en botones
Los botones son el lugar donde más se notan las microinteracciones: un buen hover le dice al usuario "esto es clicable" y hace que la interfaz se sienta viva. Aquí tienes 10 efectos, de los más sutiles a los más llamativos.
Concepto: transition vs animation
transitionanima el cambio entre dos estados cuando algo los dispara (:hover,:focus, una clase nueva). Es lo ideal para botones.animationse usa cuando hay más de dos pasos o la animación debe ejecutarse sola o en bucle.
css
.btn {
background: #8b5cf6;
transition: transform .3s ease, background .3s ease; /* qué propiedades y cómo */
}
.btn:hover {
transform: translateY(-3px); /* estado final */
background: #7c3aed;
}Declara la transición en el estado normal
Si pones transition sólo en :hover, la animación funciona al entrar pero no al salir (vuelve de golpe). Declárala en el selector base para que funcione en ambos sentidos.
Evita transition: all
all anima cualquier propiedad que cambie, incluidas algunas costosas que no esperabas. Lista explícitamente las propiedades: transition: transform .3s, opacity .3s;.
8 efectos de hover con CSS puro
Relleno deslizante, relleno desde el centro, borde que se dibuja, brillo, neón, presión 3D, flecha y degradado en movimiento.
La técnica clave: pseudo-elementos. Casi todos usan ::before o ::after como una capa extra dentro del botón:
css
.relleno { position: relative; overflow: hidden; isolation: isolate; }
.relleno::before {
content: "";
position: absolute; inset: 0; z-index: -1; /* detrás del texto */
background: #8b5cf6;
transform: scaleX(0); /* empieza sin ancho */
transform-origin: left; /* crece desde la izquierda */
transition: transform .35s ease;
}
.relleno:hover::before { transform: scaleX(1); }isolation: isolatecrea un contexto de apilamiento para quez-index: -1quede detrás del texto pero dentro del botón.- Animamos
scaleXen lugar dewidth: el resultado es igual, pero mucho más fluido. - Cambia
transform-originaright,center,topobottompara otras direcciones.
Borde dibujado: dos pseudo-elementos crecen en ancho y alto con retrasos encadenados (transition: width .25s, height .25s .25s), coloreando primero arriba/derecha y luego abajo/izquierda.
Presión 3D: una sombra sólida (box-shadow: 0 6px 0 #4c1d95) simula el grosor; en :active el botón baja 6 px y la sombra desaparece.
Botón magnético
El botón se desplaza hacia el cursor como si lo atrajera un imán. Muy usado en portafolios y agencias creativas.
Cómo funciona: en mousemove calculamos la distancia del mouse al centro del botón y la multiplicamos por un factor (--fuerza). El texto se mueve un poco más que el fondo para dar profundidad. Al salir, quitamos el transform y la transition lo devuelve suavemente a su sitio.
js
const x = e.clientX - (r.left + r.width / 2);
const y = e.clientY - (r.top + r.height / 2);
btn.style.transform = `translate(${x * fuerza}px, ${y * fuerza}px)`;Efecto ripple (onda al hacer clic)
El efecto clásico de Material Design: una onda circular nace exactamente donde hiciste clic.
Cómo funciona:
- En
pointerdowncreamos un<span class="onda">del tamaño del lado mayor del botón. - Lo posicionamos centrado en el punto del clic (
e.clientX - r.left). - Una animación lo escala de
0a4mientras se desvanece. - En
animationendlo eliminamos para no acumular elementos.
Accesibilidad en botones
- Usa siempre
<button>(o<a>si navega a otra página), nunca un<div>cononclick. - Da un estilo visible a
:focus-visiblepara quien navega con teclado. Todos los demos lo incluyen. - Los efectos que dependen del mouse (magnético) deben ser un extra: el botón tiene que verse y funcionar bien sin ellos.
Ejercicios
- Modifica el botón de relleno para que el color entre desde abajo.
- Crea un botón "outline" que al hacer hover rellene en diagonal (pista: rota el
::before45° y hazlo más grande). - Combina el ripple con el botón de brillo.
Ver solución del ejercicio 1
css
.relleno::before {
transform: scaleY(0);
transform-origin: bottom;
}
.relleno:hover::before { transform: scaleY(1); }Resumen
transitionpara hover/focus (2 estados);animationpara pasos múltiples o bucles.- Declara la transición en el estado base y lista las propiedades.
- Pseudo-elementos +
transform: scale= rellenos y brillos fluidos. - Los efectos con JS (magnético, ripple) son pocas líneas: calcula posiciones con
getBoundingClientRect().