Lego island, Glen Carrie on Unsplash Lego island, Glen Carrie on Unsplash

Intégration de fichiers SVG

Le format vectoriel SVG présente de nombreux avantages comme un poids réduit, le support des animations, des filtres et des CSS, adaptation aux différentes tailles d'écran sans perte de qualité. Les avantages du format SVG cités ici ne sont pas exhaustifs mais c'est suffisant pour avoir envie de l'utiliser. Voici quelques solutions d'intégration HTML.

Dans un fichier HTML

Avec la balise image

La solution la plus simple pour intégrer un fichier SVG dans son code HTML c'est d'utiliser la balise <img>.

<img src="svg/mon-fichier.svg" alt="intégration du fichier SVG avec la balise image" />

Le revers de cette simplicité c'est l'impossibilité de modifier le fichier SVG avec les CSS.

SVG inline et HTML

L'autre solution est d'écrire directement le fichier SVG dans le code HTML.

<!-- fichier: exemple.html -->
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Exemple SVG</title>
</head>
<body>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 64 64"
fill="currentColor"
class="mon-fichier">

<path d="M2.133 13.867h59.733c1.178 0 2.133 0.955 2.133 2.133v2.133c0 1.178-0.955 2.133-2.133 2.133h-59.733c-1.178 0-2.133-0.955-2.133-2.133v-2.133c0-1.178 0.955-2.133 2.133-2.133z"></path>
<path d="M2.133 28.8h59.733c1.178 0 2.133 0.955 2.133 2.133v2.133c0 1.178-0.955 2.133-2.133 2.133h-59.733c-1.178 0-2.133-0.955-2.133-2.133v-2.133c0-1.178 0.955-2.133 2.133-2.133z"></path>
<path d="M2.133 43.733h59.733c1.178 0 2.133 0.955 2.133 2.133v2.133c0 1.178-0.955 2.133-2.133 2.133h-59.733c-1.178 0-2.133-0.955-2.133-2.133v-2.133c0-1.178 0.955-2.133 2.133-2.133z"></path>
</svg>
</body>
</html>

Le fichier SVG inline garde tous ses avantages et on économise une requête serveur.
Evidemment pour la clarté du code, ça peut poser problème.

Dans un template

La solution vraiment idéale est d'utiliser un language de templating. Voici un exemple basé sur le language Nunjucks.

SVG inline et template

J'ai donc un fichier SVG mon-fichier.svg. Comme nous sommes dans un language de templating, j'ajoute une variable dans le code du fichier SVG {{ monFichierSize }} pour définir sa taille.

<!-- fichier: mon-fichier.svg -->
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 64 64"
width="{{ monFichierSize }}"
height="{{ monFichierSize }}"
fill="currentColor"
class="mon-fichier">

<path d="M2.133 13.867h59.733c1.178 0 2.133 0.955 2.133 2.133v2.133c0 1.178-0.955 2.133-2.133 2.133h-59.733c-1.178 0-2.133-0.955-2.133-2.133v-2.133c0-1.178 0.955-2.133 2.133-2.133z"></path>
<path d="M2.133 28.8h59.733c1.178 0 2.133 0.955 2.133 2.133v2.133c0 1.178-0.955 2.133-2.133 2.133h-59.733c-1.178 0-2.133-0.955-2.133-2.133v-2.133c0-1.178 0.955-2.133 2.133-2.133z"></path>
<path d="M2.133 43.733h59.733c1.178 0 2.133 0.955 2.133 2.133v2.133c0 1.178-0.955 2.133-2.133 2.133h-59.733c-1.178 0-2.133-0.955-2.133-2.133v-2.133c0-1.178 0.955-2.133 2.133-2.133z"></path>
</svg>

J'ai mon template Nunjucks exemple.njk. J'utilise la fonctionnalité include pour écrire le fichier SVG dans mon template et je défini la taille de mon-fichier.svg en affectant une valeur à la variable.

{# fichier: exemple.njk #}
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Exemple SVG</title>
</head>
<body>

{% set monFichierSize = 36 %}
{% include "svg/mon-fichier.svg" %}
</body>
</html>

Dans le template Nunjucks, le code reste simple et lisible.
Une fois passé par le moteur de templating, on retrouve notre fichier SVG inline dans le fichier exemple.html.

Utiliser les macros

Les macros de Nunjucks permettent de créer des morceaux de contenu réutilisable. Si on a plusieurs fichiers SVG comme des icônes, on peut se servir des macros pour créer sa propre bibliothèque.
Je crée un fichier mes-icones.njk pour regrouper mes icônes de réseaux sociaux. J'écris une macro par icône et je passe la variable {{ size }} qui me permettra de définir la taille de l'icône.

{# fichier: mes-icones.njk #}

{# icône linkedin #}
{% macro linkedin(size) %}
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 448 512"
width="{{ size }}"
height="{{ size }}"
class="icon-linkedin">
<path fill="currentColor" d="M100.28 448H7.4V148.9h92.88zM53.79 108.1C24.09 108.1 0 83.5 0 53.8a53.79 53.79 0 0 1 107.58 0c0 29.7-24.1 54.3-53.79 54.3zM447.9 448h-92.68V302.4c0-34.7-.7-79.2-48.29-79.2-48.29 0-55.69 37.7-55.69 76.7V448h-92.78V148.9h89.08v40.8h1.3c12.4-23.5 42.69-48.3 87.88-48.3 94 0 111.28 61.9 111.28 142.3V448z"></path>
</svg>

{% endmacro %}

{# icône whatsapp #}
{% macro whatsapp(size) %}
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 448 512"
width="{{ size }}"
height="{{ size }}"
class="icon-whatsapp">
<path fill="currentColor" d="M380.9 97.1C339 55.1 283.2 32 223.9 32c-122.4 0-222 99.6-222 222 0 39.1 10.2 77.3 29.6 111L0 480l117.7-30.9c32.4 17.7 68.9 27 106.1 27h.1c122.3 0 224.1-99.6 224.1-222 0-59.3-25.2-115-67.1-157zm-157 341.6c-33.2 0-65.7-8.9-94-25.7l-6.7-4-69.8 18.3L72 359.2l-4.4-7c-18.5-29.4-28.2-63.3-28.2-98.2 0-101.7 82.8-184.5 184.6-184.5 49.3 0 95.6 19.2 130.4 54.1 34.8 34.9 56.2 81.2 56.1 130.5 0 101.8-84.9 184.6-186.6 184.6zm101.2-138.2c-5.5-2.8-32.8-16.2-37.9-18-5.1-1.9-8.8-2.8-12.5 2.8-3.7 5.6-14.3 18-17.6 21.8-3.2 3.7-6.5 4.2-12 1.4-32.6-16.3-54-29.1-75.5-66-5.7-9.8 5.7-9.1 16.3-30.3 1.8-3.7.9-6.9-.5-9.7-1.4-2.8-12.5-30.1-17.1-41.2-4.5-10.8-9.1-9.3-12.5-9.5-3.2-.2-6.9-.2-10.6-.2-3.7 0-9.7 1.4-14.8 6.9-5.1 5.6-19.4 19-19.4 46.3 0 27.3 19.9 53.7 22.6 57.4 2.8 3.7 39.1 59.7 94.8 83.8 35.2 15.2 49 16.5 66.6 13.9 10.7-1.6 32.8-13.4 37.4-26.4 4.6-13 4.6-24.1 3.2-26.4-1.3-2.5-5-3.9-10.5-6.6z"></path>
</svg>

{% endmacro %}

{# icône instagram #}
{% macro instagram(size) %}
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 448 512"
width="{{ size }}"
height="{{ size }}"
class="icon-instagram">
<path fill="currentColor" d="M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z"></path>
</svg>

{% endmacro %}

Maintenant que ma bibliothèque est créée, je peux importer ces fichiers SVG dans mon template exemple.njk avec la function import de deux façons.

{# fichier: exemple.njk #}

{# liaison des valeurs à une variable #}
{% import "mes-icones.njk" as icon %}
{{ icon.linkedin(24) }}
{{ icon.whatsapp(24) }}
{{ icon.instagram(24) }}

{# importation des valeurs #}
{% from "mes-icones.njk" import linkedin, whatsapp as messagerie, instagram %}
{{ linkedin(24) }}
{{ messagerie(24) }}
{{ instagram(24) }}

Comme pour la solution précédente le code reste simple et lisible et on retrouve nos fichiers SVG inline dans le fichier exemple.html.

Dans une feuille de style

Pour utiliser un fichier SVG comme background d'un élément HTML, on l'intégre comme une image avec la propriété CSS background-image. Dans la feuille de style le fichier SVG ne peut pas être modifié.

.ma-classe {
background-image: url("svg/mon-fichier.svg");
...;
}

On peut également l'intégrer inline mais il faut l'encoder au format base64. On économise alors une requête serveur.

.ma-classe {
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2NCA2NCIgd2lkdGg9IjM2IiBoZWlnaHQ9IjM2IiBmaWxsPSJ3aGl0ZSI+DQogIDxwYXRoIGQ9Ik0yLjEzMyAxMy44NjdoNTkuNzMzYzEuMTc4IDAgMi4xMzMgMC45NTUgMi4xMzMgMi4xMzN2Mi4xMzNjMCAxLjE3OC0wLjk1NSAyLjEzMy0yLjEzMyAyLjEzM2gtNTkuNzMzYy0xLjE3OCAwLTIuMTMzLTAuOTU1LTIuMTMzLTIuMTMzdi0yLjEzM2MwLTEuMTc4IDAuOTU1LTIuMTMzIDIuMTMzLTIuMTMzeiI+PC9wYXRoPg0KICA8cGF0aCBkPSJNMi4xMzMgMjguOGg1OS43MzNjMS4xNzggMCAyLjEzMyAwLjk1NSAyLjEzMyAyLjEzM3YyLjEzM2MwIDEuMTc4LTAuOTU1IDIuMTMzLTIuMTMzIDIuMTMzaC01OS43MzNjLTEuMTc4IDAtMi4xMzMtMC45NTUtMi4xMzMtMi4xMzN2LTIuMTMzYzAtMS4xNzggMC45NTUtMi4xMzMgMi4xMzMtMi4xMzN6Ij48L3BhdGg+DQogIDxwYXRoIGQ9Ik0yLjEzMyA0My43MzNoNTkuNzMzYzEuMTc4IDAgMi4xMzMgMC45NTUgMi4xMzMgMi4xMzN2Mi4xMzNjMCAxLjE3OC0wLjk1NSAyLjEzMy0yLjEzMyAyLjEzM2gtNTkuNzMzYy0xLjE3OCAwLTIuMTMzLTAuOTU1LTIuMTMzLTIuMTMzdi0yLjEzM2MwLTEuMTc4IDAuOTU1LTIuMTMzIDIuMTMzLTIuMTMzeiI+PC9wYXRoPg0KPC9zdmc+");
...;
}

Liens