SVG : Scalable Vector Graphics dans une page HTML

LE code des images SVG (Scalable Vector Graphics) est interprété par les navigateurs WEB et peut donc être intégré dans une page HTML. L syntaxe est par contre celle de XML, plus stricte que le HTML. Cette page donne le minimum à connaître pour écrire des images SVG sans passer par un éditeur de telles images.

Une connaissance minimale du HTML est préférable, voyez cette page. La syntaxe du XML, dans laquelle est écrite une image SVG, est plus susceptible que celle du HTML. Par exemple, toute balise ouverte doit être fermée, par exemple toute la description doit se faire entre les balises <svg> et </svg>. Les balises qui ne sont pas englobantes peuvent être auto-fermées par une barre, comme par exemple <line x1="8" y1="5" x2="59" y2="19" />

Page commencée le 2025.01.18 ; elle est testée avec FireFox 128.6.0esr et Chromium 132.0.6834.83 sur GNU/Linux Debian 12 Bookworm (64 bits)

1. Généralités

1.1 Utilisez les styles
1.2 viewbox

2. Éléments simples

2.1 Rectangle
2.2 Cercles
2.3 Ellipse
2.4 Lignes

3. Éléments complexes

3.1 Polygones
3.2 Polyline
3.3 Path

4. Textes

5. Image

6. Liens

7. Attributs graphiques

7.1 Couleurs
7.2 Traits
7.3 Transformations

1. Généralités

Typiquement, un graphique SVG défini de la sorte produira un rectangle :

<svg width="200" height="100" style="border:1px grey solid" xmlns="http://www.w3.org/2000/svg">
<rect x="75" y="20" width="80" height="40" stroke="cyan" stroke-width="3" fill="yellow" />
</svg>

1.1 Utilisez les styles

La bonne intégration du SVG dans le HTML permet que des attributs contenus dans la balise puissent être regroupés dans un attribut style="" :

<rect x="75" y="20" width="80" height="40" style="stroke:cyan; stroke-width:3; fill:yellow" />

…ou encore faire l’objet d’une classe définie entre les balises <style> et </style> de début de page HTML.

<html><head>
<style>
.ua { stroke:cyan; stroke-width:3; fill:yellow; }
</style>
</head><body>

<svg width="300" height="200" xmlns="http://www.w3.org/2000/svg">
<rect class="ua" x="75" y="20" width="80" height="40" />
</svg>

</body></html>

<g> permet de grouper des éléments pour leur appliquer les mêmes attributs :

<svg width="90" height="65" xmlns="http://www.w3.org/2000/svg" style="border:1px solid #777">
<g fill="cyan" stroke="blue" stroke-width="6">
<rect x="10" y="10" width="70" height="30" />
<circle cx="55" cy="40" r="15" />
</g>
</svg>

Les attributs graphiques sont explicités au chapitre 7. Attributs graphiques.

1.2 L’importance de l’attribut viewbox

Les attributs des balises SVG contiennent souvent des nombres, qui représentent a priori les coordonnées en pixels. Voici un exemple :

<svg width="200" height="100" style="border:1px solid #777">
<rect x="10" y="10" width="40" height="20">
</svg>

Mais comme les graphiques doivent pouvoir s’afficher à n’importe quelle échelle («scalable»), il existe un attribut permettant d’agrandir ou diminuer le contenu d’un graphique SVG. viewbox="0 0 400 200" oblige SVG à considérer l’espace réservé de 200×100 comme deux fois plus grand. L’affichage de ses éléments est de ce fait diminué de moitié :

<svg width="200" height="100" viewbox="0 0 400 200" style="border:1px solid #777">
<rect x="10" y="10" width="40" height="20">
</svg>

Avec viewbox="0 0 100 50", l’espace réservé par SVG sera considéré comme diminué de moitié et les dimensions du rectangles seront doublées :

<svg width="200" height="100" viewbox="0 0 100 50" style="border:1px solid #777">
<rect x="10" y="10" width="40" height="20">
</svg>

Ci-dessous, viewbox="10 5 200 100" conserve les proportions du rectangle mais supprime les marges de gauche de 10 pixels et de droite de 5 premiers pixels :

<svg width="200" height="100" viewbox="10 5 200 100" style="border:1px solid #777">
<rect x="10" y="10" width="40" height="20">
</svg>

viewbox="8 3 100 50" supprime 8 pixels de la marge de gauche et 3 de la marge du haut du rectangle puis double les proportions du rectangle, en ce compris les marges résiduelles, à savoir respectivmement (10 -8) *2 =4 et (10 -3) *2 =14 :

<svg width="200" height="100" viewbox="8 3 100 50" style="border:1px solid #777">
<rect x="10" y="10" width="40" height="20">
</svg>

Note : Si les dimensions de l’image ne sont pas proportionnelles à celles de viewbox,

<svg width="200" height="100" viewbox="8 3 100 20" style="border:1px solid #777">
<rect x="10" y="10" width="40" height="20">
</svg>

2. Éléments simples

2.1 Rectangle

En dehors des éléments vus plus haut, il est possible d’arrondir les angles d’un rectangle :

<svg width="150" height="100" style="border:1px grey solid" xmlns="http://www.w3.org/2000/svg">
<rect x="15" y="10" width="120" height="80" rx="30" ry="15" />
</svg>

2.2 Cercles

Les cercles sont définis par :

<svg width="100px" height="100px">
<circle cx="50" cy="50" r="44" stroke="#b07" stroke-width="5px" fill="#ff7" />
</svg>

2.3 Ellipse

Les ellipses sont définies comme les cercles, mais avec deux rayons, rx et ry

<svg width="100px" height="100px">
<ellipse cx="50" cy="50" rx="30" ry="44" stroke="#70b" stroke-width="5px" fill="7ff" />
</svg>

2.4 Lignes

Une ligne simple est définie par les coordonnées de deux points, x1, y1 et x2, y2. Cet élément est sensible aux attributs de couleur et de trait.

<svg width="120px" height="120px" style="border:1px grey solid">
<line x1="40" y1="15" x2="110" y2="90" style="stroke:purple; stroke-width:6; fill:white;" />
</svg>

L’attribut stroke-linecap= permet de définir les fins de ligne :

3. Éléments complexes

3.1 Polygones

Les polygones sont définis par un ensemble de coordonnées de points. L’abscisse et l’ordonnée de chaque point sont reliés par une virgule, ces couples de valeurs sont séparés par une espace. La figure est nécessairement «fermée», c’est-à-dire que le dernier point est relié au premier. Cet élément est sensible aux attributs de couleur et de trait.

<svg width="200px" height="200px" style="border:1px grey solid">
<polygon points="40,40 160,30 180,140 30,180" style="stroke:blue; stroke-width:2; fill:yellow;" />
</svg>

3.2 Polyline

Il s’agit d’un polygone non fermé, qu’il est néanmoins possible de remplir. Les points sont définis leurs abscisse,ordonnée séparées par des espaces. Cet élément est sensible aux attributs de couleur et de trait.

<svg width="200px" height="200px" style="border:1px grey solid">
<polyline points="20,40 100,100 180,50 160,100 180,160 40,140" style="stroke:darkgreen;stroke-width:4;fill:lime;" />
</svg>

3.3 Path

Path est un polyline sophistiqué comprenant des courbes et qui peut utiliser des coordonnées relatives aux précédentes, et donc des valeurs parfois négatives. Cet élément est sensible aux attributs de couleur et de trait.

Segments de droites

<svg width="200px" height="150px" style="border:1px grey solid">
<path d="m 10 20 l 70 70 L 110 50 h 50 v 80 h -70 l 25 -25 m 0 15 l 30 -25" style="stroke:darkgreen;stroke-width:4;fill:lime;" />
</svg>

Les lettres majuscules indiquent des coordonnées absolues, les minuscules des coordonnées relatives, qui peuvent être négatives.

Note : Les lettres peuvent être collées aux nombres. M 20 20 h 50 peut s’écrire M20 20h50.

Courbes

Les courbes de Bézier permettent un chemin flexible. Les graphiques ci-dessous indiquent en rouge les points et tangentes qui permettent au navigateur de dessiner les courbes. Ils ont dû être expressément ajoutés mais ne sont pas repris dans l’explicitation du code XML ci-dessous :

<svg width="440" height="240" style="border:1px grey solid">
<path d="M 40 40 C 40 100, 180 100, 140 40" style="stroke:black;stroke-width:2;fill:none" />
<path d="M 40 150 S 100 210, 140 150" style="stroke:black;stroke-width:2;fill:none" />
<path d="M 220 20 Q 280 80, 320 20" style="stroke:black;stroke-width:2;fill:none" />
<path d="M 200 160 Q 260 220, 280 160 T 400 140" style="stroke:black;stroke-width:2;fill:none" />
</svg>

C S Q Q+T

S et Q paraissent très proches ; néanmoins :

<svg width="200px" height="200px" style="border:1px grey solid">
<path d="M 40 50 Q 120 180, 160 50" style="stroke:red;stroke-width:3;fill:none;stroke-opacity:1" />
<path d="M 40 50 S 120 180, 160 50" style="stroke:green;stroke-width:3;fill:none;stroke-opacity:0.5" />
</svg>

Note : comme pour le graphique précédent, le point de contrôle et les segments tangeants ont été ajoutés mais ne figure pas sur le code expliqué.

Ellipse orientée

<svg width="150px" height="120px" style="border:1px grey solid">
<path d="M 110 10 A 20 40 -45 0 1 60 30" style="stroke:black;stroke-width:2;fill:none" />
<path d="M 70 60 A 20 40 -45 0 1 20 80 z" style="stroke:black;stroke-width:2;fill:none" />
</svg>

4. Textes

<svg width="200px" height="140px" style="border:1px grey solid">
<text x="20" y="50" stroke="black" stroke-width="2" fill="none" font-size="48">H-W</text>
<text x="10" y="90" stroke="gray" font-size="24">Bonjour, monde!</text>
<a href="http://jchr.be/" target="_blank"><text x="100" y="120" fill="#b04">jchr.be</text></a>
</svg>

H-W Bonjour, monde!

textPath

Pour qu’un texte suive une courbe définie par path :

<svg width="300px" height="240px" style="border:1px grey solid">
<path id="cosh" d="M 20 30 q 150 250, 250 0" stroke="transparent" fill="none" />
<text style="fill:blue;font-size:32px;">
<textPath href="#cosh" startOffset="50">Bonjour, le monde!</textPath>
</text>
</svg>

Bonjour, le monde!

5. Image

Pour inclure une image SVG sous forme de fichier, celui-ci doit commencer par <?xml version="1.0" encoding="utf-8"?> et la balise <svg> doit contenir xmlns="http://www.w3.org/2000/svg" pour que FireFox l’affiche. Le logiciel libre inkscape produit ce genre de fichiers, qui sont lus par le logiciel libre Image-Magick et les afficheurs d’images des bureaux GNU/Linux (Plasma, Gnome, Mate-desktop…).

Exemple de fichier d’image SVG sauvegardé sous le nom svg.svg :

<?xml version="1.0" encoding="utf-8"?>
<svg width="180" height="50" xmlns="http://www.w3.org/2000/svg" style="background:#fea">
<text x="10" y="30" stroke="black" font-size="18">Bonjour, monde!</text>
</svg>

Note : il existe des fichiers compressés SVGZ, mais ils sont déconseillés du fait d’être rarement reconnus.

Afficher un fichier SVG dans une page HTML

Les balises <object> et <iframe> permettent d’afficher un fichier svg.svg dans une page HTML :

<object data="svg.svg" type="image/svg+xml"></object>

<iframe src="svg.svg"></iframe>

Il est également possible d’inclure un fichier SVG (PNG ou JPG) dans une image SVG :

<svg width="300px" height="220px" viewbox="0 0 100 100" style="border:1px solid #777">
<text x="0" y="20" style="font-size:12px;">L’image svg.svg :</text>
<image href="svg.svg" x="0" y="30" width="100" height="50" />
</svg>

L’image svg.svg :

6. Liens

Tout élément inclut entre <a href=""> et </a> peut servir de lien à cliquer. Dans l’exemple suivant, le disque bleu pointe vers le moteur de recherche duckduckgo.com, «jchr.be» vers le site qui héberge la présente page.

<svg width="200px" height="135px" style="border:1px grey solid">
<a href="http://duckduckgo.com/" target="_blank"><circle cx="60" cy="55" r="40" fill="#40b" /></a>
<a href="http://jchr.be/" target="_self"><text x="100" y="115" fill="#b04">jchr.be</text></a>
</svg>

jchr.be

7. Attributs graphiques

Il peut être judicieux d’insérer les attributs graphiques dans un attribut style="" ou dans des classes, définies entre les balises <style> et </style> de début de page HTML.

7.1 Couleurs et opacité

stroke="" définit la couleur du trait qui entoure une forme géométrique
fill="" définit la couleur du remplissage de l’intérieur d’une figure, ou de l’épaisseur du trait (text)

La définition d’une couleur peut se faire :

stroke-opacity="" détermine l’opacité du trait-contour
fill-opacity="" détermine l’opacité de la couleur du corps de la figure

L’opacité va de 0.0 ou transparent à opaque 1.0 (par défaut). Il est possible de la préciser avec un pourcentage dans les formules rgb(24 56 200 / 40%) et hsl(60 80% 60% / 40%)

<svg width="120", height="120" style="border:solid 1px #777">
<rect x="10" y="20" width="100", height="40" fill="#f77" />
<rect x="20" y="10" width="40", height="100" fill="rgb(0 255 255 / 50%)" />
</svg>

Dégradés de couleurs

Il existe deux formes de dégradés : le gradient linéaire et le radial.

linearGradient définit les couleurs et leur proportionnalité selon un sens. l'id="" permet un appel à cette définition de la balise de l'élément coloré

<svg width="150" height="100" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <linearGradient id="rasta" x1="0" y1="0" x2="1" y2="0">
      <stop offset="0%" stop-color="darkgreen" />
      <stop offset="50%" stop-color="yellow" />
      <stop offset="100%" stop-color="red" />
    </linearGradient>
  </defs>
  <rect x="0" y="0" width="150" height="100" fill="url(#rasta)" />
</svg>

Il est possible d'inverser le sens du dégradé en intervertissant les valeurs de x1 et x2, ou de changer de direction en intervertissant les valeurs des x et des y, voire faire un dégradé oblique en jouant avec ces paramètres.

radialGradient permet un dégradé du centre vers l'extérieur.

<svg width="100" height="100" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient id="cocarde">
<stop offset="0%" stop-color="#0f0" />
<stop offset="70%" stop-color="#0bb" />
<stop offset="100%" stop-color="#d0f" />
</radialGradient>
</defs>
<circle cx="50" cy="50" r="50" fill="url(#cocarde)" />
</svg>

Il est possible de décentrer la cocarde de couleur, par exemple avec

<radialGradient id="cocarde" cx="0.6" cy="0.4" r="0.6">

spreadMethod="" définit le comportement lors du dépassement de la définition :

+ gradientUnits="objectBoundingBox" ou userSpaceOnUse + gradientTransform

7.2 Attributs de trait

Largeur de trait

stroke-width="" détermine l’épaisseur du trait-contour de la figure (1 par défaut). Attention : c’est le centre du trait qui satisfait aux grandeurs indiquées.

Discontinuité

L’attribut stroke-dasharray="" définit un mode de discontinuité, défini par une succession de nombres précisant successivement la couleur et la transparence ; en cas de nombre impair de nombres, la succession s’inverse. Pour "12 6 2" :

xxxxxxxxxx······xx··········xxxxxx·· etc.
<svg width="200px" height="200px" style="border:1px grey solid">
<polyline points="20,40 100,100 180,50 160,100 180,160 40,140" stroke-dasharray="10 6 2" stroke-width="4" fill="darkgreen" />
</svg>

Notes : des pourcentages sont possibles, stroke-dasharray="6% 2%"

Décorations de ligne

L’attribut stroke-linecap="" définit les fins de ligne :

<svg width="180px" height="120px" style="border:1px grey solid">
<line x1="30" y1 ="30" x2="30" y2="90" stroke-width="20" stroke-linecap="square" stroke="purple" fill="tranparent" />
<line x1="55" y1 ="30" x2="55" y2="90" stroke-width="1" stroke="black" />
<line x1="80" y1 ="30" x2="80" y2="90" stroke-width="20" stroke-linecap="butt" stroke="purple" />
<line x1="105" y1 ="30" x2="105" y2="90" stroke-width="1" stroke="black" />
<line x1="130" y1 ="30" x2="130" y2="90" stroke-width="20" stroke-linecap="round" stroke="purple" />
</svg>

L’attribut stroke-linejoin="" définit les jointures d’angle d’une ligne brisée :

<svg width="300px" height="160px" style="border:1px grey solid">
<polyline points="30,20 70,60 30,100 70,140" stroke-width="20" stroke-linejoin="miter" stroke="blue" fill="none" />
<polyline points="130,20 170,60 130,100 170,140" stroke-width="20" stroke-linejoin="bevel" stroke="blue" fill="none" />
<polyline points="230,20 270,60 230,100 270,140" stroke-width="20" stroke-linejoin="round" stroke="blue" fill="none" />
</svg>

Et encore…

fill-rule, stroke-miterlimit, stroke-dashoffset

offset, offset-path, offset-anchor, offset-distance, offset-path, offset-position, offset-rotate

7.3 Transformations

L'attribut transform="" permet d'appliquer des modifications à un élément ou à un ensemble d'éléments regroupés avec <g></g>. Il est possible d'enchaîner deux ou plusieurs transformations au même élément en les séparant d'une espace :

transform="scale(10,20) rotate(45)"

Translation

"translate(,)" déplace un élément sans devoir modifier tous ses attributs de coordonnées.

<svg width="100" height="100" style="border:1px solid #999">
<circle cx="60" cy="0" r="40" fill="#777" />
<circle cx="60" cy="0" r="40" transform="translate(-20,20)" fill="green" fill-opacity="0.5" />
</svg>

Rotations

rotate() opère une rotation de l'élément, le premier paramètre est l'angle de rotation (horaire), transform-origin="dx dy" définit le point fixe de la rotation, mais il semble que transform="rotate(30)" peut également faire l'affaire.

<svg width="100" height="100" style="border:1px solid #999">
<ellipse cx="50" cy="50" rx="28" ry="40" fill="#444" />
<ellipse cx="50" cy="50" rx="28" ry="40" transform="rotate(50)" transform-origin="50 50" fill="green" fill-opacity="0.5" />
</svg>

Attention : Lors d'une composition de transformations, la seconde tient compte du changement de coordonnées de la première. Dans l'exemple ci-dessous, la translation «horizontale» devient de ce fait oblique (avec le rectangle bleu comme résultat intermédiaire) :

<svg width="100" height="100" style="border:1px solid #777">
<rect x="10" y="20" width="40" height="20" fill="#777" />
<rect x="10" y="20" width="40" height="20" transform="rotate(30)" transform-origin="30 30" fill="blue" fill-opacity="0.5" />
<rect x="10" y="20" width="40" height="20" transform="rotate(30) translate(45,0)" transform-origin="30 30" fill="green" fill-opacity="0.5" />
</svg>

Échelle

scale() permet de diminuer ou agrandir un élément ; il est possible de prévoir deux rapports différents pour les dimensions. transform-origin="" détermine le point fixe de la transformation.

<svg width="100" height="100" style="border:1px solid #777">
<rect x="10" y="10" width="40" height="20" fill="#777" />
<rect x="10" y="10" width="40" height="20" transform="scale(1.8)" fill="red" fill-opacity="0.5" />
<rect x="10" y="10" width="40" height="20" transform="scale(0.7,3)" fill="green" fill-opacity="0.5" transform-origin="10 10" />
</svg>

Cisaillements

skewX() et skewX() provoquent un cisaillement horizontal (rose) et vertical (vert) ; il est possible de préciser le point fixe de la transformation avec transform-origin="x y".

<svg width="100" height="100" style="border:1px solid #777">
<rect x="10" y="10" width="40" height="20" fill="#777" />
<rect x="10" y="10" width="40" height="20" transform="skewX(30)" fill="red" fill-opacity="0.5" transform-origin="30 20" />
<rect x="10" y="10" width="40" height="20" transform="skewY(45)" fill="green" fill-opacity="0.5" />
</svg>