El elemento <progress> de HTML5 te permite mostrar el avance de una tarea sin necesidad de ninguna librería externa. Aquí tienes la sintaxis básica, cómo darle estilo con CSS, cómo actualizarlo con JavaScript y demos en vivo que puedes probar ahora mismo.
Sintaxis básica del elemento progress
La versión más simple no lleva ningún atributo:
<progress></progress>
Sin atributo value, el navegador la muestra como progreso indeterminado: una animación que indica que algo está cargando, pero sin porcentaje conocido. Pruébala aquí:
Cuando sí conoces el avance exacto, añade max (el total) y value (el progreso actual):
<progress max="100" value="70"></progress>
max no tiene que ser 100 necesariamente: puedes usar cualquier número (por ejemplo, páginas leídas de un total) y calcular el porcentaje tú mismo si lo necesitas mostrar como texto.
Cómo darle estilo con CSS
El selector básico es progress[value], pero para cambiar de verdad los colores del relleno necesitas los pseudo-elementos específicos de cada motor de navegador:
.progreso-verde {
width: 250px;
height: 20px;
}
.progreso-verde::-webkit-progress-bar {
background-color: #e0e0e0;
border-radius: 10px;
}
.progreso-verde::-webkit-progress-value {
background-color: #2ecc71;
border-radius: 10px;
}
.progreso-verde::-moz-progress-bar {
background-color: #2ecc71;
border-radius: 10px;
}
::-webkit-progress-bar y ::-webkit-progress-value controlan el fondo y el relleno en Chrome, Edge y Safari; ::-moz-progress-bar hace lo mismo en Firefox. Necesitas los tres si quieres el mismo aspecto en todos los navegadores.
Progreso dinámico con JavaScript
Para actualizar el valor en tiempo real, solo tienes que cambiar la propiedad value del elemento desde JavaScript. Prueba el botón:
const barra = document.getElementById('mi-progreso');
boton.addEventListener('click', () => {
barra.value = barra.value + 20;
});
Progress bar real en una subida de archivo
El caso de uso más habitual es mostrar el avance real de una subida o descarga. Con XMLHttpRequest, el propio navegador te da el porcentaje exacto a través del evento progress:
const xhr = new XMLHttpRequest();
xhr.upload.addEventListener('progress', (evento) => {
if (evento.lengthComputable) {
const porcentaje = (evento.loaded / evento.total) * 100;
barra.value = porcentaje;
}
});
xhr.open('POST', '/subir-archivo');
xhr.send(formData);
No hace falta calcular nada a mano ni simular el avance con setInterval: el navegador ya te da el dato real en evento.loaded y evento.total.
Accesibilidad
El elemento <progress> ya expone automáticamente el rol progressbar a los lectores de pantalla, sin que tengas que añadir ningún atributo ARIA a mano. Solo tienes que asegurarte de que quede identificado por texto:
<label for="progreso-descarga">Progreso de la descarga</label>
<progress id="progreso-descarga" max="100" value="45"></progress>
Si no quieres mostrar una etiqueta visible, usa aria-label="Progreso de la descarga" directamente en el <progress>.
Compatibilidad de navegadores
El elemento <progress> está soportado desde hace años en todos los navegadores modernos: Chrome, Firefox, Safari y Edge. El único caso a tener en cuenta es Internet Explorer, que Microsoft ya no mantiene y no lo interpreta correctamente. Si necesitas dar soporte a IE, tendrás que recurrir a una librería JavaScript como las que ya vimos en barras de progreso con jQuery.
Si tu proyecto no necesita dar soporte a navegadores muy antiguos, usa siempre el elemento nativo: pesa cero, es accesible de fábrica y no depende de ninguna librería que puedas dejar de mantener.
Preguntas frecuentes
¿Puedo usar progress para una barra de nivel, como una batería?
No es lo más correcto: <progress> está pensado para tareas que avanzan hacia una meta. Para un valor que sube y baja libremente (batería, volumen), el elemento adecuado es <meter>.
¿Por qué mi progress no se ve del color que le puse en CSS?
Casi siempre es porque solo aplicaste el selector progress[value] sin los pseudo-elementos ::-webkit-progress-value y ::-moz-progress-bar, que son los que controlan de verdad el color del relleno en cada navegador.
¿Necesito JavaScript si el progreso es fijo?
No. Si el valor no cambia (por ejemplo, un porcentaje que ya conoces al generar la página), con HTML y CSS es suficiente. El JavaScript solo hace falta para progreso que se actualiza en tiempo real.
Si te ha quedado alguna duda sobre cómo integrar la progress bar en tu proyecto, déjamela en los comentarios.

