W3docs

Tag HTML <progress>

Il tag <progress> visualizza l'avanzamento di un'attività (barra di avanzamento). Esempi d'uso pratici.

Il tag <progress> è uno degli elementi HTML5. Rappresenta il progresso di completamento di un'attività — quanto di un'operazione (caricamento di file, download, passaggio di un modulo, installazione) è stato eseguito finora. Il browser disegna una barra di avanzamento il cui riempimento riflette il valore di value rispetto a max.

Poiché <progress> descrive solo quanto si è avanzati, i valori effettivi cambiano solitamente in fase di esecuzione. Li si aggiorna con JavaScript (vedere l'esempio dinamico qui sotto). L'aspetto esatto dell'elemento varia a seconda del browser e del sistema operativo.

<progress> vs <meter>

Questi due elementi hanno un aspetto simile ma significati diversi — scegli in base all'intento, non all'aspetto:

Usa <progress> quando…Usa <meter> quando…
Vuoi mostrare quanto è completa un'attività (si muove verso il completamento).Vuoi mostrare una misurazione statica all'interno di un intervallo noto, come l'utilizzo del disco, un punteggio o la rilevanza di un risultato di ricerca.
Il valore cresce naturalmente da 0 a max nel tempo.Il valore si trova in un punto di una scala fissa e non è "in corso".

Una regola pratica: se puoi completarlo, usa <progress>. Se stai solo misurando un livello, usa <meter>.

Sintassi

Il tag <progress> funziona in coppia. Il contenuto è scritto tra il tag di apertura (<progress>) e quello di chiusura (</progress>).

Esempio del tag HTML <progress>:

Tag HTML <progress>

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
  </head>
  <body>
    <label for="file">Loading:</label>
    <progress id="file" value="35" max="100">35%</progress>
  </body>
</html>

Risultato

progress tag example

Il testo tra i tag (35% nell'esempio) è il contenuto di fallback: i browser che supportano <progress> lo ignorano e disegnano la barra, mentre i browser molto vecchi che non riconoscono l'elemento visualizzano il testo al suo posto. È buona norma tenerlo sincronizzato con il valore corrente.

Accessibilità: aggiungi sempre un'etichetta alla barra di avanzamento

Una barra <progress> senza etichetta viene annunciata dagli screen reader come percentuale priva di contesto — "35 percent" non dice all'utente nulla su cosa si stia caricando. Fornisci un nome accessibile in uno di questi modi:

  • Un <label> il cui for corrisponde all'id della barra (come sopra). Fare clic sull'etichetta è anche una comodità apprezzata.
  • aria-labelledby che punta all'id di un testo visibile.
  • aria-label="…" quando non c'è testo visibile a cui fare riferimento.
<!-- Visible label referenced by the bar -->
<span id="upload-status">Uploading photos</span>
<progress aria-labelledby="upload-status" value="60" max="100">60%</progress>

<!-- No visible text? Use aria-label -->
<progress aria-label="Uploading photos" value="60" max="100">60%</progress>

Determinata vs indeterminata

Una barra di avanzamento può essere determinata o indeterminata.

  • Determinata — sai quanto è avanzata l'attività, quindi fornisci un value. La barra si riempie proporzionalmente (value ÷ max).
  • Indeterminata — sai che l'attività è in esecuzione ma non quanto rimane, quindi ometti l'attributo value. Il browser mostra una barra "di attività" animata (una striscia in movimento o un impulso) al posto di un riempimento fisso.

Esempio indeterminato

Ometti value per ottenere lo stato indeterminato, poi impostalo non appena conosci il numero reale:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
  </head>
  <body>
    <label for="task">Working:</label>
    <!-- No value attribute → indeterminate (animated) -->
    <progress id="task" max="100">Working…</progress>
  </body>
</html>

Questo è ideale mentre aspetti una risposta dal server e non puoi ancora calcolare una percentuale. Non appena puoi, passa lo stesso elemento allo stato determinato impostando value tramite JavaScript (progress.value = 40).

Stile della barra determinata vs indeterminata

È più facile applicare stili alla barra indeterminata, poiché non ha l'attributo value — puoi selezionarla con il selettore di negazione CSS progress:not([value]).

La barra determinata viene selezionata con il selettore progress[value]. Aggiungi le dimensioni con le proprietà CSS width e height e imposta appearance su none:

Stile delle barre di avanzamento

Il modo moderno e semplice: accent-color

Nella maggior parte dei casi non hai più bisogno di prefissi vendor o pseudo-elementi. Imposta la proprietà CSS accent-color e tutti i browser moderni colorano la barra in modo coerente con una sola riga:

progress {
  accent-color: #2563eb; /* color of the filled portion */
  width: 200px;
}

Ricorri ai pseudo-elementi con prefisso descritti sotto solo quando hai bisogno di pieno controllo sulla traccia, gradienti personalizzati, o devi supportare motori più vecchi.

Chrome, Safari e le versioni più recenti di Opera (16+) appartengono a questa categoria. Lo stile dell'aspetto dell'elemento <progress> può essere impostato usando -webkit-appearance: progress-bar.

Imposta -webkit-appearance: none; per ripristinare gli stili predefiniti.

Esempio di una barra di avanzamento

progress[value] {
  -webkit-appearance: none;
  appearance: none;
  width: 200px;
  height: 15px;
}

Esempio dello stato determinato della barra di avanzamento:

Esempio di una barra di avanzamento determinata:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      progress[value] {
        -webkit-appearance: none;
        appearance: none;
        width: 200px;
        height: 15px;
      }
    </style>
  </head>
  <body>
    <label for="file">Loading:</label>
    <progress id="file" value="30" max="100">30%</progress>
  </body>
</html>

Dopo questo, potresti riscontrare problemi perché diversi browser forniscono pseudo-elementi separati per lo stile della barra di avanzamento. Per risolvere questo problema, puoi usare dei fallback.

WebKit/Blink fornisce due pseudo-elementi:

  • ::-webkit-progress-bar, che applica stili al contenitore dell'elemento progress.
  • ::-webkit-progress-value, che applica stili al valore all'interno della barra di avanzamento.

Applica stili a ::-webkit-progress-bar con diverse proprietà CSS:

Esempio di una barra di avanzamento

progress[value]::-webkit-progress-bar {
  background-color: #eee;
  border-radius: 2px;
  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.26) inset;
}

Applica stili a ::-webkit-progress-value, che è la stessa cosa della barra, con diversi sfondi a gradiente per scopi diversi. Usa il prefisso -webkit- per i gradienti:

webkit-progress-value

progress[value]::-webkit-progress-value {
  background-image: -webkit-linear-gradient(-45deg, transparent 33%, rgba(0, 0, 0, .2) 33%, rgba(0, 0, 0, .2) 66%, transparent 66%), -webkit-linear-gradient(top, rgba(255, 255, 255, .25), rgba(0, 0, 0, .25)), -webkit-linear-gradient(left, #1000ff, #359900);
  border-radius: 4px;
  background-size: 20px 15px, 100% 100%, 100% 100%;
}

Esempio del tag HTML <progress> usato con proprietà CSS:

Esempio del tag HTML <progress> con proprietà CSS:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      progress[value] {
        -webkit-appearance: none;
        appearance: none;
        width: 200px;
        height: 15px;
      }
      progress[value]::-webkit-progress-bar {
        background-color: #cccccc;
        border-radius: 4px;
      }
      progress[value]::-webkit-progress-value {
        background-image: -webkit-linear-gradient(-45deg, transparent 33%, rgba(0, 0, 0, .2) 33%, rgba(0, 0, 0, .2) 66%, transparent 66%), -webkit-linear-gradient(top, rgba(255, 255, 255, .25), rgba(0, 0, 0, .25)), -webkit-linear-gradient(left, #1000ff, #359900);
        border-radius: 4px;
        background-size: 20px 15px, 100% 100%, 100% 100%;
      }
    </style>
  </head>
  <body>
    <span>Loading:</span>
    <progress value="55" max="100" aria-label="Loading progress"></progress>
  </body>
</html>

Firefox

Usando appearance: none possiamo rimuovere il bordo in rilievo predefinito. Tuttavia, in Firefox rimane un sottile bordo che può essere rimosso con border: none. Questo risolve anche il problema del bordo in Opera 12.

Esempio della barra <progress> su Firefox

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      progress[value] {
        -webkit-appearance: none;
        -moz-appearance: none;
        appearance: none;
        border: none;
        width: 200px;
        height: 15px;
      }
    </style>
  </head>
  <body>
    <span>Loading:</span>
    <progress value="55" max="100" aria-label="Loading progress"></progress>
  </body>
</html>

Firefox fornisce un singolo pseudo-elemento (::-moz-progress-bar) che può essere usato per selezionare il valore della barra di avanzamento. In altre parole, non è possibile applicare stili allo sfondo del contenitore in Firefox.

Tag HTML <progress> - Firefox

progress[value]::-moz-progress-bar {
  background-image: -moz-linear-gradient( 135deg, transparent 33%, rgba(0, 0, 0, 0.1) 33%, rgba(0, 0, 0, 0.1) 66%, transparent 66%), -moz-linear-gradient( top, rgba(255, 255, 255, 0.25), rgba(0, 0, 0, 0.25)), -moz-linear-gradient( left, #ff00f7, #4e922a);
  background-size: 35px 20px, 100% 100%, 100% 100%;
}

Firefox non supporta gli pseudo-elementi ::before o ::after sulla barra di avanzamento, e non permette l'animazione CSS3 con keyframe sulla barra di avanzamento, il che limita le possibilità di personalizzazione.

Esempio del tag HTML <progress> per Firefox:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      progress[value]::-moz-progress-bar {
        background-image: -moz-linear-gradient( 135deg, transparent 33%, rgba(0, 0, 0, 0.1) 33%, 
                          rgba(0, 0, 0, 0.1) 66%, transparent 66%), 
                          -moz-linear-gradient( top, rgba(255, 255, 255, 0.25), 
                          rgba(0, 0, 0, 0.25)),
                          -moz-linear-gradient( left, #ff00f7, #4e922a);
        background-size: 35px 20px, 100% 100%, 100% 100%;
      }
    </style>
  </head>
  <body>
    <span>Loading:</span>
    <progress value="35" max="100" aria-label="Loading progress"></progress>
  </body>
</html>

Aggiornare una barra di avanzamento con JavaScript

Poiché un elemento <progress> reale espone una proprietà value, si aggiorna la barra semplicemente assegnandole un numero — il browser ridisegna il riempimento automaticamente. Qui un timer simula un download che avanza da 0 a 100, poi si ferma:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
  </head>
  <body>
    <label for="download">Downloading:</label>
    <progress id="download" value="0" max="100">0%</progress>
    <span id="status">0%</span>

    <script>
      var bar = document.getElementById("download");
      var status = document.getElementById("status");
      var loaded = 0;

      var timer = setInterval(function () {
        loaded += 5;
        bar.value = loaded;          // moves the bar
        status.textContent = loaded + "%";
        if (loaded >= bar.max) {
          clearInterval(timer);
        }
      }, 300);
    </script>
  </body>
</html>

Per passare una barra dallo stato indeterminato a quello determinato in fase di esecuzione, imposta il suo value non appena conosci il numero reale (bar.value = 40). Per tornare allo stato indeterminato, rimuovi l'attributo con bar.removeAttribute("value").

Barra di avanzamento scroll (alternativa solo CSS)

L'elemento qui sotto è costruito con <div> stilizzati, non un elemento <progress> reale. È un pattern comune per un indicatore di scorrimento della pagina in cui si vuole il controllo totale sull'aspetto. Se si preferisce un elemento semantico, si potrebbe sostituire il <div> con un <progress> e aggiornarne il value nell'handler dello scroll.

Ecco come creare una barra che mostra quanto si è scorsi nella pagina:

esempio di come creare una barra di avanzamento che mostra quanto si è scorsi nella pagina

<!DOCTYPE html>
<html>
  <head>
    <style>
      #progress-bar {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 5px;
        background-color: #ddd;
      }

      #progress-bar-fill {
        height: 100%;
        background-color: blue;
        width: 0%;
      }
    </style>
  </head>
  <body>
    <div id="progress-bar">
      <div id="progress-bar-fill"></div>
    </div>

    <h1>Scrollable Content</h1>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed auctor quam non felis interdum pellentesque. Suspendisse potenti. Nullam molestie neque in justo consectetur, sit amet varius arcu malesuada. Fusce sed laoreet ipsum. Nulla
      facilisi. Donec eleifend auctor purus, eu bibendum risus facilisis sit amet.
    </p>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed auctor quam non felis interdum pellentesque. Suspendisse potenti. Nullam molestie neque in justo consectetur, sit amet varius arcu malesuada. Fusce sed laoreet ipsum. Nulla
      facilisi. Donec eleifend auctor purus, eu bibendum risus facilisis sit amet.
    </p>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed auctor quam non felis interdum pellentesque. Suspendisse potenti. Nullam molestie neque in justo consectetur, sit amet varius arcu malesuada. Fusce sed laoreet ipsum. Nulla
      facilisi. Donec eleifend auctor purus, eu bibendum risus facilisis sit amet.
    </p>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed auctor quam non felis interdum pellentesque. Suspendisse potenti. Nullam molestie neque in justo consectetur, sit amet varius arcu malesuada. Fusce sed laoreet ipsum. Nulla
      facilisi. Donec eleifend auctor purus, eu bibendum risus facilisis sit amet.
    </p>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed auctor quam non felis interdum pellentesque. Suspendisse potenti. Nullam molestie neque in justo consectetur, sit amet varius arcu malesuada. Fusce sed laoreet ipsum. Nulla
      facilisi. Donec eleifend auctor purus, eu bibendum risus facilisis sit amet.
    </p>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed auctor quam non felis interdum pellentesque. Suspendisse potenti. Nullam molestie neque in justo consectetur, sit amet varius arcu malesuada. Fusce sed laoreet ipsum. Nulla
      facilisi. Donec eleifend auctor purus, eu bibendum risus facilisis sit amet.
    </p>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed auctor quam non felis interdum pellentesque. Suspendisse potenti. Nullam molestie neque in justo consectetur, sit amet varius arcu malesuada. Fusce sed laoreet ipsum. Nulla
      facilisi. Donec eleifend auctor purus, eu bibendum risus facilisis sit amet.
    </p>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed auctor quam non felis interdum pellentesque. Suspendisse potenti. Nullam molestie neque in justo consectetur, sit amet varius arcu malesuada. Fusce sed laoreet ipsum. Nulla
      facilisi. Donec eleifend auctor purus, eu bibendum risus facilisis sit amet.
    </p>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed auctor quam non felis interdum pellentesque. Suspendisse potenti. Nullam molestie neque in justo consectetur, sit amet varius arcu malesuada. Fusce sed laoreet ipsum. Nulla
      facilisi. Donec eleifend auctor purus, eu bibendum risus facilisis sit amet.
    </p>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed auctor quam non felis interdum pellentesque. Suspendisse potenti. Nullam molestie neque in justo consectetur, sit amet varius arcu malesuada. Fusce sed laoreet ipsum. Nulla
      facilisi. Donec eleifend auctor purus, eu bibendum risus facilisis sit amet.
    </p>

    <script>
      window.addEventListener("scroll", function () {
        var progressBarFill = document.getElementById("progress-bar-fill");
        var scrollPosition = window.scrollY;
        var totalHeight = document.body.scrollHeight - window.innerHeight;
        var percentage = (scrollPosition / totalHeight) * 100;
        progressBarFill.style.width = percentage + "%";
      });
    </script>
  </body>
</html>

In questo esempio, abbiamo un div con posizione fissa e un id di progress-bar che funge da contenitore. Al suo interno, un altro div con id di progress-bar-fill funge da riempimento in movimento. (Poiché si tratta di un indicatore di scorrimento decorativo e non di un'attività, un semplice <div> è accettabile qui; un vero <progress> funzionerebbe altrettanto bene se si impostasse il suo value nello stesso handler.)

Abbiamo usato CSS per impostare la larghezza e l'altezza iniziali della barra di avanzamento, così come i colori di sfondo per la barra di avanzamento e il suo riempimento.

Abbiamo anche incluso un event listener JavaScript che ascolta l'evento scroll sull'oggetto window. Quando l'utente scorre la pagina, calcoliamo la posizione dello scroll e l'altezza totale della pagina, quindi calcoliamo la percentuale della pagina scorsa. Aggiorniamo la proprietà width dell'elemento progress-bar-fill per riflettere questa percentuale, aggiornando così la barra di avanzamento.

Puoi copiare questo codice in un nuovo file HTML e aprirlo nel browser per vedere come appare. Man mano che scorri la pagina, la barra di avanzamento si aggiornerà per riflettere quanto hai scorso. Puoi regolare l'altezza e il colore della barra di avanzamento in base alle tue esigenze.

Attributi

AttributoValoreDescrizione
maxnumberDefinisce il valore massimo del processo corrente. Il valore può essere un numero positivo maggiore di 0.
valuenumberDefinisce la dimensione dell'attività completata. Il valore può essere un numero da 0 al numero indicato nell'attributo max, oppure un numero nell'intervallo da 0 a 1 se l'attributo max non è specificato.

Il tag <progress> supporta anche gli Attributi Globali e gli Attributi Evento.

Esercizio

Pratica
Cosa rappresenta il tag HTML progress?
Cosa rappresenta il tag HTML progress?
Was this page helpful?