Como Criar uma Barra de Progresso Responsiva e Dinâmica com HTML, CSS e JavaScript

barra progresso html css javascript - Como Criar uma Barra de Progresso Responsiva e Dinâmica com HTML, CSS e JavaScript

Texto traduzido por Daniel Rosa
Um tutorial completo para você criar uma barra de progresso responsiva e dinâmica com HTML, CSS e JavaScript.

O objetivo é criar uma barra de progresso responsiva, simples e eficaz, que faça o seguinte:

  • Tenha quatro etapas até a conclusão.
  • Cada etapa tenha um estado defaultactive e complete.
  • Seja possível avançar de uma etapa para a próxima até a conclusão.

HTML

Para reduzir a redundância e aumentar a possibilidade de reutilização, rastreamos todo o state em um componente do Vue. No DOM, isso gera dinamicamente um número qualquer de etapas exigidas.

Observação: É possível fazer isso em JavaScript (ECMAScript) puro ou com qualquer outro framework de front-end. O uso do Vue é para fins de demonstração.

A barra de progresso usa uma marcação em HTML básica. Nela, temos:

  • um contêiner com as classes computadas na etapa atual: progressClasses
  • uma faixa estática em segundo plano: progress__bg
  • um laço que percorre cada etapa e aplica stepClasses com base na etapa atual.

Cada etapa tem:

  • um progress__indicator, que contém um ícone de verificação o qual fica visível quando a etapa foi concluída.
  • um progress__label, que contém o texto de rótulo daquela etapa.
<div
  id="app"
  :class="progressClasses"
>
  <div class="progress__bg"></div>
  
  <template v-for="(step, index) in steps">
    <div :class="stepClasses(index)">
      <div class="progress__indicator">
        <i class="fa fa-check"></i>
      </div>
      <div class="progress__label">
        {{step.label}}
      </div>
    </div>
  </template>
  
  <div class="progress__actions">
    <div
      class="btn"
      v-on:click="nextStep(false)"
    >
      Back
    </div>
    <div
      class="btn"
      v-on:click="nextStep"
    >
      Next
    </div>
    <div>
      Step:
      {{currentStep ? currentStep.label : "Start"}}
    </div>
  </div>
</div>

Para simplificar, progress__actions, que controla a direção na qual a barra progride, é aninhada dentro da própria barra de progresso.

CSS (SCSS)

É aqui que fazemos todo o trabalho pesado. As classes definidas aqui serão aplicadas dinamicamente pelo JS com base na etapa atual.

Primeiro, vamos selecionar algumas cores com as quais trabalharemos (dois tons de cinza, azul, verde e branco, nessa ordem):

$gray:  #E5E5E5;
$gray2: #808080;
$blue:  #2183DD;
$green: #009900;
$white: #FFFFFF;

Em seguida, definimos a classe .progress: o contêiner que une todo o conteúdo da barra de progresso.

.progress {
  position: absolute;
  top: 15vh;
  width: 0%;
  height: 10px;
  background-color: $blue;
  transition: width .2s;
}

Nossa barra de progresso precisa de um .progress__bg, que nossas etapas de progresso percorrerão como se fosse uma trilha. A trilha será cinza, mudando de cor (sendo coberta por essa outra cor) à medida que avançamos para uma próxima etapa.

.progress__bg {
  position: absolute;
  width: 100vw;
  height: 10px;
  background-color: $gray;
  z-index: -1;
}

Cada .progress__step contém o espaço circular da etapa que ficará em destaque e que se preencherá quando a barra de progresso for avançando.

.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);
    }
  }
}

Elas também contém o .progress__indicator circular e o texto do rótulo, .progress__label. O estilo padrão é definido fora 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;
}

Vamos continuar o aninhamento dentro de .progress__step e definir a etapa em seu estado active (ativo).

&.progress__step--active {
  color: $blue;
  font-weight: 600;
}

A seguir, definimos a etapa em seu estado complete (concluído). Observação: os estilos padrão para .progress__indicator e para .progress__label são sobrescritos no estado concluído.

&.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;
  }
}

JavaScript

Como mencionamos antes, esta parte será diferente com base no modo como você implementará a lógica das etapas – dependendo do tamanho do contexto em que ela for implementada, dos frameworks e dos padrões que serão utilizados e assim por diante.

Este exemplo usa um componente do Vue para demonstrar:

  • o cálculo de classes para a barra de progresso com base no estado atual.
  • o cálculo de classes para cada etapa com base no estado atual.

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)
      
      // lidando com o retorno
      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" }   
      }
      
      // lidando com o avanço
      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}`
    }
  }
})

Resultado final

progress 1 - Como Criar uma Barra de Progresso Responsiva e Dinâmica com HTML, CSS e JavaScript

Confira aqui o CodePen para ver um exemplo funcional.

Agora, seu tutorial está completo e pronto para ser compartilhado com outras pessoas que desejam aprender a criar uma barra de progresso responsiva e dinâmica.

banner fullstack developer - Como Criar uma Barra de Progresso Responsiva e Dinâmica com HTML, CSS e JavaScript

Confira também:

Projetos práticos

Sobre o Autor

Robson dos Santos
Robson dos Santos

DICA EXTRA!!!Algumas pessoas estão nos perguntando qual é o curso que recomendamos para quem deseja aprender programação, mesmo sem ter qualquer conhecimento sobre o assunto. Nossa recomendação, tanto para quem está iniciando, como para quem já possui mais experiência, é essa AQUI!

    0 Comentários

    Deixe um comentário

    O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *