Cómo crear un BOTÓN de Carga Web (Button Loader Spinner) con Animaciones CSS3 y JavaScript

- 👤 Andrés Cruz

🇺🇸 In english

Cómo crear un BOTÓN de Carga Web (Button Loader Spinner) con Animaciones CSS3 y JavaScript

Hoy en día estamos acostumbrados a interfaces que responden visualmente a cada acción. Cuando pulsamos un botón y ocurre algo en segundo plano (una petición Ajax, el envío de un formulario o una validación) esperamos una señal clara de que el sistema está trabajando.

Como hemos visto en muchas entradas, CSS nos sirve prácticamente para cualquier efecto, transformación o efecto que queramos lograr; con CSS podemos hacer ciertos efectos animados que podemos emplear en esto del Material Desing que se ha puesto bastante a la moda incluso en aplicaciones que son externas a Google que fue el progenitor de esta enfoque o guía de diseño.

En este artículo voy a mostrarte cómo transformar un botón redondeado de un estado normal a un estado de carga usando CSS, apoyándonos en un poco de JavaScript para controlar el cambio de estados. El resultado es un botón elegante, inspirado en Material Design, que cambia de forma, oculta su texto y muestra un loader animado sin necesidad de elementos HTML extra.

Veremos cómo crear un sencillo botón que se transforma al realizar un clic sobre el mismo por un tiempo determinado y luego vuelve a la normalidad; como podrás ver en la imagen promocional, este botón redondeado está inspirado en el Material Design de Google lo cual se logra con CSS y un poco de JavaScript y como resultado tenemos un comportamiento bastante elegante; en objetivo es emplearlo como un botón en una fase de carga.

Introducción: por qué transformar un botón mejora la experiencia de usuario

Un botón que no responde visualmente genera dudas:

  • ¿Se ha enviado el formulario? ¿Tengo que volver a hacer clic? ¿Está bloqueada la aplicación?

Transforma físicamente (no solo cambia de color), el usuario entiende inmediatamente que:

  • Su acción fue registrada
  • El sistema está procesando algo
  • No debe interactuar de nuevo

Este patrón es muy común en aplicaciones modernas y se puede implementar de forma sencilla combinando HTML, CSS y JavaScript.

Estructura HTML del botón y su lógica de estados

Para entender la idea primero debemos presentar el HTML del experimento:

<button id="botonTransformer" class="botonTransformer card">
	<span>Pegame un Click</span>
</button>

Cómo vemos en el HTML anterior tiene un detalle peculiar, y es que dentro de la definición del botón contiene un tag span el cual nos servirá para realizar la transformación al ocultar este span cuando sea necesario y mostrar la fase de carga en dicho proceso:

Botón Transformación estado 1

Aquí hay un detalle importante: el texto del botón está dentro de un <span>.

Esto no es casualidad.

Por qué usar un span interno en lugar de ocultar el botón completo

En lugar de ocultar el botón entero durante la carga, ocultamos solo el contenido textual. Esto permite:

  • Mantener el tamaño y la posición del botón
  • Insertar un loader encima sin romper el layout
  • Animar la transformación de forma suave

Este enfoque me ha dado mejores resultados que esconder el botón completo o reemplazarlo dinámicamente.

Estilos base del botón redondeado

Ahora definimos el estilo inicial del botón, antes de cualquier transformación.

Botón redondeado por defecto: Animación del botón

Ahora llega el turno del botón que empleamos por defecto, el botón con las esquinas o bordes redondeados y el CSS del botón propiamente dicho y del span dentro del mismo:

.botonTransformer {
	display: flex;
	justify-content: center;
	align-items: center;
	margin: 20px auto 0px auto;
	border-radius: 5px;
}

Diseño inicial y comportamiento visual

Y el estilo del texto interno:

.botonTransformer span {
	display: inline-block;
	min-width: 150px;
	padding: 10px 20px;
	z-index: 2;
}

La magia empieza cuando cambiamos de estado.

Transformación del botón usando CSS: botón redondo oculto

En otras palabras, al interactuar con el botón que dicho de otra forma es aplicar un clic sobre el botón simplemente ocultamos este span en vez de todo el botón y aquí empleamos ya un truco bastante común en otras entradas y es el de crear un contenedor extra con el selector after y/o before respectivamente:

Uso del pseudo-elemento ::after como loader

.botonTransformer::after {
	content: " ";
	border: solid 4px rgb(204, 0, 0);
	border-right: solid 4px rgb(204, 0, 0);
	border-bottom: solid 4px rgb(204, 0, 0);
	border-left: solid 4px transparent;
	border-radius: 50px;
	position: absolute;
	top: 7px;
	right: 7px;
	bottom: 7px;
	left: 7px;
	margin: auto;
	width: 30px;
	height: 30px;
	opacity: 0;
	z-index: 1;
}

Botón Transformación estado 2

Este pseudo-elemento será nuestro spinner.

Por defecto está oculto (opacity: 0), y solo aparecerá cuando el botón entre en estado de carga.

El botón con el span está oculto y es mostrado al darle un clic para indicar la fase de carga de una tarea.

Animaciones con @keyframes y control de opacidad

Y este CSS es el empleado al presionar el clic sobre el botón; como podemos apreciar tenemos una clase Loading que es colocada mediante JavaScript como veremos un poco más adelante, además indicamos la animación a realizar:

.botonTransformer.Loading::after {
	animation: fadeIn .3s ease-in, spin 1.3s infinite ease-in-out;
	animation-fill-mode: forwards;
}
.botonTransformer.Loading {
	border-radius: 25px;
	max-width: 50px;
	max-height: 50px;
	cursor: default;
}
.botonTransformer.Loading span {
	opacity: 0;
}

Y definimos las animaciones:

@keyframes spin {
 0% { transform: rotate(0deg); }
 100% { transform: rotate(360deg); }
}
@keyframes fadeIn {
 from { opacity: 0; }
 to { opacity: 1; }
}

Cambio de estado del botón al hacer clic

En resumen, cuando el botón entra en estado .Loading, también transformamos su forma:

.botonTransformer.Loading {
 border-radius: 25px;
 max-width: 50px;
 max-height: 50px;
 cursor: default;
}

Y ocultamos el texto:

.botonTransformer.Loading span {
 opacity: 0;
}

Aquí ocurre algo clave: el botón deja de parecer un botón tradicional y pasa a ser un indicador de estado. Este cambio visual es mucho más claro que un simple icono girando.

JavaScript para la transformación del botón de un estado a otro

Cómo podrás imaginar, el JavaScript simplemente captura el evento clic sobre el botón y aplica la clase Loading durante un tiempo determinado, que podría ser el tiempo de carga de algún método Ajax pero para nuestro experimento lo simulamos con un simple setTimeout que es la forma que tenemos en JavaScript para "dormir" o pausar o mejor dicho postergar la ejecución de una función en milisegundos.

En este caso estamos postergando la recuperación del botón a su estado original por 3 segundos, o lo que es lo mismo 3000 milisegundos:

var botonTransformer = document.getElementById('botonTransformer');
var transformer = function () {
	botonTransformer.classList.add('Loading')
	window.setTimeout(function () {
		botonTransformer.classList.remove('Loading')
	}, 3000)
}
botonTransformer.addEventListener('click', transformer)

Con esto obtenemos el siguiente resultado:

Simulación de carga con setTimeout

En este ejemplo simulamos una carga de 3 segundos, pero en un caso real este tiempo puede corresponder a:

  • Una petición Ajax
  • El envío de un formulario
  • Una validación en servidor

Buenas prácticas para producción

En proyectos reales suelo:

  • Deshabilitar clics adicionales
  • Volver al estado original solo cuando la tarea termina
  • Manejar errores visuales si algo falla

Variantes y mejoras del botón

Botón flotante

Para colocar un botón flotante y que este no se vea alterado por el scroll debes emplear el position: fixed; y luego emplear las propiedades bottom o top para posicionar el botón flotante en la parte de arriba o abajo y las propiedades right o left para posicionarlo a la derecha o a la izquierda; y esto es todo.

.float {
 position: fixed;
 bottom: 40px;
 right: 40px;
 box-shadow: 2px 2px 3px #999;
}

Personalización del loader

Puedes cambiar:

  • Tamaño del spinner
  • Colores del borde
  • Velocidad de rotación
  • Forma (redondo, cuadrado, barra)

Ajustes de accesibilidad

  • Añade aria-busy="true" en estado de carga
  • Usa contraste suficiente
  • Evita animaciones demasiado rápidas

Conclusiones

Cómo puedes darte cuenta, es un botón muy curioso y bastante útil, cuantas aplicaciones no hemos empleado hoy en día que tienen un comportamiento similar y lo podemos hacer fácilmente con HTML, JavaScript y CSS; ya con nuestro botón te resultará fácil colocarlo flotante en una esquina, a la izquierda, derecha o donde quieras.

Transformar un botón redondeado de un estado a otro con CSS es un patrón potente, elegante y fácil de implementar. No solo mejora la experiencia de usuario, sino que transmite profesionalidad y cuidado en los detalles.

En mi caso, este enfoque me ha resultado especialmente útil en:

  • Formularios
  • Acciones críticas
  • Interfaces con carga asíncrona

Con muy poco código y una buena estructura, puedes lograr un comportamiento moderno y perfectamente alineado con el diseño actual de aplicaciones web.

Acepto recibir anuncios de interes sobre este Blog.

Se explica cómo transformar un botón con HTML, CSS y JavaScript de un estado a otro, este elegante botón redondeado es ideal para mostrar fases de carga.

| 👤 Andrés Cruz

🇺🇸 In english