SVG's

  1. Introduction
  2. Fonctionnement
  3. Utilisation
  4. Interactions
  5. Animations
  6. Plugins

1. Introduction

a. Qu'est-ce ?

Le Scalable Vector Graphics est un format de données conçu pour décrire des ensembles de graphiques vectoriels et basé sur XML.

  • Image vectorielle >< Bitmap
  • Générée par le navigateur
  • Basé sur le XML (Code)

b. Bref historique

  • 1999 : Développement par le W3C
    >< PGML (Adobe) et VML (Microsoft)
  • 2001 : Version 1.0
  • 2003 : Version 1.1
  • 2011 : Version 1.1(Second Edition)
  • 2016? : Version 2.0

c. Avantages

  • Code source lisible et facilement modifiable
  • Image vectorielle donc extensible à l’infini (retina !)
  • Accessible lecteurs d’écrans & Moteurs de recherche
  • Possibilité d’interactions avec utilisateur
  • Accessible en  CSS

c. Avantages

500 x 500px

SVG : 4,7Ko

PNG :  15Ko

  • Poids des fichiers

d. Utilisation

Graphiques

d. Utilisation

Cartes

d. Utilisation

Logos

d. Utilisation

Icônes

d. Utilisation

Illustrations vectorielles

d. Utilisation

Backgrounds

d. Utilisation

Exemples en ligne

e. Quand ne pas l’utiliser

  • Images trop complexes
  • Support IE8
  • Surplus de filtres

500 x 125px

SVG : 9,9Ko

PNG :    9Ko

  • Poids des fichiers

e. Quand ne pas l’utiliser

2. Fonctionnement

<svg xmlns="http://www.w3.org/2000/svg" width="500px" height="500px">
<g>
	<path fill="#B68472" d="M179.5,206.5c0,0-37.9,19.1-80.2-29.5c4.2-4.4,42.9-39.2,100.5-11.4L179.5,206.5z"/>
	<path fill="#D76C79" d="M176.8,195.8c0,0-30,6.6-53-16.5c0,0,21.9-20.7,65.2-3.6L176.8,195.8z"/>
	<path fill="#B68472" d="M320.5,206.5c0,0,37.9,19.1,80.2-29.5c-4.3-4.4-42.9-39.2-100.5-11.4L320.5,206.5z"/>
	<path fill="#D76C79" d="M323.2,195.8c0,0,30,6.6,53-16.5c0,0-21.9-20.7-65.2-3.6L323.2,195.8z"/>
</g>
<g>
	<path fill="#B68472" d="M258,416.2c-0.1,0-0.2,0-0.3,0c-2.5,0.1-5.1,0.2-7.8,0.2v34.3c5.6,0,11.2-0.5,16.5-1.4v23.1h36.3v-36.2c24.2-14.7,40.3-39.1,41.6-67.1C344.4,369.2,322.2,412.8,258,416.2z"/>
	<path fill="#8F6552" d="M353.3,329.5c0-54-46.3-97.8-103.3-97.8c-57.1,0-103.3,43.8-103.3,97.8s46.2,97.8,103.3,97.8C307.1,427.2,353.3,383.5,353.3,329.5z"/>
	<path fill="#8F6552" d="M242.4,416.2c-0.2,0-0.5,0-0.7-0.1c-63.3-3.6-86.1-47-86.1-47c1.3,27.9,17.5,52.4,41.6,67.1v36.2h36.3v-23.1c5.4,0.9,10.9,1.4,16.5,1.4v-34.3C247.4,416.4,244.9,416.4,242.4,416.2z"/>
	<path fill="#B68472" d="M250,150.4v215.2v47.3c2.6,0,5.2-0.1,7.8-0.2c0.1,0,0.2,0,0.3,0c39.2-1.5,70.1-20.2,86.4-47c8.1-13.3,12.8-28.3,12.8-44.5C357.2,270.4,350.2,150.4,250,150.4z"/>
	<path fill="#8F6552" d="M206.5,159.7c-20.6,11.1-34.8,31-34.8,31c-26.6,39.6-28.9,98.6-28.9,130.4c0,16.1,5,31.1,12.8,44.5c15.4,26.3,45.1,45.2,86.1,47c0.2,0,0.4,0,0.7,0c2.5,0.1,5,0.2,7.6,0.2v-47.3V150.4C232.9,150.4,218.3,153.4,206.5,159.7z"/>
</g>
<g>
	<path fill="#481910" d="M215,478.6c1.5,0,2.8,1.3,2.8,2.8v7h29.2c0-17.4-14.1-31.6-31.6-31.6c-17.4,0-31.6,14.1-31.6,31.6h28.4v-7C212.2,479.8,213.4,478.6,215,478.6z"/>
	<path fill="#481910" d="M284.3,478.6c1.5,0,2.8,1.3,2.8,2.8v7h29.2c0-17.4-14.1-31.6-31.6-31.6c-17.4,0-31.6,14.1-31.6,31.6h28.4v-7C281.5,479.8,282.8,478.6,284.3,478.6z"/>
</g>
<g>
	<path fill="#F5C799" d="M188.6,251.5c0,16.6,9.7,30.1,21.6,30.1c11.9,0,21.6-13.5,21.6-30.1c0-16.6-9.7-30.1-21.6-30.1C198.3,221.4,188.6,234.9,188.6,251.5z"/>
	<path fill="#F5C799" d="M268.1,251.5c0,16.6,9.7,30.1,21.6,30.1c11.9,0,21.6-13.5,21.6-30.1c0-16.6-9.7-30.1-21.6-30.1C277.8,221.4,268.1,234.9,268.1,251.5z"/>
	<path fill="#481910" d="M200.8,258.5c0,5.2,4.2,9.4,9.4,9.4l0,0c5.2,0,9.4-4.2,9.4-9.4v-14.1c0-5.2-4.2-9.4-9.4-9.4l0,0c-5.2,0-9.4,4.2-9.4,9.4V258.5z"/>
	<path fill="#481910" d="M280.3,258.5c0,5.2,4.2,9.4,9.4,9.4l0,0c5.2,0,9.4-4.2,9.4-9.4v-14.1c0-5.2-4.2-9.4-9.4-9.4l0,0c-5.2,0-9.4,4.2-9.4,9.4V258.5z"/>
	<path fill="#FFFFFF" d="M286.5,244.7c0,3,2.2,5.5,4.9,5.5c2.7,0,4.9-2.5,4.9-5.5c0-3-2.2-5.5-4.9-5.5C288.7,239.3,286.5,241.7,286.5,244.7z"/>
	<ellipse fill="#FFFFFF" cx="211.8" cy="244.7" rx="4.9" ry="5.5"/>
</g>
<g>
	<path fill="#F7E9E5" d="M246,323.8c-3.2,0-5.9,2.6-5.9,5.9c0,3.3,2.6,5.9,5.9,5.9s5.9-2.6,5.9-5.9C251.8,326.4,249.2,323.8,246,323.8z"/>
	<path fill="#F7E9E5" d="M298.4,339.9C283,323.6,263,324,262.1,324c-3.1,0.1-5.5,2.7-5.5,5.8c0.1,3.1,2.6,5.5,5.7,5.5c0,0,0.1,0,0.1,0c0.2,0,15.9-0.2,27.8,12.3c1.1,1.2,2.6,1.8,4.1,1.8c1.4,0,2.8-0.5,3.9-1.5C300.5,345.7,300.6,342.2,298.4,339.9z"/>
	<path fill="#481910" d="M250,316.3c-24.9,0-81.7,22.7-50.1,56.5c17.8-25.2,33.3,18.3,50.1,18.3c17.6,0,32-43.7,50.1-18.2C331.8,339,274.9,316.3,250,316.3z M246,335.5c-3.2,0-5.9-2.6-5.9-5.9c0-3.2,2.6-5.9,5.9-5.9s5.9,2.6,5.9,5.9C251.8,332.9,249.2,335.5,246,335.5z M294.3,349.4c-1.5,0-3-0.6-4.1-1.8c-11.9-12.6-27.6-12.3-27.8-12.3c0,0-0.1,0-0.1,0c-3,0-5.6-2.4-5.7-5.5c-0.1-3.1,2.4-5.7,5.5-5.8c0.9,0,20.9-0.5,36.3,15.9c2.1,2.3,2,5.8-0.2,8C297.1,348.9,295.7,349.4,294.3,349.4z"/>
</g>
<g>
	<path fill="#F49F2C" d="M216.2,118.9c-4.7-12.9-6.4-56.9-5-93.9c0.3-7.1-5.2-13-12.3-13.3c-7.1-0.3-13,5.2-13.3,12.3c-0.4,11.7-0.8,26.2-0.5,41c-0.4,0-0.8-0.1-1.3-0.1c-1.7,0-2.3-0.5-2.8-1.1c-3.6-3.9-4.7-15.3-4.1-22c0.6-7-4.6-13.2-11.6-13.8c-7-0.6-13.3,4.6-13.9,11.6c-0.4,4.5-1.8,27.9,10.7,41.5c5.6,6.2,13.2,9.4,21.8,9.4c0.8,0,1.6-0.1,2.4-0.2c0.8,11,2.2,21.4,4.2,29.9c-3.5,0.2-7,0.1-10.5-0.2c-15.8-1.6-16.3-25.2-16.4-26.3c0-7-5.8-12.7-12.8-12.7c0,0,0,0,0,0c-7.1,0-12.8,5.8-12.8,12.8c0.1,16.5,8.3,48.5,39.4,51.7c9.2,0.9,17.7,0.2,25.1-0.5c2.6-0.2,5.9-0.5,8.7-0.6c0,0,0,0,0.1,0c0,0,0.1,0,0.1,0c2.8-0.1,5.2-0.1,6.1,0.4c0,0,1.2,1.7,1.2,8.1c0,7.1,5.7,12.8,12.8,12.8c7.1,0,12.8-5.7,12.8-12.8c0-12.3-3.1-21.1-9.5-26.9C229.4,121,223,119.3,216.2,118.9z"/>
	<path fill="#F49F2C" d="M349.4,81c-7.1,0.1-12.8,5.6-12.9,12.7c0,1-0.5,24.7-16.3,26.3c-3.5,0.4-7,0.4-10.5,0.2c2-8.5,3.4-18.9,4.2-29.9c0.8,0.1,1.6,0.2,2.4,0.2c8.6,0,16.1-3.3,21.8-9.4c12.5-13.7,11.2-37,10.7-41.5c-0.6-7.1-6.8-12.2-13.9-11.6c-7,0.6-12.3,6.8-11.6,13.9c0.6,6.5-0.6,18.1-4.1,22c-0.5,0.6-1.1,1.1-2.9,1.1c-0.4,0-0.9,0.1-1.3,0.1c0.3-14.8-0.1-29.3-0.5-41c-0.3-7.1-6.3-12.6-13.3-12.3C294.1,12,288.6,18,288.8,25c1.4,36.9-0.3,80.9-5,93.9c-6.8,0.4-13.2,2.2-18.6,7.1c-6.4,5.8-9.5,14.6-9.5,26.9c0,7.1,5.7,12.8,12.8,12.8c7.1,0,12.8-5.7,12.8-12.8c0-6,1.1-7.9,1-7.9c2-1.1,9.9-0.4,15.2,0.1c7.5,0.7,16,1.4,25.1,0.5c31-3.2,39.3-35.2,39.4-51.7C362.1,86.8,356.4,81.1,349.4,81z"/>
</g>
</svg>

a. Figures - Éléments

<rect>


<rect x="0" y="0" width="100" height="100" />

<rect>


<rect x="0" y="0" width="100" height="100" rx="15" ry="15"/>

a. Figures - Éléments

<circle>


<circle cx="50" cy="50" r="50" />

<ellipse>


<ellipse cx="50" cy="50" rx="50" ry="30"/>

a. Figures - Éléments

<line>


<line x1="0" y1="0" x2="100" y2="100" stroke="black" stroke-width="2"/>

<polygon>


<polygon points="0,0 100,40 100,80 60,100 20,80 20,40" />

a. Figures - Éléments

<polyline>


<polyline fill="none" stroke="black" points="20,100 40,60 70,80 100,20"/>

a. Figures - Éléments

<path>


<path d="M47.1,90.7c-2-2.3-7.2-6.8-11.3-9.9C23.3,71.4,21.6,70,16.6,65.4C7.3,56.8,
3.3,48.2,3.3,36.6c0-5.7,0.4-7.9,2-11.3C8,19.6,12,15.4,17.1,12.8c3.6-1.8,5.4-2.6,
11.4-2.7c6.3,0,7.6,0.7,11.3,2.7c4.5,2.5,9.2,7.8,10.1,11.6l0.6,2.3l1.5-3.2C60.3,
5.4,86.7,5.7,95.9,24c2.9,5.8,3.2,18.2,0.7,25.2c-3.4,9.1-9.7,16-24.3,26.7c-9.6,
7-20.5,17.5-21.2,19C50.1,96.5,51,95.1,47.1,90.7z"/>

a. Figures - Éléments

<text>

<tspan>


<text x="20" y="40" font-size="55">Hello World !</text>

<text x="20" y="40" font-size="55">
    <tspan fill="red">Hello</tspan> World !
</text>

a. Figures - Éléments

<image>


<image xlink:href="reindeer.png" x="0" y="0" height="100" width="100" />  

<g>


<g>
    <!-- Whatever -->
</g>

b. Les attributs

  • x, y, x1, y1, x2, y2

  • cx, cy

  • r, rx, ry

  • d

  • width, height

  • fill

  • stroke, stroke-width, stroke-dasharray, stroke-dashoffset,
    stroke-linecap, stroke-linejoin

  • opacity, fill-opacity, stroke-opacity

  • filter

  • font-family, font-size, font-style, font-weight, text-anchor

  • xlink:href

  • clip-path, mask

b. Les attributs

La plupart sont accessibles en CSS !

c. Coordinate system

Coordonnées initiales

  • Origines à 0 0 (en haut à gauche)
  • Axe X positif vers la droite
  • Axe Y positif vers le bas 
  • Une unité = 1 pixel

b. Coordinate system

Viewport

  • Zone visible du SVG
  • Viewport du navigateur
  • Défini par "width" & "height"
  • Unités acceptées : px, em, %, ...
  • Les éléments en dehors du viewport ne seront pas dessinés

Démo

b. Coordinate system

viewBox

  • Propriété du tag <svg>
  • Permet de définir une zone toujours visible
  • viewBox="min-x min-y width height"
  • La zone définie aura un effet similaire à
  • un background-size : contain;
  • Si ratio viewport != ratio viewBox, certains éléments en dehors du viewBox peuvent être apparents
  • Le système de coordonnées est redéfini et mis à l'échelle

Démo

b. Coordinate system

preserveAspectRatio

  • Propriété du tag <svg>
  • preserveAspectRatio="<align> <meetOrSlice>"
  • Défini comment le viewBox s'aligne dans le viewport
  • Défini si le viewBox peut être rogné ou doit toujours être affiché (// contain vs cover)
  • none
  • xMinYMin
  • xMidYMin
  • xMaxYMin
  • xMinYMid
  • xMidYMid
  • xMaxYMid
  • xMinYMax
  • xMidYMax
  • xMaxYMax
  • meet
  • slice

Démo

3. Utilisation

a. Importer un SVG

<img>


<img src="reindeer.svg" width="500" height="500" />

CSS background


.el{
    background-image: url(mysvg.svg);
}

Inline


<svg>
    <rect x="0" y="0" width="10" height="10" />
</svg>

Pas besoin de doctype !

a. Importer un SVG

<object>


<object type="image/svg+xml" data="mysvg.svg">
    <img src="mypng.png" alt="Pretty PNG" />
</object>
<object type="image/svg+xml" data="mysvg.svg">
    <div class="fallBackSVG"></div>    
</object>

Pour ne pas charger 2 images

Démo

b. Exporter depuis Adobe Illustrator

b. Exporter depuis Adobe Illustrator

b. Exporter depuis Adobe Illustrator

b. Exporter depuis Adobe Illustrator

Copier-Coller !

Clean your SVG

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" 
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="500px" height="500px" 
viewBox="0 0 500 500" style="enable-background:new 0 0 500 500;" xml:space="preserve">

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" 
width="500px" height="500px" viewBox="0 0 500 500">

4. Interactions

a. Liens

<a xlink:href="http://www.google.com/" target="_blank">
    <path fill="#481910" d="M250,316.3c-24.9,0-81.7,22.7-50.1,56.5c17.8-25.2,33.3,
    18.3,50.1,18.3c17.6,0,32-43.7,50.1-18.2C331.8,339,274.9,316.3,250,316.3z M246,
    335.5c-3.2,0-5.9-2.6-5.9-5.9c0-3.2,2.6-5.9,5.9-5.9s5.9,2.6,5.9,5.9C251.8,332.9,
    249.2,335.5,246,335.5z M294.3,349.4c-1.5,0-3-0.6-4.1-1.8c-11.9-12.6-27.6
    -12.3-27.8-12.3c0,0-0.1,0-0.1,0c-3,0-5.6-2.4-5.7-5.5c-0.1-3.1,2.4-5.7,
    5.5-5.8c0.9,0,20.9-0.5,36.3,15.9c2.1,2.3,2,5.8-0.2,8C297.1,348.9,295.7,349.4,
    294.3,349.4z"/>
</a>

<a xlink:href="...">

<object> et inline seulement

Démo

b. CSS Pseudo-classes

.nez:hover{
    fill: red;
}

:hover

a:focus path{
    fill: green;
}

:focus

Démo

c. Javascript events

var nose = document.querySelector(".nose");
nose.addEventListener("click", function(){
    this.classList.toggle("clicked");
});

.addEventListener()

var svg = document.querySelector("#reindeer");
svg.addEventListener("load", function(){
    var nose = svg.getSVGDocument().querySelector(".nose");
    nose.addEventListener("click", function(){
        this.classList.toggle("clicked");
    });
});

Si <object>

! serveur

Démo

d. Pointer-events

Seule la zone peinte d'un élément est interactive.

Exemple : <rect fill="none" stroke="red" [...] /> ne sera cliquable que sur son contour.

Il faut utiliser la propriété pointer-events pour définir la zone interactive.

visiblePainted | visibleFill | visibleStroke | visible

painted | fill | stroke | all | none | inherit

Démo

5. Animations

a. CSS Transitions

.nose{
    transition : 1s;
    transform-origin: 249.5px 353px; 
}
.nose path:last-child{transition: 1s;}
.nose:hover{
    transform: scale(1.2);
}
.nose:hover path:last-child{
    fill:red;
}

Pas de support actuellement sous Internet Explorer

Démo

b. CSS Animations


.leftEye{
    transform-origin: 210px 251px;
    animation: rotateEye 0.7s infinite alternate ease-out;
}
@keyframes rotateEye{
    to{transform:rotate(360deg);}
}

Pas de support actuellement sous Internet Explorer

Démo

c. GreenSock

TweenMax.set(".leftHorn",{"transformOrigin":"right bottom"});
TweenMax.set(".rightHorn",{"transformOrigin":"left bottom"});
TweenMax.set(".eye",{"transformOrigin":"center center"});
TweenMax.set(".leftFoot",{y:10});
TweenMax.set(".rightFoot",{y:-10});
var horns = new TimelineMax({repeat:-1, yoyo:true});
horns.to(".leftHorn", 0.8,{rotation:-10});
horns.to(".rightHorn", 0.8,{rotation:10}, "-=0.8");
var eyeBlink = new TimelineMax({repeat:-1, repeatDelay:2});
eyeBlink.to(".eye", 0.1,{scaleY:0, repeat:1, yoyo:true});
var feet = new TimelineMax({repeat:-1});
feet.to(".leftFoot", 0.5,{y:-10, ease:Linear.easeNone});
feet.to(".rightFoot", 0.5,{y:10, ease:Linear.easeNone}, "-=0.5");
feet.to(".rightFoot", 0.5,{y:-10, ease:Linear.easeNone});
feet.to(".leftFoot", 0.5,{y:10, ease:Linear.easeNone}, "-=0.5");
TweenMax.fromTo(".road", 1,{y:40}, {y:-70, repeat:-1, ease:Linear.easeNone});

Démo

6. Plugins

a. Raphaël

b. D3.js

c. Highcharts

d. IcoMoon