CSS Creare barra di complessità (progress bar)

SmartApp

Utente Gold
24 Aprile 2013
528
31
156
289
Ultima modifica:
Ciao a tutti,
vorrei creare una specie di progress bar per indicare una complessità che sia suddivisa in 3 e che cambi colore in base al riempimento.
Se la complessità è "Facile" dovrà essere verde e piena per 1/3, se è "Media" gialla e piena per 2/3 infine se "Difficile" rossa e completamente piena.

A prescindere dal valore, la barra deve avere delle "tacche" che sporgono un po' più dell'altezza del componente che indicano la divisione. Centrato sotto alla rispettiva sezione il testo della complessità colorando solo quello del valore raggiunto.

Il valore verrà dato in ingresso e non sarà modificabile dall'utente. E' una progress bar indicativa

Qualcuno è in grado di fare qualcosa? Sono un po' indietro con il CSS
L'intendo è di creare un component Angular da riutilizzare in varie parti di un progetto
 
Ciao, per le tacche potresti creare dei div e col css gli dai uno spessore di 1-2px, probabilmente devi visualizzarli al di sotto o sopra la progress bar, per poi spaziarli tra loro con margin o flex. Dovrei ragionarci un attimo. Se vuoi approfondire lo studio del css ti consiglio freecodecamp.org, è un ottimo sito con tutorial progressivi, dacci un occhio. Se usi angular comunque sviluppa un componente per tenere organizzato il codice. Con il javascript (o meglio typescript) poi colorerai le tacche, una volta raggiunta una certa percentuale immagino.
 
Il component Angular l'ho già creato e una versione base è già funzionante. Magari lato TS posso fare la gestione del colore in base al valore passato.
Mi rimane solo lo stile da applicare per rendere la barra accattivante con quei dettagli che ho descritto
 
Con non poche difficoltà sono riuscito ad ottenere qualcosa di piacevole che vada incontro alle mie necessità. Cosa ne pensate? Migliorereste qualcosa?

Schermata 2020-05-18 alle 09.46.20.png


Schermata 2020-05-18 alle 09.46.27.png
 
Mi dice che la box-shadow non può essere applicata (triangolino giallo nell'ispezione dell'elemento) su una progress, in questo caso sarebbe addirittura un ion-progress-bar, ma sotto c'è sempre una progress.

Per quel che riguarda le tacche andrebbero leggermente modificate magari arrotondando leggermente i bordi. Ora anche quando la progress non raggiunge la tacca questa ha il colore di opacità in modo da non essere grigia ma uniformandosi alla parte sottostante di barra.
Come pensi starebbero bene?
Da tenere conto che la barra non va mai sotto alla prima tacca, quindi di fatto solo la seconda cambia di colore. Le immagini mostrano già una situazione di minima e di massima
 
HTML:
<!DOCTYPE html>
<html lang="it" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
  </head>
  <body>
    <div class="skills">
      <div class="skill">
        <div class="skill-name">HTML</div>
        <div class="skill-bar">
          <div class="skill-per" per="90"></div>
        </div>
      </div>

      <div class="skill">
        <div class="skill-name">CSS</div>
        <div class="skill-bar">
          <div class="skill-per" per="70"></div>
        </div>
      </div>

      <div class="skill">
        <div class="skill-name">Javascript</div>
        <div class="skill-bar">
          <div class="skill-per" per="60"></div>
        </div>
      </div>
    </div>

    <script>
      $('.skill-per').each(function(){
        var $this = $(this);
        var per = $this.attr('per');
        $this.css("width",per+'%');
        $({animatedValue: 0}).animate({animatedValue: per},{
          duration: 1000,
          step: function(){
            $this.attr('per', Math.floor(this.animatedValue) + '%');
          },
          complete: function(){
            $this.attr('per', Math.floor(this.animatedValue) + '%');
          }
        });
      });
    </script>
    <style>
body{
  margin: 0;
  padding: 0;
  font-family: 'Open Sans',sans-serif;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #f1f1f1;
}

.skills{
  width: 100%;
  max-width: 600px;
  padding: 0 20px;
}

.skill-name{
  font-size: 18px;
  font-weight: 700;
  text-transform: uppercase;
  margin: 20px 0;
}

.skill-bar{
  height: 20px;
  background: #cacaca;
  border-radius: 8px;
}

.skill-per{
  height: 20px;
  background-color: #0fbcf9;
  border-radius: 8px;
  width: 0;
  transition: 1s linear;
  position: relative;
}

.skill-per::before{
  content: attr(per);
  position: absolute;
  padding: 4px 6px;
  background-color: #000;
  color: #fff;
  font-size: 12px;
  border-radius: 4px;
  top: -35px;
  right: 0;
  transform: translateX(50%);
}

.skill-per::after{
  content: '';
  position: absolute;
  width: 10px;
  height: 10px;
  background-color: #000;
  top: -16px;
  right: 0;
  transform: translateX(50%) rotate(45deg);
  border-radius: 2px;
}
    </style>
  </body>
</html>
 
HTML:
<!DOCTYPE html>
<html lang="it" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
  </head>
  <body>
    <div class="skills">
      <div class="skill">
        <div class="skill-name">HTML</div>
        <div class="skill-bar">
          <div class="skill-per" per="90"></div>
        </div>
      </div>

      <div class="skill">
        <div class="skill-name">CSS</div>
        <div class="skill-bar">
          <div class="skill-per" per="70"></div>
        </div>
      </div>

      <div class="skill">
        <div class="skill-name">Javascript</div>
        <div class="skill-bar">
          <div class="skill-per" per="60"></div>
        </div>
      </div>
    </div>

    <script>
      $('.skill-per').each(function(){
        var $this = $(this);
        var per = $this.attr('per');
        $this.css("width",per+'%');
        $({animatedValue: 0}).animate({animatedValue: per},{
          duration: 1000,
          step: function(){
            $this.attr('per', Math.floor(this.animatedValue) + '%');
          },
          complete: function(){
            $this.attr('per', Math.floor(this.animatedValue) + '%');
          }
        });
      });
    </script>
    <style>
body{
  margin: 0;
  padding: 0;
  font-family: 'Open Sans',sans-serif;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #f1f1f1;
}

.skills{
  width: 100%;
  max-width: 600px;
  padding: 0 20px;
}

.skill-name{
  font-size: 18px;
  font-weight: 700;
  text-transform: uppercase;
  margin: 20px 0;
}

.skill-bar{
  height: 20px;
  background: #cacaca;
  border-radius: 8px;
}

.skill-per{
  height: 20px;
  background-color: #0fbcf9;
  border-radius: 8px;
  width: 0;
  transition: 1s linear;
  position: relative;
}

.skill-per::before{
  content: attr(per);
  position: absolute;
  padding: 4px 6px;
  background-color: #000;
  color: #fff;
  font-size: 12px;
  border-radius: 4px;
  top: -35px;
  right: 0;
  transform: translateX(50%);
}

.skill-per::after{
  content: '';
  position: absolute;
  width: 10px;
  height: 10px;
  background-color: #000;
  top: -16px;
  right: 0;
  transform: translateX(50%) rotate(45deg);
  border-radius: 2px;
}
    </style>
  </body>
</html>
Ciao @orox , potresti dare un contesto più chiaro al tuo messaggio? Inoltre, quando devi postare lavori HTML da far vedere esteticamente, ti consiglio di utilizzare servizi online come CodePen o simili.
 
Ciao @orox , potresti dare un contesto più chiaro al tuo messaggio? Inoltre, quando devi postare lavori HTML da far vedere esteticamente, ti consiglio di utilizzare servizi online come CodePen o simili.
@Dazorn va bene, io evito link perché alcuni utenti potrebbero non fidarsi per questo ho sempre cercato di evitare però se mi dici che è meglio le prossime volte usrerò CodePen (che già usavo). comunque sono nuovo su questo forum mi devo ancora un abituare.
Grazie per il consiglio.