Apprendre le langage SVG, pas Ă pas
Public visé : vous connaissez un peu HTML/CSS, mais vous n'avez jamais (ou peu) écrit de SVG à la main. À la fin, vous saurez lire et composer un document SVG complet — structure, formes, styles, chemins, réutilisation, transformations, texte, dégradés, découpes, filtres et animations — en le tapant vous-même.
Le SVG (Scalable Vector Graphics) est un format d'image vectorielle décrit en XML. Contrairement à une image matricielle (PNG, JPEG), il ne stocke pas des pixels mais des instructions de dessin : « trace un cercle ici », « remplis cette forme ». D'où ses deux qualités : il reste net à n'importe quelle taille, et son code est du texte lisible, versionnable, modifiable à la main.
C'est un tutoriel : chaque étape s'appuie sur la précédente et le chemin décrit ici fonctionne. Suivez-le dans l'ordre.
Ce dont vous avez besoin
- Un éditeur de texte (n'importe lequel) et un fichier
.svg. - Un navigateur pour voir le rendu : ouvrez-y le fichier, ou collez le code dans une page HTML.
Écrivez chaque exemple, regardez le rendu, modifiez une valeur, regardez à nouveau. C'est en déplaçant les nombres vous-même que le repère de coordonnées devient une intuition.
Les exemples s'appuient sur SVG 2, la spécification du W3C. Les liens de référence sont regroupés en fin de tutoriel.
Étape 1 — La structure : un document SVG minimal
Un SVG est avant tout un document XML : chaque balise doit être correctement fermée. Créez un fichier et tapez le strict minimum.
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="120" viewBox="0 0 200 120"> <rect x="10" y="10" width="180" height="100" fill="none" stroke="black"/> </svg>
Ouvrez le fichier dans un navigateur : vous devez voir un rectangle au trait noir. Tant que ce n'est pas le cas, ne passez pas Ă la suite.
Ce que vous venez d'écrire :
<svg>est la balise racine. L'attributxmlnsdéclare l'espace de noms SVG : sans lui, le navigateur ne traite pas le fichier comme du SVG. C'est l'erreur numéro un du débutant.widthetheightfixent la taille affichée du dessin.viewBoxdéfinit l'espace de dessin interne — on y revient à l'étape 2.<rect>dessine un rectangle ;fill="none"le laisse creux,strokelui donne un contour.
Exercice — Ajoutez, juste après la balise
<svg>, un<title>Mon dessin</title>. C'est le nom de l'image ; nous verrons son rôle à l'étape 10.
Étape 2 — Le repère : coordonnées, viewBox et unités
Tout se joue sur un repère à deux axes : X vers la droite, Y vers le bas
(attention, Y descend, contrairement aux mathématiques). L'origine (0, 0) est
en haut Ă gauche.
La subtilité, c'est la viewBox. Elle vaut min-x min-y largeur hauteur et
définit un repère logique, indépendant de la taille affichée.
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="200" viewBox="0 0 100 50"> <rect x="0" y="0" width="100" height="50" fill="#f2f2f2" stroke="#333"/> <circle cx="50" cy="25" r="10" fill="#3a6ea5"/> </svg>
Ici le dessin raisonne dans un espace de 100 × 50 « unités utilisateur », mais il est affiché sur 400 × 200 pixels. Chaque unité logique est donc étirée par quatre. C'est tout l'intérêt du vectoriel : vous dessinez dans un repère confortable, le navigateur met à l'échelle sans perte.
Ă€ retenir :
viewBoxmappe un repère logique vers la taille affichée.- L'unité par défaut est l'« unité utilisateur », souvent proche du pixel.
- Les valeurs en
%se calculent sur la boîte d'affichage.
Exercice — Changez la
viewBoxen0 0 200 100sans toucher au reste, et observez comment le cercle rapetisse : il occupe désormais une plus petite fraction du repère.
Étape 3 — Les formes de base
Avant les chemins libres, SVG offre des formes prêtes à l'emploi, idéales pour des icônes simples.
<svg xmlns="http://www.w3.org/2000/svg" width="220" height="140" viewBox="0 0 220 140"> <rect x="10" y="10" width="60" height="40" rx="6" fill="#f2c94c"/> <circle cx="120" cy="30" r="20" fill="#3a6ea5"/> <ellipse cx="180" cy="30" rx="25" ry="15" fill="#2d9cdb"/> <line x1="10" y1="80" x2="210" y2="80" stroke="#333" stroke-width="2"/> <polyline points="10,110 60,90 110,110 160,90 210,110" fill="none" stroke="#0f2d40" stroke-width="2"/> <polygon points="60,130 90,100 120,130" fill="#eb5757"/> </svg>
rect: rectangle ;rx/ryarrondissent les coins.circle: cercle défini par son centrecx/cyet son rayonr.ellipse: deux rayons,rxetry.line: un segment entre(x1, y1)et(x2, y2).polyline: une suite de points non fermée.polygon: une suite de points fermée automatiquement.
La seule différence entre polyline et polygon est cette fermeture : le
polygone relie son dernier point au premier.
Exercice — Transformez la
polylineenpolygonet donnez-lui unstroke: vous verrez le côté de fermeture apparaître.
Étape 4 — Le style : peindre les formes
Deux propriétés gouvernent l'apparence : fill (l'intérieur) et stroke (le
contour). Vous pouvez les poser en attributs de présentation directement sur
l'élément, ou les mutualiser en CSS.
<svg xmlns="http://www.w3.org/2000/svg" width="220" height="130" viewBox="0 0 220 130"> <style> .accent { fill: #3a6ea5; stroke: #0f2d40; stroke-width: 3; } </style> <rect x="10" y="10" width="80" height="60" class="accent"/> <circle cx="150" cy="40" r="25" fill="none" stroke="#333" stroke-width="4" stroke-dasharray="6 4"/> <rect x="120" y="80" width="80" height="40" fill="#f2c94c" opacity="0.7"/> </svg>
- Les attributs de présentation (
fill,stroke,stroke-width…) sont les plus simples pour démarrer. - Une balise
<style>avec des classes CSS évite de répéter le même style sur plusieurs éléments. stroke-dasharray="6 4"trace un trait en pointillés (6 unités de trait, 4 de vide).opacityrend l'élément entier translucide. À distinguer defill-opacity, qui n'agit que sur le remplissage.
Exercice — Remplacez
opacity="0.7"parfill-opacity="0.7"sur le rectangle jaune et comparez : le contour, lui, redevient opaque.
Étape 5 — Les chemins (path) : dessiner librement
Le <path> est l'élément le plus puissant. Toutes les autres formes pourraient
s'y ramener. Il tient dans un seul attribut, d, une suite de commandes.
<svg xmlns="http://www.w3.org/2000/svg" width="240" height="120" viewBox="0 0 240 120"> <path d="M10 90 L60 20 L110 90 Z" fill="#f2c94c" stroke="#333" stroke-width="2"/> <path d="M140 90 C140 20 220 20 220 90" fill="none" stroke="#3a6ea5" stroke-width="3"/> </svg>
Les commandes essentielles :
M x y— move to : déplace le curseur sans tracer (point de départ).L x y— line to : trace une ligne droite jusqu'au point.Z— ferme le chemin en rejoignant le point de départ.C x1 y1 x2 y2 x y— courbe de Bézier cubique (deux points de contrôle).Q x1 y1 x y— courbe de Bézier quadratique (un seul point de contrôle).
Règle transversale : une commande majuscule utilise des coordonnées
absolues (depuis l'origine), sa version minuscule des coordonnées
relatives (depuis le point courant). L 60 20 va au point (60, 20) ;
l 60 20 avance de 60 vers la droite et 20 vers le bas.
Exercice — Remplacez la courbe
Cdu second chemin par une courbeQ(un seul point de contrĂ´le) et observez comment la forme change.
Étape 6 — Réutiliser : g, defs et use
Dès qu'un dessin se complexifie, on veut grouper et réutiliser. Trois outils répondent à ce besoin.
<svg xmlns="http://www.w3.org/2000/svg" width="240" height="120" viewBox="0 0 240 120"> <defs> <g id="badge"> <circle cx="20" cy="20" r="16" fill="#3a6ea5"/> <text x="20" y="25" text-anchor="middle" font-size="10" fill="white">SVG</text> </g> </defs> <use href="#badge" x="10" y="10"/> <use href="#badge" x="80" y="10"/> <use href="#badge" x="150" y="10"/> </svg>
<g>regroupe plusieurs éléments. Un style ou une transformation posé sur le<g>s'applique à tous ses enfants.<defs>contient des éléments définis mais non dessinés directement : une bibliothèque de motifs à instancier plus tard.<use href="#id">instancie un élément défini ailleurs. Ici, un seul badge décrit, dessiné trois fois à des positions différentes.
C'est le principe « définir une fois, réutiliser partout », qui allège le code et garantit la cohérence.
Exercice — Ajoutez
transform="scale(1.2)"au deuxième<use>pour l'agrandir. La transformation est le sujet de l'étape suivante.
Étape 7 — Les transformations
Une transformation déplace, agrandit ou fait pivoter un élément (ou un groupe).
Elle se pose dans l'attribut transform.
<svg xmlns="http://www.w3.org/2000/svg" width="220" height="120" viewBox="0 0 220 120"> <g transform="translate(20 20) rotate(10)"> <rect x="0" y="0" width="80" height="40" fill="#f2c94c"/> </g> <rect x="140" y="20" width="60" height="60" fill="#3a6ea5" transform="scale(1.1)"/> </svg>
translate(dx dy)— déplace.scale(facteur)— met à l'échelle (attention : agrandit aussi la distance à l'origine).rotate(angle)— fait tourner autour de l'origine ;rotate(angle cx cy)fait tourner autour du point(cx, cy).
Deux points clés :
- Les transformations se cumulent dans l'ordre d'écriture :
translate(...) rotate(...)déplace d'abord, puis tourne dans le repère déplacé. Inverser l'ordre change le résultat. - Posée sur un
<g>, la transformation affecte tout le groupe d'un coup.
Exercice — Faites tourner le second rectangle autour de son propre centre avec
rotate(angle cx cy), en calculantcx/cyau milieu du rectangle.
Étape 8 — Le texte
Le texte SVG est du vrai texte : sélectionnable, zoomable, indexable — pas une image de lettres.
<svg xmlns="http://www.w3.org/2000/svg" width="220" height="120" viewBox="0 0 220 120"> <defs> <path id="arc" d="M20 80 Q110 10 200 80"/> </defs> <text x="20" y="30" font-size="14">Texte simple</text> <text font-size="14" fill="#3a6ea5"> <textPath href="#arc">Texte sur un chemin</textPath> </text> </svg>
<text>se positionne parx/y(leyest la ligne de base, pas le haut des lettres).<tspan>permet de styler ou repositionner une portion du texte (un mot en gras, un retour à la ligne manuel).<textPath href="#id">fait suivre un chemin au texte, en s'appuyant sur un<path>défini dans<defs>.
Exercice — Enveloppez un mot du « Texte simple » dans un
<tspan font-weight="bold">…</tspan>pour le mettre en gras.
Étape 9 — Dégradés et motifs (paint servers)
fill et stroke n'acceptent pas que des couleurs unies : ils acceptent aussi
des serveurs de peinture — dégradés et motifs — définis dans <defs> et
référencés par url(#id).
<svg xmlns="http://www.w3.org/2000/svg" width="220" height="120" viewBox="0 0 220 120"> <defs> <linearGradient id="grad" x1="0" y1="0" x2="1" y2="0"> <stop offset="0%" stop-color="#3a6ea5"/> <stop offset="100%" stop-color="#f2c94c"/> </linearGradient> <pattern id="grid" width="8" height="8" patternUnits="userSpaceOnUse"> <path d="M8 0 H0 V8" fill="none" stroke="#ccc" stroke-width="1"/> </pattern> </defs> <rect x="10" y="10" width="90" height="60" fill="url(#grad)"/> <rect x="120" y="10" width="90" height="60" fill="url(#grid)"/> </svg>
<linearGradient>— un dégradé linéaire, dont la direction est donnée parx1,y1 → x2,y2. Chaque<stop>place une couleur à unoffset(de 0 % à 100 %).<radialGradient>— même principe, mais rayonnant depuis un centre.<pattern>— un motif répété qui pave la forme.- On les applique toujours via
fill="url(#id)".
Exercice — Remplacez
linearGradientparradialGradient(en retirant les attributs de direction) et observez le dégradé rayonner du centre.
Étape 10 — Découper et masquer (clipPath, mask)
Deux techniques pour ne montrer qu'une partie d'un dessin, avec une logique différente.
<svg xmlns="http://www.w3.org/2000/svg" width="220" height="120" viewBox="0 0 220 120"> <defs> <clipPath id="clip"> <circle cx="60" cy="60" r="40"/> </clipPath> <mask id="fade"> <rect width="220" height="120" fill="white"/> <rect x="110" y="0" width="110" height="120" fill="black"/> </mask> </defs> <rect width="220" height="120" fill="#f2c94c"/> <rect width="220" height="120" fill="#3a6ea5" clip-path="url(#clip)"/> <rect width="220" height="120" fill="#0f2d40" mask="url(#fade)"/> </svg>
<clipPath>découpe selon une forme géométrique : ce qui est dedans reste, ce qui est dehors disparaît. C'est une découpe franche, tout ou rien.<mask>module la transparence par niveaux de gris : le blanc laisse voir, le noir cache, les gris rendent semi-transparent. D'où les dégradés de disparition (le fade).
Retenez la distinction : le clip est une paire de ciseaux, le masque est un calque de transparence.
Exercice — Remplacez le
<circle>duclipPathpar un<polygon>pour découper selon une forme anguleuse.
Étape 11 — Les filtres
Les filtres appliquent des effets de traitement d'image (flou, désaturation…) via
un <filter> composé de primitives.
<svg xmlns="http://www.w3.org/2000/svg" width="220" height="120" viewBox="0 0 220 120"> <defs> <filter id="blur"> <feGaussianBlur stdDeviation="3"/> </filter> <filter id="mono"> <feColorMatrix type="saturate" values="0"/> </filter> </defs> <circle cx="60" cy="60" r="30" fill="#3a6ea5" filter="url(#blur)"/> <rect x="120" y="30" width="70" height="60" fill="#f2c94c" filter="url(#mono)"/> </svg>
<feGaussianBlur stdDeviation="…">— un flou gaussien ; plusstdDeviationest grand, plus c'est flou.<feColorMatrix type="saturate" values="0">— ici une désaturation complète (noir et blanc).- On applique un filtre via
filter="url(#id)". - Un mĂŞme
<filter>peut enchaîner plusieurs primitives, la sortie de l'une alimentant l'entrée de la suivante.
Note de performance : les filtres peuvent être coûteux à calculer, surtout sur mobile. Utilisez-les avec parcimonie.
Exercice — Augmentez
stdDeviationdu filtrebluret observez le flou s'intensifier.
Étape 12 — Animer
On peut animer un SVG sans JavaScript, avec les balises d'animation SMIL.
<svg xmlns="http://www.w3.org/2000/svg" width="220" height="120" viewBox="0 0 220 120"> <circle cx="20" cy="60" r="18" fill="#3a6ea5"> <animate attributeName="cx" from="20" to="200" dur="2s" repeatCount="indefinite"/> </circle> </svg>
<animate>fait varier un attribut (icicx) defromĂtosur une durĂ©edur.repeatCount="indefinite"boucle sans fin.<animateTransform>anime une transformation (rotation, translation, Ă©chelle) plutĂ´t qu'un simple attribut.
Deux points de compatibilité, à connaître avant de choisir SMIL :
- Le support de SMIL varie selon les navigateurs et n'est pas garanti partout.
- Pour de la robustesse, on anime souvent
transformouopacityen CSS, qui offre un support plus homogène.
Gardez les animations simples : c'est le meilleur gage de compatibilité.
Exercice — Remplacez
<animate>par un<animateTransform>de typerotatepour faire tourner un élément.
Assembler : un dessin complet
Vous avez maintenant toutes les briques. Un SVG riche les combine dans un ordre naturel :
- La structure (
<svg>,xmlns,viewBox) pose le cadre. <defs>regroupe les ressources réutilisables : dégradés, motifs,clipPath,mask, filtres, éléments à instancier.- Le corps du dessin assemble formes et chemins, organisés en
<g>, peints avecfill/strokeou des serveurs de peinture, positionnés par destransform, complétés de<text>. - Découpes, masques et filtres affinent le rendu ; les balises d'animation lui donnent vie.
Reprenez chaque étape comme une couche que vous empilez consciemment, plutôt que comme une liste d'options isolées.
Pour aller plus loin
- L'accessibilité du SVG est un sujet à part entière : un dessin neuf est
muet pour un lecteur d'écran tant qu'on ne lui ajoute pas, explicitement, un
<title>, une<desc>, les rôles ARIA — ou qu'on ne le masque pas s'il est décoratif. Ce parcours est traité dans le tutoriel dédié « Produire un SVG accessible, pas à pas », à suivre après celui-ci. - Générer du SVG par programme : puisque c'est du texte, un langage serveur ou client peut le produire dynamiquement (graphiques, badges, visualisations de données).
Références W3C
- SVG 2 — Structure : https://www.w3.org/TR/SVG2/struct.html
- SVG 2 — Systèmes de coordonnées, transformations et unités : https://www.w3.org/TR/SVG2/coords.html
- SVG 2 — Formes de base : https://www.w3.org/TR/SVG2/shapes.html
- SVG 2 — Peinture : https://www.w3.org/TR/SVG2/painting.html
- SVG 2 — Style : https://www.w3.org/TR/SVG2/styling.html
- SVG 2 — Chemins : https://www.w3.org/TR/SVG2/paths.html
- SVG 2 — Texte : https://www.w3.org/TR/SVG2/text.html
- SVG 2 — Serveurs de peinture (dégradés, motifs) : https://www.w3.org/TR/SVG2/pservers.html
- SVG 2 — Masquage : https://www.w3.org/TR/SVG2/masking.html
- SVG 2 — Animation : https://www.w3.org/TR/SVG2/animate.html
- Filter Effects 1 : https://www.w3.org/TR/filter-effects-1/
- Guide de rédaction SVG (SVG Authoring) : https://www.w3.org/TR/svg-authoring/