Barra de progreso animada en CSS puro

Después de ver lo sencillo que es crear animaciones en CSS con @keyframes y animation, como vimos en el artículo Animando con CSS3: keyframes y animation, hoy vamos a hacer una barra de progreso, una animación un poco más compleja, que como verás, al final no lo es tanto.

Las barras de progreso son de esos elementos que no suelen faltar en casi ninguna aplicación, y evidentemente las aplicaciones web no son menos. Tradicionalmente se han implementado mediante algún lenguaje de programación, generalmente Javascript, pero las funcionalidades de CSS3 son muchas, y con las nuevas implementaciones de HTML5 que nos permiten hasta crear videojuegos, una barra de progreso ligera y funcional es mucho mejor que las clásicas soluciones. Ya sabes, cuanto menos Javascript mejor.

La estructura

Para crear una barra de progreso no necesitamos mucho, así que nuestra estructura en HTML va a ser muy sencilla. Tan sólo vamos a usar tres etiquetas div, una como contenedor general, que también hará de barra global. La segunda será la que mostrará el progreso de forma gráfica, llenando poco a poco el contenedor. Y la última es sólo un capricho, ya que además de mostrar el progreso de forma gráfica, lo haremos de forma porcentual, y con algún truquillo CSS para que quede lo mejor posible.


<div id="contenedor">
  <div id="barra">
    <div id="texto"></div>
  </div>
</div>

Dibujando la barra

Ahora que ya tenemos nuestra estructura HTML es momento de ponernos a dibujar nuestra barra de progreso. Vamos a definir un alto y un largo para nuestro contenedor general, además le daremos un borde al que le asignaremos un color determinado, así ya tendremos nuestra barra. Después damos estilo a #barra, haciendo que ocupe el 100% del alto y dejando su ancho a cero, ya que inicialmente este será el valor a mostrar por la barra de progreso. Lógicamente le vamos a dar un color de fondo.

Sólo con lo anterior ya tendríamos dibujada nuestra barra de progreso, ahora viene "el capricho". Con nuestro contenedor #texto lo que vamos ha hacer es centrar su contenido tanto vertical como horizontalmente. El texto, como queremos que sea para mostrar un progreso no podemos tenerlo directamente en el HTML, así que lo inyectaremos mediante la propiedad content del pseudo-elemento ::after.


#contenedor {
    width: 25em;
    height: 4em;
    margin: 0 auto;
    border: 2px solid #eb7260;
}

#barra {
    width: 0;
    height: 100%;
    background: #eb7260;
}

#texto {
    font-size: 2em;
    font-weight: bold;
    line-height: 2em;
    width: 12.5em;
    height: 100%;
    text-align: center;
    color: #eb7260;
    mix-blend-mode: multiply;
}

#texto:after {
    content: '0%';
}

Creando la animación

Lo primero que vamos a hacer es crear las @keyframes. Para la barra vamos a jugar con su ancho (width) para simular el efecto de una barra que se llena poco a poco, para lo cual únicamente necesitaremos dos estado, el inicial con width:0 y el final con width:100%.

Para las @keyframes de nuestro campo de texto vamos a necesitar algunos estados más, para al menos mostrar los estados 0%, 25%, 50%, 75% y 100%. Podemos añadir tantos como queramos, pero para este ejemplo será más que suficiente.


@keyframes progreso {
    0% {
        width: 0;
    }
    100% {
        width: 100%;
    }
}

@keyframes porcentaje {
    0% {
        content: '0%';
    }
    25% {
        content: '25%';
    }
    50% {
        content: '50%';
    }
    75% {
        content: '75%';
    }
    100% {
        content: '100%';
    }
}

Por último nos quedan las propiedades de animación que hay que asignar a los elementos que vamos a animar, en nuestro caso #barra y #texto. No vamos a usar ningún valor complicado, tan sólo les daremos a ambas la misma duración (como es lógico), definiremos que el ritmo de la animación sea linear (sobre todo a causa de los porcentajes), y le daremos el valor infinito para la duración de la animación.


#barra {
    animation: progreso 5s linear infinite;
}

#texto:after {
    animation: porcentaje 5s linear infinite;
}

Como ves no es tan difícil hacer una barra de progreso animada, y eso que lo he complicado un poco con ese "caprichito". Tan sólo puntualizar un par de cosas. La primera es que es aconsejable usar los prefijos tanto para @keyframes como para animation, para no tener problemas con los navegadores, sobre todo es aconsejable el prefijo -webkit-.

La segunda es sobre una propiedad que he usado y que no es muy frecuente, mix-blend-mode, y que nos permite realizar diversos efectos mezclando los colores de un elemento con todo lo que tenga debajo. En este pen puedes hacerte una idea general de como funcionan sus valores. Además he creado un pen con la animación que hemos creado en este post, para que puedas trastear con ella todo lo que quieras.

See the Pen Barra de progreso animada sólo con CSS by amram (@amram1977) on CodePen.