Démos

Toutes les démos

<>

Couverture du livre CSS3 Le design web moderne

Livre CSS3

Le design web moderne

Plus d'infos sur le site officiel

En vente sur Amazon, FNAC, Dunod

Suivre

Actualités du site CSS3Create

Actualités sur CSS et le web en général

Barre de progression avec l’élément HTML5 <progress>

Styler en CSS une barre de progression

Création: septembre 2012Modifié:

Retrieving data...0%

0%
Contenu
Full CSS Pas d’images Avec JavaScript
Navigateurs
Firefox Chrome
Partagez
Facebook Twitter

Votez

114 votes4.52

Étude de cas pour mettre en forme via CSS les nouveaux éléments de formulaire HTML5 <progress> et <meter>. Le W3C ne définit encore aucune spécification.

Cet article n’est qu’une étude de cas puisque qu’à l’heure actuelle (septembre 2012), il n’existe aucune spécification W3C définissant la mise en forme des éléments <progress> ou <meter>. Cependant, certains navigateurs ont implémenté des pseudo-éléments/pseudo-classes permettant de mettre en forme ces éléments. Nous allons dons les tester. Mais attention, ces techniques ne sont pas pérennes et sont à prendre à titre expérimental. De plus, le rendu par défaut de ces éléments diffère d’un navigateur à l’autre et d’un OS à l’autre.

Les éléments de base

Commençons tout d’abord par le HTML utile. Un balisage simple entoure notre élément <progress>, lequel reçoit 3 attributs : value, min et max.

<div id="progress">
   <p>Retrieving data...<strong>0%</strong></p>
   <progress value="5" min="0" max="100">0%</progress>
</div>

Nous ajoutons à ce code quelques CSS de base :

#progress{
   width: 300px;
   margin: auto;
}
progress{
   display: inline-block;
   -moz-box-sizing: border-box;
        box-sizing: border-box;
   width: 300px;
   height: 20px;
   padding: 3px 3px 2px 3px;
   background: #333;
   background: -webkit-linear-gradient(#2d2d2d,#444);
   background:    -moz-linear-gradient(#2d2d2d,#444);
   background:      -o-linear-gradient(#2d2d2d,#444);
   background:         linear-gradient(#2d2d2d,#444);
   border: 1px solid rgba(0,0,0,.5);
   border-radius: 15px;
   box-shadow: 0 1px 0 rgba(255,255,255,.2);  
}

Cibler précisément avec les pseudo-éléments

Pour l’élément <progress>, il existe donc un (ou deux) pseudo-éléments. En fait, il en existe un pour Firefox, et deux pour Chrome. Ce sont :

  • ::-moz-progress-bar : la barre de progression
  • ::-webkit-progress-bar : le conteneur de la barre de progression
  • ::-webkit-progress-value : la barre de progression

Les deux approches peuvent se comprendre, mais pour nous, il va nous falloir dupliquer notre code. Cela nous donne donc :

/* Style de la barre pour Firefox*/
progress::-moz-progress-bar{
   border-radius:10px;
   background: #09c;
   background:
     -moz-repeating-linear-gradient(
       45deg,
       rgba(255,255,255,.2) 0,
       rgba(255,255,255,.2) 10px,
       rgba(255,255,255,0) 10px,
       rgba(255,255,255,0) 20px
     ),
     -moz-linear-gradient(
       rgba(255,255,255,.1) 50%,
       rgba(255,255,255,0) 60%
     ),
     #09c;
   background:
     repeating-linear-gradient(
       45deg,
       rgba(255,255,255,.2) 0,
       rgba(255,255,255,.2) 10px,
       rgba(255,255,255,0) 10px,
       rgba(255,255,255,0) 20px
     ),
     linear-gradient(
       rgba(255,255,255,.1) 50%,
       rgba(255,255,255,0) 60%
     ),
     #09c;
   background-size: 300px 20px, auto, auto;
   background-position: -300px 0, top, top;
   background-position: top right, top, top;
   box-shadow: 0 1px 0 rgba(255,255,255,.5) inset,
               0 -1px 0 rgba(0,0,0,.8) inset,
               0 0 2px black;
 
}

/* Style de la barre pour Chrome*/
progress::-webkit-progress-value{
 
   /* Code identique mais avec les bons préfixes! */

}

Nous avons donc le premier bloc (progress::-moz-progress-bar) et le second (progress::-webkit-progress-value) qui ciblent la barre. Dans Webkit (Chrome), il nous faut ôter la couleur de fond du conteneur de la barre (progress::-webkit-progress-bar) :

/* Enlève la couleur d'arrière-plan */
progress::-webkit-progress-bar{
   background: transparent;
}

Animer la barre de progression

La barre de progression est un élément de formulaire automatiquement créée grâce à ses attributs, notamment value. C’est pourquoi, il n’est pas possible de modifier cet attribut par CSS (en tout cas pour l’instant...).

Pour l’animation créée ici, le JavaScript est donc indispensable. Le code utilisé est le suivant (nécessite jQuery). Une simple fonction qui récupère la valeur de value et l’incrémente de 0.25 toutes les 40ms.

function modifValues(){
   var val = $('#progress progress').attr('value');
   if(val>=100){val=5;}
   var newVal = val*1+0.25;
   var txt = Math.floor(newVal)+'%';      
     
   $('#progress progress').attr('value',newVal).text(txt);
   $('#progress strong').html(txt);
}
setInterval(function(){ modifValues(); },40);

Dégradation gracieuse

Nous obtenons donc quelque chose de très similaire dans ces 2 navigateurs. Mais qu’en est-il des autres ?

  • Safari ne supporte ni <progress>, ni <meter>
  • Opéra 11+ les supporte mais il n’existe aucun moyen de les personnaliser. Par défaut, les barres de progression sont vertes (et ce sur tous les OS).
  • Internet Explorer 10+ les supporte également sans personnalisation. Cependant, la valeur de color est utilisée pour l’arrière-plan de la barre de progression. Il n’est donc pas possible d’y inclure de dégradé, ni d’image.
  • Sans oublier les navigateurs plus anciens

Malgré ces limitations, il est envisageable de simuler les barres de progression, soit grâce au polyfill de Lea Verou ou plus simplement, en stylant un élément qui se base sur la valeur de value.

Pour cela, ajoutons un élément au sein de <progress>. Celui-ci n’est affiché que si l’élément <progress> n’est pas supporté. Ici, c’est un <span>.

<div id="progress">
   <p>Retrieving data...<strong>0%</strong></p>
   <progress value="5" min="0" max="100"><span></span></progress>
</div>

Ensuite, cet élément est stylé par rapport à la valeur de value, de cette façon :

progress[value='100'] span{
   width: 100%;
}
progress[value^='9']:not([value^='9.']):not([value='9']) span{
   width: 95%;
}
progress[value^='8']:not([value^='8.']):not([value='8']) span{
   width: 85%;
}
progress[value^='7']:not([value^='7.']):not([value='7']) span{
   width: 75%;
}
progress[value^='6']:not([value^='6.']):not([value='6']) span{
   width: 65%;
}
progress[value^='5']:not([value^='5.']):not([value='5']) span{
   width: 55%;
}
progress[value^='4']:not([value^='4.']):not([value='4']) span{
   width: 45%;
}
progress[value^='3']:not([value^='3.']):not([value='3']) span{
   width: 35%;
}
progress[value^='2']:not([value^='2.']):not([value='2']) span{
   width: 25%;
}
progress[value^='1']:not([value^='1.']):not([value='1']):not([value='100']) span{
   width: 15%;
}

Chaque bloc se lit de cette façon : élément <span>, contenu dans un élément <progress> dont l’attribut value commence par ’N’, mais qui n’est pas ’N’, ni ’N.’ (chiffres à virgule).

Avec cette syntaxe, nous pouvons cibler la valeur de 10 à 19, puis de 20 à 29, et ainsi de suite...

Enfin, l’ajout de transitions CSS permet de simuler une progression dynamique :

progress span{
-webkit-transition: width 1.6s linear;
   -moz-transition: width 1.6s linear;
     -o-transition: width 1.6s linear;
        transition: width 1.6s linear;
}

Bien entendu, pour les navigateurs encore plus ancien, l’utilisation d’un polyfill est nécessaire, ou alors le contenu textuel de progression doit toujours rester présent.

Les autres pseudo-éléments/pseudo-classes

D’autres pseudo-éléments/pseudo- classes sont disponibles et s’appliquent à l’élément <meter>. C’est le cas de :

  • :-moz-meter-optimum, :-moz-meter-sub-optimum et :-moz-meter-sub-sub-optimum
  • ::-webkit-meter-optimum-value, ::-webkit-meter-suboptimum-value et ::-webkit-meter-even-less-good-value

Coté standard, les pseudo-classes définies dans le module User Interface ne s’appliquent pas (encore ?) à ces éléments, sauf :indeterminate. Cette pseudo-classe permet de mettre en forme un élément dont l’attribut value n’est pas conforme ou non présent.

Conclusion

Si vous souhaitez approfondir le sujet, bien que ce soit encore non homogène, voici quelques liens intéressants :

Une suggestion ? Une amélioration ? Parlez-en sur le forum...

Envie d'une nouvelle démo?

Un p'tit mot...

#1par titi951, le 30 septembre 2012

Dommage, il faut utiliser du JS...

#2par Mamadelrey, le 1er octobre 2012

Très sympa étant débutant ceci m’a permis de voir de nouvelle fonction et aussi de voir que le rendu est totalement différent suivant les navigateurs.

En passant fonctionne très bien sous Opera avec une belle (ou pas) barre de progression verte ^^

#3par css3create, le 2 octobre 2012

@titi951 : Oui c’est normal. La balise <progress> symbolise la progression d’une tâche, au sein d’une application web par exemple. la mise à jour de la valeur doit se faire via un langage de programmation d’où le JavaScript ici. CSS n’est là que pour la mise en forme de l’élément.

#4par Tijs Verwest, le 30 janvier 2013

Bravo encore une fois, ça prouve que le CSS3 est trés puissant et qu’on peut faire avec pleine de chose et qu’il est l’avenir du design web par contre IE qui refuse toujours de respecter le standard W3C, et je sais pas pourquoi sinon merci beaucoup est bon courage pour la suite des tutos :)

#5par bluewind, le 8 juin 2013

@Tijs Verwest : a partir de IE9, les standards W3C et le CSS3 sont entierement respectés

#6par Darkhan, le 22 septembre 2013

J’ai la belle barre bleue CSS mais elle ne bouge pas elle reste fixe . Je n’arrive pas a faire marche le JS ... Si il faut jQuery je ne sait pas comment on le met .
Help Please

#7par JinzoR, le 23 octobre 2013

Salut ! Merci pour cet exemple, je note juste que IE 10 & 11 supportent l’élément progress (avec un style par défaut assez jolie d’ailleurs, pour une fois...)

#8par JinzoR, le 23 octobre 2013

Woops ! Je n’avais pas lu "Internet Explorer 10+ les supporte également sans personnalisation"... Autant pour moi ;)


modération à priori

Ce forum est modéré à priori : votre contribution n'apparaîtra qu'après avoir été validée par un administrateur du site.

Un message, un commentaire ?
    Qui êtes-vous ? (optionnel)
  • (Pour créer des paragraphes, laissez simplement des lignes vides.)