Le Hollandais Volant

Des icônes pour le web : PNG, SVG ou Icon-font ?

Il y a quelques temps, je vous montrais une petite astuce pour faire des icônes « propres » sur mobile et desktop, puis une astuce pour faire un formulaire avec des icônes pouvant bénéficier de la première méthode

Depuis j’ai essayé de voir les autres techniques pour faire des icônes dans une page web.
Aujourd’hui, principalement 3 méthodes sont possibles :

  • prendre une image PNG (comme celle-ci) avec plein d’icônes dedans et utiliser la méthode des fenêtres coulissantes.
  • prendre la même image, mais au format SVG, donc vectorielle
  • utiliser les icon-fonts, des polices d’écriture avec des icônes dedans

Les PNG

La première technique avec les images de fond en PNG, tout le monde la connaît : c’est la plus utilisée, la plus supportée par les navigateurs, la plus simple… mais c’est aussi la moins malléable !
En effet, si ont veut afficher une icône plus grande, on peut le faire, mais l’image sera floue et pixelisée. Même chose si on veut afficher les icônes sur un écran où la densité de pixels est plus grande (écrans « Retina® », par exemple, mais Apple et ses Mac Book sont loin d’être un cas isolé aujourd’hui).
On peut créer plusieurs images avec différentes résolutions pour plusieurs types d’écran, mais ce n’est pas pratique.

Le second problème c’est si on veut changer la couleur de son thème graphique : les icônes doivent être adaptées aussi. Or pour ça, on ne peut pas faire grand chose : pour changer la couleur des icônes, il faut modifier l’image, ou là encore créer des images différentes pour chaque thème…

Les SVG

Les SVG permettent d’avoir des images nettes quelque soit la taille : c’est très pratique lors du zoom, ou lorsque votre site est susceptible d’être affiché sur un mobile (où la densité de pixels est bien plus grande que sur un écran d’ordinateur).
On peut obtenir le même effet avec du PNG, mais il faut pour cela partir d’icônes à haute résolution, et donc d’images très lourdes, ce qui va poser problème lors du chargement de la page, particulièrement sur mobile et surtout avec des connexions pourries. Le SVG, lui, reste précis avec le même fichier.

Le seul problème ici c’est que si on a toujours besoin de faire plusieurs images si on veut changer la couleur du thème. On peut faire ça en JavaScript (je fais cela dans cet exemple), mais pour le thème en CSS, ce n’est pas pratique.

Les Icon-fonts

Alors ici on conserve la netteté du SVG lors de la mise à l’échelle, mais on a en plus l’avantage très important de pouvoir colorier les icônes comme on veut !

En effet, tout se fait en simple CSS : on dit que l’on veut afficher tel ou tel caractère contenu dans la webfont et ensuite c’est du simple texte : on peut l’agrandir (avec font-size), la colorier (avec color), ajouter une ombre CSS (avec text-shadow), etc. C’est la méthode la plus pratique pour le designer final.

Pour créer un fichier de police avec les icônes dedans, il faut disposer d’icônes initiales (PNG ou SVG) et utiliser un programme pour transformer ça en une police. Je n’ai pas trouvé d’outil facile pour faire ça en local, mais cet outil en ligne fonctionne bien : IcoMoon.io.
Ensuite il suffit d’utiliser la police d’écriture comme c’est fait dans le fichier demo.html fourni au téléchargement.

Il y a quand même quelques inconvénients. J’en ai noté deux principaux :

  • une fois qu’on a généré notre police, il est difficile de la modifier : pour ajouter une icône, il faut régénérer la police (comme si on la recompilait à partir des icônes initiales), ce qui peut éventuellement changer les codes des icônes (chaque icône est accessible avec un code à utiliser dans le CSS).
  • le fonctionnement de l’usage des Icon-fonts fait qu’il ne sont utilisables que dans la propriété content de CSS. Or content ne peut être utilisée que sur les pseudo-éléments (::after et ::before), qui elles-mêmes ne sont utilisables que sur les éléments HTML non-autofermantes (donc toutes sauf les input, img, br, hr…). On peut donc utiliser les Icon-fonts partout sauf sur les input, les images…

Si vous voulez quand-même utiliser une icône sur un input, il faut ruser, et l’appliquer par exemple sur un label qui est rendu invisible.

L’usage des Icon-fonts est assez simple. Comme je l’ai dit, on utilise un code pour accéder à un caractère en particulier dans la police. Le CSS se charge d’afficher ce caractère à l’écran grâce à la propriété content :

.icon::before {
    content: "\1a02";
}

Ce que l’on fait parfois, c’est qu’on place ce code directement dans un attribut de l’élément HTML, puis le CSS affiche le contenu de cet attribut dans le content (oui, on peut faire tout ça :D) :

<span data-icon="&#x1a02;">Text</span>
[
@font-face {
    font-family: "icons";
    src: url("icons.woff") format("woff");
}

data-icon]::before {
    font-family: icons;
    content: attr(data-icon);
}

Et on peut changer la couleur, etc :

[data-icon]::before {
   [ …]
    color: red;
    font-size: 3em;
}

Bref, une fois qu’on a créé notre fichier d’icônes, l’usage est très simple, les possibilités sont énormes (couleurs, taille, ombres, animations — y compris sur la couleur, donc pour faire des couleurs arc-en-ciel \o/ — etc.), c’est supporté par les bon navigateurs récents (y compris mobiles).

Et concernant la lourdeur et le poids, je trouve que ça va tranquillement : mon fichier d’Icon-fonts fait 48 ko et contient 400 icônes différentes. Mon fichier PNG avant contenait environ 60 icônes pour 25 ko (certaines étaient en doubles pour pouvoir avoir des couleurs différentes).