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