Skip to content

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 ​

  • transition anima el cambio entre dos estados cuando algo los dispara (:hover, :focus, una clase nueva). Es lo ideal para botones.
  • animation se 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.

8 botones con hover

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: isolate crea un contexto de apilamiento para que z-index: -1 quede detrás del texto pero dentro del botón.
  • Animamos scaleX en lugar de width: el resultado es igual, pero mucho más fluido.
  • Cambia transform-origin a right, center, top o bottom para 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.

Botón magnético

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.

Ripple al hacer clic

Cómo funciona:

  1. En pointerdown creamos un <span class="onda"> del tamaño del lado mayor del botón.
  2. Lo posicionamos centrado en el punto del clic (e.clientX - r.left).
  3. Una animación lo escala de 0 a 4 mientras se desvanece.
  4. En animationend lo eliminamos para no acumular elementos.

Accesibilidad en botones

  • Usa siempre <button> (o <a> si navega a otra página), nunca un <div> con onclick.
  • Da un estilo visible a :focus-visible para 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 ​

  1. Modifica el botón de relleno para que el color entre desde abajo.
  2. Crea un botón "outline" que al hacer hover rellene en diagonal (pista: rota el ::before 45° y hazlo más grande).
  3. 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 ​

  • transition para hover/focus (2 estados); animation para 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().

Academia Web — aprende, copia y construye.