Kako izraditi reaktivnu i dinamičnu traku napretka pomoću HTML-a, CSS-a i JavaScript-a

Prije nekoliko godina napisao sam kratki članak o stvaranju responzivne trake napretka. Moje su se tehnike razvile od tada i tako je na redu ažuriranje.

Najveća je promjena u tome što više nisu potrebni pseudo-elementi (prije, poslije). Sada je CSS jednostavniji, DOM je lakši za čitanje i puno je dinamičniji.

Pokušajmo ovo ponovo.

Cilj nam je izgraditi jednostavnu i učinkovitu reakcijsku traku napretka koja čini sljedeće:

  • Ima četiri koraka do završetka.
  • Svaki korak ima default, activei completedržavu.
  • Može napredovati od koraka do koraka do završetka.

Ovdje pogledajte CodePen za primjer uživo.

HTML

Da bismo smanjili suvišnost i povećali mogućnost ponovne upotrebe, pratimo sva stanja u Vue komponenti. U DOM-u ovo dinamički generira bilo koji broj potrebnih koraka.

Napomena : Izvorni JavaScript (ECMAScript) ili bilo koji drugi okvir to mogu postići. Upotreba Vuea je u demonstrativne svrhe.

Traka napretka koristi osnovne oznake. Tamo je:

  • spremnik s izračunatim klasama na temelju trenutnog koraka: progressClasses
  • statična pozadinska staza: progress__bg
  • petlja koja se ponavlja kroz svaki korak i primjenjuje stepClassesna temelju trenutnog koraka.

Svaki korak ima:

  • a progress__indicatorkoja sadrži ikonu za provjeru koja je vidljiva ako je korak dovršen.
  • a progress__labelkoji sadrži tekst naljepnice za taj korak.
 {{step.label}} Back Next Step: {{currentStep ? currentStep.label : "Start"}} 

Radi jednostavnosti, progress__actionskoji kontroliraju smjer vožnje ugniježđeni su unutar same trake napretka.

CSS (SCSS)

Ovdje radimo dizanje teških tereta. Ovdje definirane klase JS će dinamički primijeniti na temelju trenutnog koraka.

Prvo, odaberite neke boje za rad:

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

Sada definirajte .progressklasu: spremnik koji zajedno sadrži sadržaj trake napretka.

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

Naša traka napretka treba .progress__bgda bi se koraci napretka pregazili poput staze. To će biti sivo, prekriveno obojenom trakom dok prelazi u sljedeći korak.

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

Svaki .progress__stepsadrži okrugli korak koji će istaknuti i ispuniti kako se traka napretka napreduje.

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

Sadrži i okrugli .progress__indicatortekst i tekst naljepnice .progress__label. Njihovi zadani stilovi definirani su izvan .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; }

Nastavimo se .progress__stepopet gnijezditi unutra i definirajmo korak u aktivnom stanju.

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

Zatim definirajte korak u njegovom cjelovitom stanju. Napomena : zadani stilovi za .progress__indicatori .progress__labelprepisuju se kada su u cjelovitom stanju.

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

Kao što je ranije spomenuto, to će se razlikovati ovisno o tome kako implementirate logiku koraka, širem kontekstu u kojem je implementiran, kojim okvirima i obrascima koristite itd.

Ovaj primjer koristi Vue komponentu da demonstrira:

  • izračun klasa za traku napretka na temelju trenutnog stanja.
  • izračun klasa za svaki korak na temelju trenutnog stanja.
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}` } } })

Zaključak

Na kraju svega imate ovo:

Pogledajte CodePen za primjer uživo.

Ako su vam moji članci korisni, razmislite o tome da postanete član mog Patreona :)

Ili ako mi samo želite kupiti kavu (volim kavu):