Cómo animar un interruptor de palanca de forma limpia
Guía completa para animar un interruptor toggle: desplazamiento del botón, cambio de color de la pista, físicas de muelle frente a transiciones CSS, gestos táctiles y accesibilidad.
Idea clave
Un interruptor bien diseñado mueve la posición del botón y cambia el color de la pista al mismo tiempo en respuesta a la interacción. El botón debe usar un muelle interrumpible o una transición corta de 150 a 200 ms con transform: translateX, mientras la pista cambia su color de fondo. El interruptor debe exponer role="switch" y aria-checked a tecnologías de asistencia, y respetar prefers-reduced-motion.
Por qué fallan las animaciones de interruptor en producción
Los interruptores se pulsan con frecuencia y a menudo muy rápido. Los fallos más comunes ocurren cuando una transición CSS fija se interrumpe a mitad de camino: el botón salta a su origen o queda fuera de sincronía. El uso de físicas de muelles o transiciones de transformación breves y deterministas evita saltos visuales cuando el usuario cambia de opinión y pulsa dos veces seguidas.
Desplazamiento del botón y relleno de pista
Mueve el botón usando translateX en lugar de left o margin-left, porque las propiedades transform no provocan recalcular el diseño ni repintar toda la página. Combina el movimiento con un leve estiramiento (por ejemplo scaleX(1.1)) al pulsar para comunicar inercia, volviendo a escala normal al soltar.
- Traslada el botón con transform: translateX(), nunca con left
- Cambia el color de la pista en 150 a 200 ms
- Mantén el botón circular o ajustado al radio de la pista
- Conserva un área táctil mínima de 44x44 px aunque el interruptor sea más pequeño
Navegación por teclado y estados de foco
Nunca elimines el anillo de foco de un interruptor. Quienes usan teclado y lectores de pantalla navegan con Tab y cambian el estado con Espacio. Asegúrate de que el contorno :focus-visible rodee toda la pista con suficiente contraste contra el fondo.
Comportamiento con movimiento reducido
Cuando se solicita movimiento reducido mediante prefers-reduced-motion, haz que el cambio de color de la pista sea instantáneo o muy breve (50 ms) y mueve el botón directamente a su posición final sin oscilaciones.
Fragmento de implementación en producción
/* Accessible toggle switch */
.switch-track {
width: 48px;
height: 28px;
background-color: #d1d5db;
border-radius: 9999px;
transition: background-color 180ms ease-out;
cursor: pointer;
}
.switch-track[aria-checked="true"] {
background-color: #ff4a1c;
}
.switch-thumb {
width: 22px;
height: 22px;
background: white;
border-radius: 50%;
transform: translateX(3px);
transition: transform 180ms cubic-bezier(0.16, 1, 0.3, 1);
}
.switch-track[aria-checked="true"] .switch-thumb {
transform: translateX(23px);
}
@media (prefers-reduced-motion: reduce) {
.switch-track, .switch-thumb {
transition: none;
}
}Principios clave para recordar
- Usa transform: translateX() para mantener 60 FPS sin recalcular el diseño
- Mantén la animación por debajo de 200 ms o usa un muelle amortiguado
- Conserva un role="switch" accesible con el estado aria-checked reflejado
- Asegura un área de toque de al menos 44x44 px en dispositivos móviles
Preguntas frecuentes
Fuentes
- Switch Pattern — W3C WAI-ARIA Authoring Practices
- CSS Transforms Module Level 1 — W3C