Des images vectorielles désormais adaptatives

Je l'avoue ... je vous ai menti jusqu'à présent. Vous avez pu remarquer que pour les pages précédentes de ce tuto et même sur le petit écran d'un smartphone les zones de dessin SVG s'adaptent parfaitement à l'écran alors qu'officiellement elles font le plus souvent 900 pixels de large. Or sur un écran de smartphone vous n'avez jamais 900 pixels de large.

En fait le code SVG que je vous ai indiqué dans les pages précédentes de ce tuto n'est pas le vrai code !
Ainsi vous avez souvent lu que le code de la balise SVG était par exemple : <svg width = '900' height = '600' ...
Alors qu'en fait le code réel était : < svg width = '100%' height = 'auto' ...viewBox ="0 0 900 600" ...

L'attribut viewBox de la balise SVG est incontournable lorsqu'on veut que l'image vectorielle soit adaptative c'est à dire s'affiche correctement sur tous les écrans (ordinateur de bureau ou smartphone).

Coucher de soleil sur la mer : code erroné

Le code correspondant

... <style> .orange_demi {fill-opacity : 0.5 ; fill : orange ; } ... <svg width ="800" height ="400" style ="background :skyblue;" > <defs> <filter id="flou"> <feGaussianBlur stdDeviation="9" /> </filter> </defs> <circle cx="400" cy="200" r="100" class ='orange_demi' filter ="url(#flou)"/> <rect x ='0' y = '200' width = '800' height = '200' fill = 'navy' fill-opacity ="0.7" /> </svg> ...

Quand vous affichez cette page avec votre smartphone en mode portrait le texte apparait en caractères minuscules (et est donc illisible).
En effet le navigateur veut afficher tout le canevas SVG et donc il "dézoome" la page.
Et si vous zoomez pour rendre le texte lisible le canevas est alors rogné à droite. Donc tout cela n'est guère satisfaisant. Il faut donc exprimer la largeur de la zone de dessin SVG en pourcentage de son conteneur (et non pas en pixels).

Coucher de soleil sur la mer : bonne solution

Testez l'affichage de cette page sur mon smartphone et sur votre tablette.

L'image vectorielle s'adapte à la taille de l'écran même à celui d'un smartphone.

Le code correspondant

Il est exactement identique à celui de la première image vectorielle sauf que dans la balise SVG il y a désormais l'attribut viewBox et les valeurs des attributs width et height on été modifiés.
Le code de la balise SVG est désormais :

... <svg width ="100%" height ="auto" viewBox ="0 0 800 400" ... > ...

Remarque : surtout respectez la casse ; un B majuscule à viewBox !

La largeur de l'image (attribut width) est désormais exprimée en pourcentage ; la valeur de l'attribut height est à "auto".

Donc la largeur d'affichage (100%) de l'image vectorielle est égale à la largeur de son conteneur (BODY).
Quant à la hauteur, la taille "auto" permet un respect du rapport entre les deux derniers termes du viewBox (800 400). Donc ici la hauteur sera toujours la moitié de la largeur.

Comme les coordonnées des formes dessinées ne peuvent plus être calculées par rapport aux valeurs des attributs width & height de la balise SVG elles le seront grâce aux valeurs de viewBox qui définit donc le nouveau système de coordonnées du canevas SVG.
Donc résumons nous ! Les quatre valeurs de l'attribut viewBox servent à positionner et dimensionner les éléments SVG dans le canevas alors que les attributs width & height précisent l'affichage dudit canevas dans la page.

Le viewBox : autre exemple

Ci-dessous deux canevas SVG de front

Les deux images ne sont jamais rognées mais s'adaptent à la largeur de l'écran (page adaptative).

SVG SVG

Le code SVG de chaque canevas

<svg width="44%" height="auto" viewBox="0 0 150 100" class ="de_front"> <rect x="0" y="0" width="150" height="100" fill="red"/> <circle cx="75" cy="50" r="45" fill="green"/> <text x="75" y="55" font-size="25" text-anchor="middle" fill="white">SVG</text> </svg>

Les deux canevas ont exactement le même code !

Notez le "width" à 44% et les valeurs du viewBox qui créent un ratio de 1.5 entre largeur et hauteur.
Remarquez aussi l'attribut class associé à la balise SVG.

Extrait de la feuille de style de la page

	.de_front {display : inline-block ; margin :1% ; vertical-align : top ;}

Ainsi les éléments affectés de cette classe sont des boites qui se positionnent côte à côte !

Le viewBox : à utiliser sans modération

Même si vous modifiez les valeurs des attributs width & height de la balise SVG vous n'aurez pas à modifier les paramètres des formes contenues (attributs : x,y,cx,cy,width,height,r,etc.) puisque pour être dessinées ces éléments utilisent désormais les valeurs de l'attribut viewBox.
C'est pas formidable le SVG !

Retour menu