Les SVG (Scalable vector graphics) sont devenus des formats d’image très prisés sur les sites web. La raison ? La façon dont ils s’adaptent et ne perdent pas en qualité peu importe la taille de l’écran ! Mais ce n’est pas tout ! Les fichiers SVG permettent également d’être modifiés directement avec le CSS pour changer la couleur, la bordure, la taille ou la position de l’image sur le site. Changer la couleur d’une image lors d’un hover directement en CSS avec une seule image ? C’est désormais possible ! Suivez le guide.
Menu de navigation rapide
Quel intérêt et dans quel cas utiliser des SVG ?
Un fichier SVG reste identique qu’il fasse 5cm de large ou 15 mètres de large. Ceci est dû au fait qu’il n’est pas un assemblage de pixels mais de vecteurs. Et si on se rappelle de ses (lointains pour ma part) cours de maths, un vecteur n’est rien d’autre que des informations sur le dessin et non pas des millions de petits carrés de couleur juxtaposés. Si dans un espace donné un trait part d’un point A et arrive à un point B, le tout avec des repères relatifs, la machine va afficher le trait de façon proportionnelle sur un écran de montre comme sur la façade d’un immeuble ! Alors que si on prend une photo classique de son chat qui dort, si on l’agrandit on finit par surtout voir des petits carrés de toutes les couleurs….
Alors on va me dire « ouiiiiiiiii mais non, tu utilises une image, comment tu veux convertir une image comme celle-ci en tracéééééééé, serieuuuuuuux ???? ». Effectivement ! Quand on parle de SVG on parle surtout de tracés et donc d’images simples (icônes, dessins, formes, etc.). Mais justement ! Sans s’en rendre compte on a beaucoup de ce genre d’images sur un site et préférer un format qui pèse vraiment peu en terme de poids et qui est plus facilement manipulable ça compte au final !
Si l’on veut qu’un élément de cette icône soit modifié lors du survol de la souris, on doit refaire l’icône en faisant la modification et avoir les 2 versions sur son site web ! Hors si on peut modifier l’image originale directement on divise par 2 le nombre d’images qui seront dans ce cas ! Et ce gain multiplié par le nombre d’images sur un site ça peut vite faire une différence !
Faire en sorte que le site web « lise » le SVG
Un fichier SVG, et ça tombe plutôt pas mal dans le cadre d’un site web, utilise les même bases de langage que ce dernier : Le XML ! (le HTML est lui-même issu du XML). Donc si le CSS est capable de modifier l’apparence du HTML il est tout aussi qualifié pour modifier l’apparence du SVG. Mais lorsque l’on rajoute un SVG sur son site il reste une image comme une autre avec juste son extension qui se termine par « .svg ». Alors comment faire ? On va d’abord demander à son site de « récupérer » les informations du SVG, et de remplacer l’image par ces informations pour avoir directement dans la page le code XML du SVG pour pouvoir le modifier en CSS.
Ajouter des scripts perso dans son thème WordPress
Pour cet exemple on va partir d’un site web fait avec WordPress et un thème. Si votre site n’est pas fait avec WordPress, la démarche reste la même, il suffit juste de l’adapter et de suivre l’esprit de la démarche ! On va donc ajouter un fichier pour mettre son code jQuery directement dans le thème enfant de son site WordPress. (SI le thème enfant ne vous dit rien, allez faire un petit tour sur cet article !). On va créer un dossier ‘js » (pour javascript) et y placer notre fichier que l’on va appeler « custom_js.js ». Voilà à quoi ressemble notre dossier au final :
Reste plus qu’à faire en sorte que le code dans ce fichier soit chargé en même temps que le site, et pour ça on va utiliser cette fonction que l’on va mettre dans le fichier « fonction.php » de son thème enfant :
function custom_enqueue_scripts() { wp_enqueue_script( 'my-custom-script', get_stylesheet_directory_uri() . '/js/custom_js.js', array('jquery')); } add_action( 'wp_enqueue_scripts', 'custom_enqueue_scripts' );
Ce code va appeler la fonction « custom_enqueue_scripts » lors du chargement de WordPress, fonction qui va récupérer (ligne 2) le fichier « custom_js..js » dans le dossier du thème enfant (get_stylesheet_directory_uri()) dans le sous-dossier « js », et qui va lui faire utiliser directement jquery (une bibliothèque javascript spéciale pour le web ! En attendant un article sur le sujet vous pouvez en apprendre plus sur ce site !)
Ajouter un script jQuery pour lire les SVG
Maintenant que l’on peut ajouter un script perso sur son site, il est temps de lui dire qu’il doit remplacer notre « enveloppe.svg » par tout le code XML qui le compose. Pour cela, on va ajouter ce code :
/* Remplacer les svg par son code xml directement dans le DOM au chargement de la page */ jQuery('img.svg').each(function(){ var $img = jQuery(this); var imgID = $img.attr('id'); var imgClass = $img.attr('class'); var imgURL = $img.attr('src'); jQuery.get(imgURL, function(data) { // Récupérer uniquement le svg et ignorer le reste var $svg = jQuery(data).find('svg'); // Rajouter l'ID de l'ancienne image sur le SVG if(typeof imgID !== 'undefined') { $svg = $svg.attr('id', imgID); } // Rajouter les classes de l'ancienne image sur le SVG if(typeof imgClass !== 'undefined') { $svg = $svg.attr('class', imgClass+' replaced-svg'); } // Supprimer les balises non valides d'après http://validator.w3.org $svg = $svg.removeAttr('xmlns:a'); // Remplacer l'image par le SVG $img.replaceWith($svg); }, 'xml'); });
Pour éviter les erreurs, il est plus que recommandé d’entourer le script avec des instructions qui disent d’attendre que la page soit entièrement chargée avant d’exécuter ce code. Si ce n’est pas fait, le code peut s’exécuter et ne rien trouver puisque la page n’a pas fini de charger…
jQuery( document ).ready( function( $ ) { /* Remplacer les svg par son code xml directement dans le DOM au chargement de la page */ jQuery('img.svg').each(function(){ var $img = jQuery(this); var imgID = $img.attr('id'); var imgClass = $img.attr('class'); var imgURL = $img.attr('src'); jQuery.get(imgURL, function(data) { // Récupérer uniquement le svg et ignorer le reste var $svg = jQuery(data).find('svg'); // Rajouter l'ID de l'ancienne image sur le SVG if(typeof imgID !== 'undefined') { $svg = $svg.attr('id', imgID); } // Rajouter les classes de l'ancienne image sur le SVG if(typeof imgClass !== 'undefined') { $svg = $svg.attr('class', imgClass+' replaced-svg'); } // Supprimer les balises non valides d'après http://validator.w3.org $svg = $svg.removeAttr('xmlns:a'); // Remplacer l'image par le SVG $img.replaceWith($svg); }, 'xml'); }); });
Et voilà ! Votre page ne va plus afficher une simple image, mais tout le code que contient le SVG !
Pour que ça fonctionne, il faut impérativement que l’image avec le SVG ait la classe « svg ». Cet élément a été mis en place pour laisser la possibilité de choisir quelles images manipuler ou non. Donc les SVG avec la classe ‘svg’ seront impactés par le code ci-dessus et la autres non !
Si on fait un clic droit sur notre image dans le navigateur et que l’on « inspecte » l’élément, on n’aura plus :
<img class="wp-image-732 alignnone size-full svg" src="https://hop-pop-up-site-web-bordeaux.com/wp-content/uploads/2018/10/enveloppe.svg" alt="" width="50" height="53">
Mais plutôt :
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Calque_1" x="0px" y="0px" viewBox="0 0 60 40" style="enable-background:new 0 0 60 40;" xml:space="preserve" class="wp-image-732 alignnone size-full svg replaced-svg"> <style type="text/css"> .st0{fill-rule:evenodd;clip-rule:evenodd;fill:#0099A8;} .st1{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;} </style> <rect class="st0" width="60" height="40"></rect> <g id="MAIL-ICON"> <g> <path class="st1" d="M30.6,22L53.3,3H6.7l22.7,19C29.7,22.2,30.2,22.2,30.6,22z M22.2,20L4.4,5.2v29.6l4.2-3.5L22.2,20z M35.4,22 l-3,2.5L30.6,26c-0.3,0.3-0.8,0.3-1.2,0l-1.9-1.6L24.6,22l-11.1,9.3L6.7,37h46.7l-6.1-5.1L35.4,22z M37.8,19.9l14.3,12l3.3,2.7 V5.2L37.8,19.9z"></path> </g> </g> </svg>
Un élément <svg> avec sont propre <style></style> et son contenu <rect></rect> pour « rectangle » (le vert qui fait le fond) et ses vecteurs <path></path> pour les tracés de l’enveloppe. Maintenant que l’on a ces éléments, on va pouvoir les modifier !
Modifier directement le SVG en CSS
Pour cet exemple on va faire en sorte de modifier non seulement le fond derrière l’enveloppe mais également la couleur de l’enveloppe elle-même. Pour cela nous allons utiliser un hover sur l’élément. On va donc dire : « quand la souris passe sur l’enveloppe, change la couleur de fond du vert au rouge ! ». Mais quelle propriété doit-on changer ? comment la changer ? La réponse est déjà écrite dans le code du SVG dans les balises <style></style> : c’est la propriété « fill » !
<style type="text/css"> .st0{fill-rule:evenodd;clip-rule:evenodd;fill:#0099A8;} .st1{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;} </style>
Un coup d’oeil suffit (et profitons-en ce n’est pas aussi évident d’habitude) pour remarquer que :
- Le fond vert de couleur #0099a8 correspond au sélecteur « .st0 »
- L’enveloppe blanche de couleur #ffffff correspond au sélecteur « .st1 »
Il ne reste plus qu’à écrire le CSS qui va modifier ces éléments au passage de la souris :
.svg:hover .st0{ fill: red; } .svg:hover .st1{ fill: black; }
Et voilà le travail :
Lors du passage de la souris sur l’enveloppe on retrouve le hover et le tout avec une seule image. Et les possibilités sont infinies puisque tout est modifiable ! On peut même imaginer manipuler les éléments du SVG avec du jQuery ?