Réaliser des barres de progression avec CSS 3

Réaliser des barres de progression avec CSS 3

30/12/2013

Pas​‌‍​‌​‌‍​‍ toujours facile de réaliser des barres de progression avec HTML et CSS. Les barres horizontales sont relativement simples à réaliser mais les barres verticales et circulaires c’est une autre histoire et ça se termine généralement en JS avec un canvas.

Il existe d’autres solutions plus simples et plus rapides avec CSS3. Je sais bien que dans 60% des cas les clients voudront une compatibilité avec les navigateurs d’antan, c’est un point que je ne traiterais pas de ce tutoriel.

Dans ce tutoriel nous allons utiliser LESS de manière à nous simplifier la tâche. Si vous ne connaissez pas je vous recommande de commencer par lire . Nous allons voir comment réaliser une barre de progression horizontale, vertical puis finalement circulaire en utilisant uniquement du CSS3. Le tutoriel n’utilise pas la notation préfixé, libre à vous des ajoutés en fonction de vos besoins ou en utilisant Prefixr.

Les connaissances requises pour pouvoir suivre ce tutoriel sont :

  • Notions de base en HTML et CSS
  • Quelques connaissances de la syntaxe LESS

Une barre de progression horizontale

La manière la plus simple de procéder serait de mettre un bloc dans un autre bloc et de définir une longueur relative au bloc interne pour obtenir une barre de progression. Cette méthode est compatible avec tous types de navigateurs mais ce n’est pas celle que je vais utiliser dans ce tutoriel.

Nous allons utiliser les fonctions de gradient disponibles dans CSS3. Nous allons donc commencer par créer un template HorizontalProgressBar dans notre fichier style.less qui prendra en paramètre le pourcentage, la hauteur de la barre de progression, les couleurs des parties actives et passives de celle-ci. Le template ce défini de la manière suivante :

1
2
3
4
.HorizontalProgressBar(@percent, @height:25px, @color:#61c419, @color2:#FFF)
when (ispercentage(@percent)) and (ispixel(@height)) and (iscolor(@color)) and (iscolor(@color2)) {
height : @height;
}

Nous allons maintenant placer les couleurs dans la barre sous la forme d’un gradient bicolore de la manière suivante :

1
2
3
4
5
.HorizontalProgressBar(@percent, @height:25px, @color:#61c419, @color2:#FFF)
when (ispercentage(@percent)) and (ispixel(@height)) and (iscolor(@color)) and (iscolor(@color2)) {
height : @height;
background-image: linear-gradient(90deg, @color @percent, @color2 @percent, @color2);
}

Maintenant nous allons appeler ce template dans une classe de manière à pouvoir le tester dans un fichier HTML.

1
2
3
.horizontal-progress-50{
.HorizontalProgressBar(50%);
}
1
2
3
4
5
6
7
8
9
<html>
<head>
<link rel=”stylesheet/less” type=”text/css” href=”style.less” />
<script src=”less.js” type=”text/javascript”></script>
</head>
<body>
<div class=”horizontal-progress-50”></div>
</body>
</html>

Voilà, nous avons réalisé et affiché une barre de progression horizontale.

Barre de progression verticale

Pour la barre de progression verticale, le principe est sensiblement le même sauf que l’on retire la rotation de 90 degrés et qu’il nous faut un paramètre supplémentaire pour définir la largeur de la barre.

1
2
3
4
5
6
.VerticalProgressBar(@percent, @height:100px, @width:25px, @color:#61c419, @color2:#FFF)
when (ispercentage(@percent)) and (ispixel(@height)) and (ispixel(@width)) and (iscolor(@color)) and (iscolor(@color2)) {
height : @height;
width: @width;
background-image: linear-gradient(0deg, @color @percent, @color2 @percent, @color2);
}

Comme précédemment, on crée une classe avec le template VerticalProgressBar et on l’ajoute dans notre HTML pour apprécier le résultat.

1
2
3
.vertical-progress-50{
. VerticalProgressBar(50%);
}
1
2
3
4
5
6
7
8
9
10
<html>
<head>
<link rel=”stylesheet/less” type=”text/css” href=”style.less” />
<script src=”less.js” type=”text/javascript”></script>
</head>
<body>
<div class=”horizontal-progress-50”></div>
<div class=”vertical-progress-50”></div>
</body>
</html>

Barre de progression circulaire

Nous voilà maintenant arrivés au point le plus épineux de ce tutoriel, les barres de progression circulaire ne semblent pas simples à mettre en place, mais là encore CSS3 est plein de réserve. Comme nous l’avons déjà vue dans les parties précédentes, il est possible d’appliquer un angle à un dégradé.

Nous aurons donc trois cas à traiter, les barres inférieures à 50%, celles strictement égales à 50% et enfin celles supérieures à 50%. Pour cela nous allons créer trois templates du même nom mais avec une précondition différente.

Pour rendre notre carré rond nous allons lui appliquer une autre règle CSS3 nommé border-radius permettant d’arrondir les coins.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.CircularProgressBar(@percent, @size:100px, @color:#61c419, @color2:#FFF, @margin:0px)
when (ispercentage(@percent)) and (ispixel(@size)) and (iscolor(@color)) and (iscolor(@color2)) and (@percent < 50%) {
height: @size;
width: @size;
border-radius: 50%;
}
.CircularProgressBar(@percent, @size:100px, @color:#61c419, @color2:#FFF, @margin:0px)
when (ispercentage(@percent)) and (ispixel(@size)) and (iscolor(@color)) and (iscolor(@color2)) and (@percent = 50%) {
height: @size;
width: @size;
border-radius: 50%;
}
.CircularProgressBar(@percent, @size:100px, @color:#61c419, @color2:#FFF, @margin:0px)
when (ispercentage(@percent)) and (ispixel(@size)) and (iscolor(@color)) and (iscolor(@color2)) and (@percent > 50%) {
height: @size;
width: @size;
border-radius: 50%;
}

Le cas du 50% est le plus simple à gérer car seule la partie de droite sera colorée. On le représente donc de la même manière qu’une barre de progression horizontale en inversant les couleurs.

1
2
3
4
5
6
7
.CircularProgressBar(@percent, @size:100px, @color:#61c419, @color2:#FFF, @margin:0px)
when (ispercentage(@percent)) and (ispixel(@size)) and (iscolor(@color)) and (iscolor(@color2)) and (@percent = 50%) {
height: @size;
width: @size;
background-image: linear-gradient(90deg, @color2 50%, @color 50%, @color);
border-radius: 50%;
}

CSS3 permet de superposer les calques, c’est-à-dire de mettre plusieurs couches de background. Nous allons donc avoir une couche avec un angle correspondant un pourcentage passé en paramètres plus une seconde qui définira si les 50% ont étés passés ou non.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.CircularProgressBar(@percent, @size:100px, @color:#61c419, @color2:#FFF, @margin:0px)
when (ispercentage(@percent)) and (ispixel(@size)) and (iscolor(@color)) and (iscolor(@color2)) and (@percent < 50%) {
height: @size;
width: @size;
background-image: linear-gradient(90deg, @color2 50%, transparent 50%, transparent), linear-gradient((((unit(@percent, deg)/100)360)+90), @color 50%, @color2 50%, @color2);
border-radius: 50%;
}
.CircularProgressBar(@percent, @size:100px, @color:#61c419, @color2:#FFF, @margin:0px)
when (ispercentage(@percent)) and (ispixel(@size)) and (iscolor(@color)) and (iscolor(@color2)) and (@percent > 50%) {
height: @size;
width: @size;
background-image: linear-gradient( (((unit(@percent, deg)/100)360)+90), @color 50%, transparent 50%, transparent), linear-gradient(90deg, @color2 50%, @color 50%, @color);
border-radius: 50%;
}

Une fois encore on implémente dans une classe et on test.

1
2
3
4
5
6
7
8
9
.circular-progress-50{
.CircularProgressBar(50%);
}
.circular-progress-80{
.CircularProgressBar(80%);
}
.circular-progress-15{
.CircularProgressBar(15%);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
<html>
<head>
<link rel=”stylesheet/less” type=”text/css” href=”style.less” />
<script src=”less.js” type=”text/javascript”></script>
</head>
<body>
<div class=”horizontal-progress-50”></div>
<div class=”vertical-progress-50”></div>
<div class=”circular-progress-15”></div>
<div class=”circular-progress-50”></div>
<div class=”circular-progress-80”></div>
</body>
</html>