Barras de temporizador en CSS con propiedades personalizadas
El otro día estaba trabajando en algo que necesitaba un temporizador visible. Había un precedente de UI para este tipo de temporizador en el proyecto. La gente no quería ver que los números bajaran; Era más ideal ver una “barra” drenarse desde llena hasta vacía. Menciono esto porque hay muchísimas maneras de abordar una interfaz de usuario de "temporizador". Esta no es una exploración de todos ellos (una búsqueda en CodePen sería más útil allí), sino una exploración de la única forma que me resultó útil.
El tipo de cronómetro que necesitaba era lo que el proyecto llamó una barra de “tiempo redondo”. Se realiza una acción. Puede provocar un tiempo de ronda y la mayoría de las acciones posteriores se bloquean hasta que finaliza el tiempo de ronda. Entonces, una barra roja muy clara que marcaba era la interfaz de usuario correcta. Da una sensación de ritmo y fluidez en la que puedes sentir el final del cronómetro y cronometrar tu próxima acción.
Configurar esto es bastante fácil...
Pensemos en algo padre/hijo, en caso de que queramos darle estilo a la parte vacía del contenedor en algún momento.
div div/div/div
Por ahora, simplemente diseñemos la barra por dentro.
.round-time-bar div { height: 5px; background: linear-gradient(to bottom, red, #900);}
Eso nos da una pequeña barra roja que podemos usar como indicador de tiempo.
Lo siguiente que debemos hacer es reducirlo, pero aquí es donde debemos pensar en la funcionalidad. ¡Un cronómetro como este necesita saber cuánto tiempo está cronometrando! Podemos darle esa información directamente en el HTML. Esto no significa que estemos evitando JavaScript: lo estamos adoptando. Estamos diciendo: "Hola JavaScript, danos la duración como una variable y la tomaremos a partir de ahí".
div div/div/div
De hecho, esta forma es muy amigable para el JavaScript moderno que maneja DOM. Siempre que --variable
sea correcto, es libre de volver a renderizar ese elemento DOM en cualquier momento y podemos asegurarnos de que el diseño lo maneje bien. Haremos una variación que haga eso.
Por ahora, hagamos realidad la animación. Buenas noticias, es fácil. Aquí hay un fotograma clave de una sola línea:
@keyframes roundtime { to { /* More performant than animating `width` */ transform: scaleX(0); }}
Podemos “aplastar” la barra porque el diseño de la barra no tiene nada que parezca aplastado cuando la escalamos horizontalmente. Si lo hiciéramos, podríamos animar el width
. No es gran cosa, especialmente porque no refluye nada más.
Ahora lo aplicamos a la barra:
.round-time-bar div { /* ... */ animation: roundtime calc(var(--duration) * 1s) steps(var(--duration)) forwards; transform-origin: left center;}
¿Ves cómo estamos tirando de esa --duration
variable para establecer la duración de la animación? Eso hace el trabajo pesado. También lo estoy usando para establecer el mismo número de steps()
modo que "marque" hacia abajo. Ese "tick" puede ser una característica visual de la interfaz de usuario que te guste (a mí me gusta), pero también se adapta a la idea de que JavaScript puede volver a representar esta barra en cualquier momento, y los ticks hacen que sea menos probable que lo notes. Utilicé un número entero para el valor de duración para que pudiera realizar una doble función como esta.
Sin embargo, si desea una animación fluida, podríamos hacerla como una variación, como:
div data-style="smooth" ... /
Entonces no sigas los pasos:
.round-time-bar[data-style="smooth"] div { animation: roundtime calc(var(--duration) * 1s) linear forwards;}
Tenga en cuenta que también estamos usando una linear
animación, lo que parece tener sentido para un temporizador. El tiempo, por así decirlo, no amaina. ¿O no? Lo que sea, es tu decisión. Si desea un temporizador que parezca acelerar o desacelerar en ciertos puntos, hágalo.
Podemos usar la misma API basada en atributos de datos de variación para cosas como variaciones de color:
.round-time-bar[data-color="blue"] div { background: linear-gradient(to bottom, #64b5f6, #1565c0);}
Y una última variación es hacer que cada “segundo” tenga un ancho fijo. De esa manera, un temporizador de 10 segundos literalmente parecerá más largo que uno de 5 segundos:
.round-time-bar[data-style="fixed"] div { width: calc(var(--duration) * 5%);}
Aquí está la demostración:
Observe el pequeño truco que hay para reiniciar la animación CSS.
Ah, y bueno, sé que hay un meter
elemento que tal vez sea un poco más semántico, pero trae su propia interfaz de usuario que no es animable como quería que estuvieran las cosas aquí, al menos no sin luchar contra ello. Pero me pregunto si es más accesible. ¿Anuncia su valor actual de forma útil? ¿Sería un temporizador más accesible si estuviéramos actualizando meter
en tiempo real con JavaScript? Si alguien lo sabe, puedo vincular una solución aquí.
Deja un comentario