Filtre CSS
Un petit truc est d’appliquer un filtre « Grayscale » sur l’image pour obtenir une image noir, grise ou blanche. C’est tricher, mais si cela peut vous éviter une image supplémentaire!
#monImageSVG {filter:grayscale(100%);}
J’ai profité d’un nouveau contrat pour optimiser la manipulation des images vectorielles que j’utilise depuis longtemps. L’idée est de n’utiliser qu’une seule image pour toutes les occurrences de celle-ci dans la page, peu importe ces dimensions et ses couleurs. Si je transforme déjà les dimensions d’une image sans problème à l’aide de classe CSS, quand est-il de la couleur de fond? Malheureusement, j’en suis toujours à une image par variation de couleurs! La seule amélioration c’est que j’ajoute maintenant des classes à l’intérieur de l’image pour simplifier la manipulation.
Ce qu’il y a de formidable avec les images vectorielles SVG, c’est la possibilité de modifier leur apparence sans perte de qualité. Par exemple changer les dimensions de l’image à l’infinie à l’aide d’une simple classe CSS. C’est un net avantage particulièrement si on désire une très grosse image. À moins d’avoir une image plutôt complexe, on peut sauver des centaines d’octets!
Redimension d’une image SVG
Directement
<img src="image.svg" style="width:200px;" /> <img src="image.svg" style="width:100px;" /> <img src="image.svg" style="width:50px;" />
Avec une classe
<style> .p200 {width:200px;max-width:200px;width:100%} .p100 {width:100px;max-width:100px;width:100%} .p50 {width:50px;max-width:50px;width:100%} </style> <img src="image.svg" class="p200" /> <img src="image.svg" class="p100" /> <img src="image.svg" class="p50" />
N’est-ce pas merveilleux? Dans le deuxième cas, j’applique même une largeur de 100% avec un max-width
qui permet un affichage adaptatif. Le prochain exemple utilise une image de fond. Bien que plus complexe à utiliser, c’est tout à fait adapté au SVG puisque ça fonctionne un peu de la même manière, avec un conteneur.
Image SVG de fond
<style> .logo {background-repeat: no-repeat;width:380px;height:199px;background-size: 380px 199px;background-image: url("data:image/svg+xml;base64,[image SVG en Base64]");} .pf200 {width:200px;height:105px;background-size: 200px 105px;} .pf100 {width:100px;height:52px;background-size: 100px 52px;} .pf50 {width:50px;height:26px;background-size: 50px 26px;} </style> <div class="logo pf200"></div> <div class="logo pf100"></div> <div class="logo pf50"></div>
Ce qui est intéressant avec ce dernier exemple c’est qu’il permet de n’avoir qu’une seule image, encodée et donc plus petite, qu’on peut modifier les dimensions. Placez ce code dans une feuille de style et vous n’aurez plus à vous préoccuper de l’image SVG et de ses dimensions.
Changement de couleur d’une image SVG
On pourrait croire que changer les couleurs d’une image vectorielle SVG avec le CSS background-color
oups, plutôt fill
(!) se ferait aussi simplement que changer les dimensions de celle-ci. Eh bien non, il n’en est rien. À part l’astuce du masque et des filtres, impossible de changer les couleurs d’une image SVG!
Si #monImageSVG {width:100px;}
fonctionne, impossible de faire #monImageSVG {fill:#eeeeee;}. Pourquoi? Dans la mesure où il est possible de le faire en JavaScript, parce que les programmeurs derrière le CSS ne l’ont tout simplement pas fait! À mon avis, le CSS4(!) offrira cette possibilité en natif. En attendant, à part le JavaScript, toutes les solutions demande d’avoir plusieurs images, une image par variation de couleurs. En effet, on peut vouloir modifier la couleur de seulement un objet de l’image.
À l’époque je ne me cassais pas la tête, je changeais la couleur directement dans mon Illustrator et je sauvegardait une nouvelle copie de l’image. Cela demeure toujours la meilleurs façon de faire. En d’autres mots, toute la beauté et la flexibilité du SVG mis à mal à cause de ce petit détail. Même chose pour la feuille de style interne ou externe à l’image, puisqu’elle est déclarée à l’intérieur de l’image et que c’est impossible de le déclarer à l’extérieur. Ça vous prendra encore une image par variation, même s’il s’agit de modifier une seule ligne de code dans l’image. On en sort pas.
Simplifier la gestion avec des classes CSS
La seule chose qu’on peut faire est de simplifier la manipulation, avec un SCSS par exemple. Modifier la couleur avec Illustrator n’est pas toujours facile, déjà l’ouvrir et surtout l’acheter n’est pas donner à tous. Ensuite, il faut sélectionner le bon objet, qui est peut-être sous un autre objet, etc. Une meilleure solution consiste à imbriquer le CSS directement dans l’image. Il suffit alors d’ouvrir l’image dans votre éditeur de texte favori pour changer le CSS. Il y a trois méthode, déjà le CSS en ligne :
<path fill="#A5C400" d="M304.141... // ou encore <path style="fill:#A5C400;" d="M304.141...
Le problème avec cette méthode c’est que vous devez passer l’image au complet pour trouver les attributs. Une meilleure solution consiste à utiliser une feuille de style et des classes :
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg version="1.1" xmlns="http://www.w3.org/2000/svg"> <defs> <style> .couleurdefond {fill: #a5c400;} </style> </defs> <path class="couleurdefond" d="M304.141...
Vous aurez compris qu’il suffit de modifier la classe couleurdefond
et de sauvegarder une copie de l’image sous un nouveau nom. Inutile d’avoir une feuille de style externe si le CSS ne prend pas plus de place que l’instruction de la feuille de style externe. Mais si votre feuille de style est plutôt longue, c’est-à-dire si vous devez spécifier plusieurs couleurs, utiliser une feuille externe. Mais encore une fois, il faudra sauvegarder une image par variation de couleur puisque le URL de la feuille de style doit être modifiée directement dans l’image.
<?xml version="1.0" encoding="utf-8"?> <?xml-stylesheet href="mafeuilledestyles.css" type="text/css"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg version="1.1" xmlns="http://www.w3.org/2000/svg"> <defs> </defs> <path class="couleurdefond" d="M304.141...
Le Mask
Bien que le « mask » ne soit pas tellement compatible, il permet avec une complexité supplémentaire de modifier la couleur d’une image SVG. Il s’agit en fait d’un leurre puisque l’image ne change pas de couleurs, mais bien la couleur de fond du masque. Pour plus d’information, lire l’excellent tutoriel sur le sujet par Noah Blon Coloring SVGs in CSS Background Images.
Le JavaScript
Je sais bien que ça ne plait pas à tout le monde, moi le premier. Même si l’ensemble des interprétations natives du Navigateur se font déjà en JavaScript, c’est transparent à l’usager qui ne peut pas bloquer sont exécution, contrairement au JavaScript imbriquer dans un document HTML. C’est une solution au prix de l’accessibilité, donc, certains visiteurs ne pourront voir la couleur si le JavaScript est désactivé. Remarquez que la grande majorité des sites Web sont mal fait et exige tant le JavaScript que les fichiers témoins pour bien fonctionner. Essayer de naviguer sans ces deux services pour voir!
Et encore, s’il suffit de $(’#arbre’).css({ fill: "#ff0000" });
, le code de l’image doit être imbriqué dans le document HTML. Alors à moins de devoir faire une manipulation dynamique, aussi bien utilisé du CSS normal! Toute fois, avec le JavaScript, on peut ouvrir l’image et la régénérer en mémoire. Ce qui permet par la suite de modifier tout CSS de l’image puisqu’elle fait maintenant partie du DOM comme si elle était imbriquée dans le document HTML! Puisqu’il est essentiellement question de poids, on peut aussi placer le code SVG dans une variable JavaScript, d’appliquer la couleur et d’écrire l’image finale. Bien sûr la page HTML contiendra plusieurs images mais elles seront encore une fois généré localement, sans utiliser la bande passante.
Références
- W3C - CSS filter Property
- Le SVG Colorier vos formes sur OpenClassrooms
- Coloring SVGs in CSS Background Images par Noah Blon
- Base64 encoder and decoder