Rendre un SVG responsif
Infiniment redimensionnable, le format SVG n'en est pas moins étonnamment difficile à rendre responsif. Dudley Storey montre comment y parvenir.
Pour un format d’image infiniment redimensionnable, SVG peut être étonnament difficile à rendre responsif : les images vectorielles ne s’ajustent pas par défaut à la taille du viewport.
Une image SVG responsive
En tant qu’image, votre SVG peut se redimensionner avec le contenu de la page, comme tous les autres :
<img src="monkey.svg" alt="Monkey face" style="width: 100%; height: auto;">
Ça fonctionne dans la plupart des cas, mais parfois ce n’est pas suffisant, surtout si vous embarquez votre SVG via une balise <object>
ou en insérant le code directement dans la page. Dans ce cas, la simple modification de width
et height
ne suffit pas.
Un SVG en ligne responsif
Le code SVG embarqué, une fois collé dans le <body>
d’un document HTML, ressemblera à ceci :
<body>
<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" enable-background="new 0 0 500 500" xml:space="preserve">
<circle fill="#F7941E" stroke="#231F20" stroke-width="10" cx="250" cy="250" r="200" opacity="0.6" />
</svg>
</body>
Une fois l’élément racine <svg>
nettoyé, le code est beaucoup plus présentable :
<svg version="1.1" viewBox="0 0 500 500">
<circle fill="#F7941E" stroke="#231F20" stroke-width="10" cx="250" cy="250" r="200" opacity="0.6" />
</svg>
La suppression des attributs redondants de l’élément <svg>
rend l’illustration responsive, mais il y a un coût : cela ajoute un espace au-dessus et en-dessous de l’image vectorielle. On pourrait supposer que le coupable est l’attribut viewport
, qui est toujours présent, mais ce n’est pas le cas, laissons-le tranquille. Il nous reste trois étapes pour intégrer l’élément SVG responsif dans notre page :
Tout d’abord, entourons le code SVG avec une <div>
et ajoutons un attribut preserveAspectRatio
, ainsi qu’une classe à l’élément racine svg
:
<div class="svg-container">
<svg version="1.1" viewBox="0 0 500 500" preserveAspectRatio="xMinYMin meet" class="svg-content">
<circle fill="#F7941E" stroke="#231F20" stroke-width="10" stroke-miterlimit="10" cx="250" cy="250" r="200" opacity="0.6" />
</svg>
</div>
Cela déplace l’illustration SVG en haut de son conteneur. Pour terminer la présentation, nous utilisons une variante de la vieille astuce de l’élément-absolument-positionné-dans-un-conteneur-relatif avec un padding décalé :
.svg-container {
display: inline-block;
position: relative;
width: 100%;
padding-bottom: 100%;
vertical-align: middle;
overflow: hidden;
}
Remarquez que la width
utilisée dans le CSS suppose que vous voulez que votre image couvre toute la largeur de la page (ou tout au moins de son conteneur parent). Le padding-bottom
a pour valeur le ratio entre la hauteur et la largeur de l’illustration SVG. En divisant la hauteur du viewbox
de l’élément par sa largeur, on obtient ici un ratio de 1:1 (voir plus haut : viewBox="0 0 500 500"
), et par conséquent le padding-bottom doit être fixé à 100%. Si l’image SVG était plus large que haute, par exemple dans un ratio 1:2, le padding-bottom
serait fixé à 50%.
Enfin, on positionne le SVG à l’intérieur du conteneur avec un petit CSS :
.svg-content {
display: inline-block;
position: absolute;
top: 0;
left: 0;
}
Avec cette solution, notre illustration SVG peut se redimensionner gracieusement sur la page sans déranger les autres contenus. Le même code fonctionne sur une balise <object>
utilisée pour embarquer le dessin vectoriel :
<div class="svg-container">
<object type="image/svg+xml" data="samurai.svg" width="100%" height="100%" class="svg-content">
</object>
</div>
Attention : tout le contenu situé à l’intérieur de sera redimensionné, y compris le texte.