Hace un par de años escribí un breve artículo sobre cómo crear una barra de progreso receptiva. Mis técnicas se han desarrollado desde entonces, por lo que es necesario actualizarlas.
El mayor cambio es que los pseudo-elementos (antes, después) ya no son necesarios. Ahora el CSS es más sencillo, el DOM es más fácil de leer y es mucho más dinámico.
Intentemos esto de nuevo.
Nuestro objetivo es crear una barra de progreso receptiva simple y eficaz que haga lo siguiente:
- Tiene cuatro pasos para completar.
- Cada paso tiene una
default
,active
ycomplete
estado. - Puede progresar paso a paso hasta su finalización.
Consulte CodePen aquí para ver un ejemplo en vivo.
El HTML
Para reducir la redundancia y aumentar la reutilización, rastreamos todo el estado en un componente de Vue. En el DOM, esto genera dinámicamente cualquier número de pasos requeridos.
Nota : JavaScript nativo (ECMAScript) o cualquier otro marco puede lograr esto. El uso de Vue es para fines demostrativos.
La barra de progreso utiliza un marcado básico. Ahi esta:
- un contenedor con clases calculadas según el paso actual:
progressClasses
- una pista de fondo estática:
progress__bg
- un bucle que recorre cada paso y se aplica
stepClasses
según el paso actual.
Cada paso tiene:
- a
progress__indicator
que contiene un icono de verificación que está visible si el paso está completo. - a
progress__label
que contiene el texto de la etiqueta para ese paso.
{{step.label}} Back Next Step: {{currentStep ? currentStep.label : "Start"}}
Para simplificar, los progress__actions
que controlan la dirección de viaje están anidados dentro de la propia barra de progreso.
El CSS (SCSS)
Aquí es donde hacemos el trabajo pesado. Las clases definidas aquí serán aplicadas dinámicamente por JS según el paso actual.
Primero, seleccionemos algunos colores para trabajar:
$gray: #E5E5E5; $gray2: #808080; $blue: #2183DD; $green: #009900; $white: #FFFFFF;
Ahora defina la .progress
clase: el contenedor que mantiene juntos los contenidos de la barra de progreso.
.progress { position: absolute; top: 15vh; width: 0%; height: 10px; background-color: $blue; transition: width .2s; }
Nuestra barra de progreso necesita .progress__bg
que los pasos de progreso se ejecuten como una pista. Este será gris, cubierto por la barra de color a medida que avanza al siguiente paso.
.progress__bg { position: absolute; width: 100vw; height: 10px; background-color: $gray; z-index: -1; }
Cada uno .progress__step
contiene el paso circular que se resaltará y completará a medida que avanza la barra de progreso.
.progress__step { position: absolute; top: -8px; left: 0; display: flex; flex-direction: column; align-items: center; text-align: center; @for $i from 1 through 5 { &.progress__step--#{$i} { left: calc(#{$i * 20}vw - 9px); } } }
También contiene el .progress__indicator
texto redondo y de etiqueta .progress__label
. Sus estilos predeterminados se definen fuera de .progress__step
.
.progress__indicator { width: 25px; height: 25px; border: 2px solid $gray2; border-radius: 50%; background-color: $white; margin-bottom: 10px; .fa { display: none; font-size: 16px; color: $white; } } .progress__label { position: absolute; top: 40px; }
Ahora continuemos anidando adentro .progress__step
nuevamente y definamos el paso en su estado activo .
&.progress__step--active { color: $blue; font-weight: 600; }
A continuación, defina el paso en su estado completo . Nota : los estilos predeterminados para .progress__indicator
y .progress__label
se sobrescriben cuando están en estado completo.
&.progress__step--complete { .progress__indicator { background-color: $green; border-color: $blue; color: $white; display: flex; align-items: center; justify-content: center; } .progress__indicator .fa { display: block; } .progress__label { font-weight: 600; color: $green; } }
El JavaScript
Como se mencionó anteriormente, esto diferirá en función de cómo implemente la lógica de pasos, el contexto más amplio en el que se implemente, los marcos y patrones que use, etc.
Este ejemplo usa un componente de Vue para demostrar:
- cálculo de clases para la barra de progreso basado en el estado actual.
- cálculo de clases para cada paso basado en el estado actual.
var app = new Vue({ el: '#app', data: { currentStep: null, steps: [ {"label": "one"}, {"label": "two"}, {"label": "three"}, {"label": "complete"} ] }, methods: { nextStep(next=true) { const steps = this.steps const currentStep = this.currentStep const currentIndex = steps.indexOf(currentStep) // handle back if (!next) { if (currentStep && currentStep.label === 'complete') { return this.currentStep = steps[steps.length - 1] } if (steps[currentIndex - 1]) { return this.currentStep = steps[currentIndex - 1] } return this.currentStep = { "label": "start" } } // handle next if (this.currentStep && this.currentStep.label === 'complete') { return this.currentStep = { "label": "start" } } if (steps[currentIndex + 1]) { return this.currentStep = steps[currentIndex + 1] } this.currentStep = { "label": "complete" } }, stepClasses(index) { let result = `progress__step progress__step--${index + 1} ` if (this.currentStep && this.currentStep.label === 'complete' || index < this.steps.indexOf(this.currentStep)) { return result += 'progress__step--complete' } if (index === this.steps.indexOf(this.currentStep)) { return result += 'progress__step--active' } return result } }, computed: { progressClasses() { let result = 'progress ' if (this.currentStep && this.currentStep.label === 'complete') { return result += 'progress--complete' } return result += `progress--${this.steps.indexOf(this.currentStep) + 1}` } } })
Conclusión
Al final de todo, tienes esto:

Consulte CodePen para ver un ejemplo en vivo.
Si encuentra útiles mis artículos, por favor considere convertirse en miembro de mi Patreon :)
O si solo quieres comprarme café (me encanta el café):