Niveau : Confirmé

Des statistiques graphiques grâce aux CSS

Fans des statistiques en tout genre, mais plutôt fainéants en ce qui concerne leur réalisation picturale, voici une solution basée sur les feuilles de style CSS pour mettre en valeur de façon élégante et simple diverses données à présenter.

Tutoriel par (Intégrateur du Dimanche, Strasbourg)
Créé le , mis à jour le (33335 lectures)
Tags : css, statistique

Avertissement

Cette technique exploitant CSS est à la frontière entre présentation et génération d'un pseudo-contenu, elle rencontre cependant des limites :

  • D'accessibilité : elle peut, selon le contexte où se trouvent les données chiffrées, invalider le critère d'accessibilité WCAG1.0 de niveau AAA 14.2 qui préconise l'utilisation d'images de contenu en complément du contenu textuel afin d'en faciliter la compréhension.
  • D'ergonomie : le graphique généré en CSS ne sera, par exemple, pas copiable avec la même facilité qu'une image HTML. Il faudra s'assurer également qu'il peut être imprimé lorsque les couleurs sont désactivées (utilisation des bordures en complément de la couleur, éventuellement grâce à une feuille de style pour le media print adaptée, par exemple).
  • Et plus généralement d'interopérabilité : l'information spécifique apportée par le graphique ne sera conservée que dans la mesure où les données de présentation CSS seront conservées avec le document HTML.

Il peut donc être nécessaire, selon le contexte, d'utiliser une image HTML de préférence à cette technique CSS.

Cette technique est proposée surtout lorsque vous n'avez pas de moyen technique de réaliser un complément graphique illustrant vos données brutes.

Le code HTML

Avant tout, il faut s'occuper du code (X)HTML qui devra dans tous les cas présenter votre contenu avec ou sans CSS, vous devez donc vous assurer que toutes les informations sont bien indiquées au sein de votre code HTML.

Pour ce faire, voici un exemple de structure HTML :

<div class="stats">
	<h2>Un petit benchmark</h2>
	<ul>
		<li>Fonction f1 sur 10000 itérations&nbsp;: <span class="percent v70">14,7 ms</span></li>
		<li>Fonction f2 sur 10000 itérations&nbsp;: <span class="percent v30">6,3 ms</span></li>
		<li>Fonction f3 sur 10000 itérations&nbsp;: <span class="percent v100">21 ms</span></li>
	</ul>
</div>

On encadre notre ensemble d'éléments d'une division à laquelle nous appliquons une classe "stats" (par exemple), cette identification nous permettra d'accéder aux éléments de contenu à mettre en forme par la suite.

Ensuite, les données peuvent être présentées comme bon vous semble, nous avons ici opté pour une liste non ordonnée qui semble adaptée. Nous enveloppons notre valeur statistique d'une balise <span> à laquelle nous affectons les classes percent et vX (où X représente la largeur à associer à notre valeur statistique). Pour notre exemple, nous associons 14,7ms à 70% de la largeur ; 6,3ms à 30% de la largeur ; 21ms à 100% de la largeur.

C'est tout pour la partie HTML, vous constaterez qu'à ce stade, vos statistiques sont parfaitement parlantes et complètes, une synthèse vocale ou tout autre moyen de consultation de page (plage braille, robot d'indexation, navigateur textuel ou navigateur avec styles CSS désactivés, ...) peut accéder à l'information pertinente. Il ne reste plus qu'à embellir tout ceci grâce aux styles CSS.

Mise en forme CSS

Nous souhaitons associer à chaque valeur une barre d'une largeur proportionnelle à cette valeur.

Réalisation de la barre

/* suppression des puces sur les listes */
div.stats ul { list-style: none; }
div.stats .percent {
	/* on passe l'élément span correspondant à la classe .percent
	en affichage en bloc pour pouvoir lui donner une dimension.
	Diverses autres choses sont modifiées ensuite à votre convenance. */
	display: block;  /* on affiche le span sous forme de bloc pour lui affecter des dimensions */
	height: 1.5em;
	line-height: 1.5em;
	margin: 5px 10px;
	padding: 0 5px;
	text-align: right;
	color: #fff;
	font-weight: bold;
	font-family: monospace; 
	-moz-border-radius: 5px;  /* un petit arrondi pour les navigateurs le supportant */
	border-bottom: 1px solid #aaa;
	border-right: 1px solid #aaa;
	cursor: default;
}

Spécialisation de la barre en fonction de sa valeur

Nous voici arrivés à des barres quasi invisibles et illisibles, il ne reste qu'à leur appliquer une couleur de fond (ou une image si vous le souhaitez) et une largeur.

Il faut s'occuper d'appliquer une largeur différente suivant la valeur que l'on a associé à notre donnée statistique, c'est ici qu'interviennent les classes vX. Vous pouvez en définir autant que vous le souhaitez, si vous ne voulez que 2 valeurs ou 20, il faudra simplement modifier les styles associés à ces classes. Voici un exemple avec 10 couleurs différentes :

/* Multicolore */
.v100 { background: #970000; width: 100%; }
.v90 { background: #ff0000; width: 90%; }
.v80 { background: #ff6600; width: 80%; }
.v70 { background: #ff9c00; width: 70%; }
.v60 { background: #ffd800; width: 60%; }
.v50 { background: #eaff00; width: 50%; }
.v40 { background: #baff00; width: 40%; }
.v30 { background: #78ff00; width: 30%; }
.v20 { background: #12ff00; width: 20%; }
.v10 { background: #00ff60; width: 10%; }

Paramétrabilité des barres

Les possibilités sont maintenant infinies sur le style de la barre (horizontal, vertical, avec ou sans bordure, avec image de fond, ...), un moyen simple de différencier plusieurs familles de barres est d'associer une classe spécifique à chaque bloc de statistiques dans la balise <div>

<div class="stats multicolor">
...
</div>
<div class="stats green_uni">
...
</div>

De cette manière, vous pouvez appliquer le style multicolore au premier bloc de statistiques et le style vert uni au second.

/* Commun à tous les styles */
.v100 { width: 100%; }
.v90 { width: 90%; }
.v80 { width: 80%; }
.v70 { width: 70%; }
.v60 { width: 60%; }
.v50 { width: 50%; }
.v40 { width: 40%; }
.v30 { width: 30%; }
.v20 { width: 20%; }
.v10 { width: 10%; }
/* Multicolore */
.multicolor .v100 { background: #970000; }
.multicolor .v90 { background: #ff0000; }
.multicolor .v80 { background: #ff6600; }
.multicolor .v70 { background: #ff9c00; }
.multicolor .v60 { background: #ffd800; }
.multicolor .v50 { background: #eaff00; }
.multicolor .v40 { background: #baff00; }
.multicolor .v30 { background: #78ff00; }
.multicolor .v20 { background: #12ff00; }
.multicolor .v10 { background: #00ff60; }
/* Unicolore vert */
.green_uni .percent { background: #83df00; }

Il est très simple de paramétrer différents looks en fonction de vos humeurs, de votre thème du jour, du type de données à afficher etc. Quelques exemples de résultats possibles.

Complément optionnel

Un point interessant serait d'ajouter un attribut title pour faciliter la lecture du texte au cas où celui-ci soit moins lisible à cause d'une couleur de fond ou d'une image peu adaptée, vous pouvez l'ajouter directement dans le code HTML (<span title="ma valeur" class="percent vXX">ma valeur</span>) ou bien, si vous connaissez JavaScript, c'est une excellente occasion de l'utiliser. Il suffit de récupérer toutes les balises <span> qui ont pour classe percent et de leur ajouter un attribut title qui a pour valeur le contenu de la balise elle même.

Je vous propose ici la version qui utilise jQuery (une bibliothèque JavaScript) par soucis de simplicité :

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
// script pour ajouter un attribut title au <span> de façon automatisée
function titlePercentage() {
	// pour chaque élément de classe "percent"
	$(".percent").each(function() {
		// on définit son attribut "title" à partir du texte de l'élément
		$(this).attr("title",$(this).html());
	});
}

$(document).ready(function() {
	titlePercentage();
});
</script>

Si vous n'utilisez pas jQuery pour autre chose, préférez coder une version en JavaScript classique pour éviter de charger la bibliothèque pour presque rien.

Ressources complémentaires

Voici différentes autres méthodes et mises en forme trouvées sur le Web (plus ou moins complexes, accessibles ou paramétrables).