À la suite de discussions sur Twitter avec Nicolas Hoizey (@nhoizey) et Pascal Cauhépé (@eQRoeil), je publie ici mes démêlés avec l’intégration d’une bannière au format SVG dans une page html. Je les remercie tous deux de m’avoir accompagnée dans mes maugréements sur Twitter et de m’avoir aidée à chercher des solutions.

Dans le cadre de mon activité professionnelle, je dois intégrer dans l’entête une bannière qui se prête bien au format SVG (Scalable Vector Graphic) : essentiellement du texte et quelques formes simples. Comme j’avais lu pas mal d’articles et tutoriels sur le sujet et que je suis curieuse, j’ai sauté sur l’occasion pour tâcher de les mettre en pratique.

Les contraintes

J’ai des contraintes assez fortes, que je m’impose ou qu’on m’impose :

  • la bannière doit être cliquable (c’est un lien de retour à l’accueil du site) ;
  • elle doit s’afficher sur les vieilles versions d’Internet Explorer ;
  • elle doit pouvoir subir des modifications au survol et au focus ;
  • elle doit se transformer sur les petits écrans ;
  • le fichier de l’image doit rester externe (pas de data directement dans la source) ;
  • je ne souhaite pas utiliser de javascript ;
  • le tout doit respecter les normes d’accessibilité (RGAA niveau 2 minimum).

Oui, je suis un peu maso. Enfin ce qui est surtout maso c’est de vouloir tout ça avec du SVG parce qu’avec une image classique ça n’a rien de bien sorcier. Si vous vous demandez pourquoi donc je m’embête avec le SVG je vous renvoie à ces explications du Pr Lapointe.

L’image

Les différents états de la bannière sont gérés directement par l’application de styles au SVG (j’y reviendrai). La voici donc telle qu’elle apparaît sur les écrans de bureau et tablette[1].

Logo Dali

Si vous réalisez des images SVG pour le web, suivez les recommandations de Stéphanie Walter (voir ci-dessous), c’est très bien décrit.

Choix de la méthode d’insertion

Il existe plusieurs méthodes pour insérer une image SVG dans une page HTML. Chris Coyer les détaille dans son article “Using SVG” et Stéphanie Walter les évoque également dans « Un logo cliquable SVG avec alternatives ». Je vous renvoie à ces articles pour les découvrir.

Après avoir repoussé celles qui ne permettaient pas de manipuler le svg une fois inséré (en utilisant la balise <img /> ou en css via un background), celles qui auraient demandé d’insérer les données directement dans le html (svg inline) et celles qui sont trop hipster (et impliqueraient donc obligatoirement l’usage de javascript pour la compatibilité avec les vieux navigateurs), j’ai opté pour la robuste balise <object>. Son utilisation est d’une simplicité biblique.

Code de l’étape 1 :

Fichier index.html.

<object type="image/svg+xml" data="img/logo-dali2.svg" id="object-logo"></object>

L’image s’affiche correctement sur les navigateur modernes.

Lien sur la bannière

Lorsqu’on entoure un object avec un lien et qu’on veut que toute son étendue soit cliquable il faut donner à ce lien les mêmes largeur et hauteur que l’objet. Ça fonctionne très bien mais ce lien vient alors se placer au-dessus de l’objet et s’interpose donc entre lui et la souris. Ça ne convenait pas à mon usage puisque je veux que mon SVG reçoive des événements (le focus et le hover) car j’ai prévu que son survol déclenche des transformations (changement de couleur dans mon exemple simple).

Je dois donc placer le lien dans le fichier SVG lui-même. Rien de bien compliqué là non plus. J’ai suivi les instructions.

Attention : si vous voulez que toute la zone soit cliquable et pas seulement les éléments « pleins », il faut que votre dessin comporte un élément englobant le tout. (J’ai mis un rectangle transparent sur toute la zone, voir l’étape 5.)

Code de l’étape 2 :

Fichier logo-dali2.svg.
Ouverture du lien juste après la balise inaugurale <svg …>, fermeture juste avant la balise finale </svg>.

<svg …>
  <a xlink:href="url-de-mon-choix" target="_parent">
     […]
  </a>
</svg>

L’image est désormais cliquable.

Fallback

On peut placer un contenu entre l’ouverture et la fermeture de la balise object pour indiquer aux navigateurs qui ne gèrent pas ce format ce qu’ils doivent afficher à la place. Plutôt que mettre une image en fallback, ainsi que beaucoup d’articles le préconisent, j’ai choisi d’insérer ici le titre du site et de placer l’image en background de cet élément. Cela me permettra de ne charger l’image de remplacement que dans la feuille de style pour IE et de faire en sorte que le survol offre lui aussi une autre présentation, comme pour sa sœur SVG. Comme j’ai placé le lien du SVG à l’intérieur de son fichier, il faut en mettre un sur le fallback.

Code de l’étape 3 :

Fichier index.html.

<object type="image/svg+xml" data="img/logo-dali2.svg" id="object-logo">
  <a class="logo-fallback" href="url-de-mon-choix"><span class="visually-hidden">DALI - Accueil</span></a>
</object>

Les vieux navigateurs afficheront une zone cliquable avec une image de fond. Notez le span class="visually-hidden" : grâce à des règles css spécifiques je pourrai faire en sorte que le le contenu textuel ne soit pas visible sur l’écran mais lu par les aides techniques type Jaws.

Accessibilité

Puisqu’on parle d’accessibilité, il faut prévoir une alternative textuelle pour le cas où le navigateur peut afficher le SVG mais est utilisé par une personne ne pouvant pas le voir. Je modifie donc à nouveau le fichier SVG pour ajouter les éléments nécessaires sur les toujours excellents conseils de la maison Paciello.

Code de l’étape 4 :

Fichier logo-dali2.svg
Au sein de la balise inaugurale <svg …>

role="img" aria-labelledby="title"

et juste après elle (autrement dit juste avant la balise <a> placée à l’étape 2) :

<title>DALI - Accueil</title>

Le texte « DALI - Accueil » sera prononcé par les lecteurs d’écran. Je crois toutefois que ça n’est pas pleinement satisfaisant car ça ne fonctionnera que sur des versions récentes des navigateurs (?)

Styles

On peut appliquer des styles CSS sur des SVG de différentes manières : dans les différents éléments (path, g, circle…) eux-mêmes, dans l’entête du fichier, dans la feuille de style du site. J’ai choisi cette dernière option pour pouvoir y opérer des modifications plus facilement. Pour indiquer au fichier SVG où il peut trouver les styles qui le concernent, il faut insérer une ligne au début du fichier.

Puis on ajoute les styles dans la feuille de style qu’on vient d’indiquer. J’ai appliqué toute la colorisation via CSS, le fichier SVG n’embarque aucune instruction de couleur.

Code de l’étape 5 :

Fichier logo-dali2.svg
Au tout début, avant l’ouverture de la balise <svg …>.

<?xml-stylesheet href="../css/screen.css" type="text/css" rel="stylesheet" ?>

Fichier screen.css :

		.st0{fill:#137BBB;}
		.st1{fill:#E6007E;}
		.st2{fill:#4D96D2;}
		.st3{fill:#808080;}
		.st4{fill:#F39200;}
		.st5{fill:none;}
		#svg-logo a:hover #sigle path,
		#svg-logo a:hover #chocolat path,
		#svg-logo a:focus #sigle path,
		#svg-logo a:focus #chocolat path,
		#svg-logo a:hover path#coeur,
		#svg-logo a:focus path#coeur {
			fill: #FF2700;
			transition: all .7s ease;
		}
		#svg-logo a:hover #moustache path,
		#svg-logo a:hover #moustache path {
			fill:#000;
		}
		rect.svg-container {
			fill:transparent;
		}

Désormais le survol du lien change les couleurs à certains endroits de l’image. C’est bô !

Log Dali au survol

Transformations sur petits écrans

Comme ci-dessus pour l’état de survol du lien, on peut aussi donner des instructions de transformation selon la dimension du conteneur de l’image. C’est ce que j’ai fait en supprimant la baseline, en remontant le sigle et en plaçant la moustache dessous. Attention : la largeur prise en compte n’est pas celle du body mais celle du conteneur de l’image.

Code de l’étape 6 :

Fichier screen.css.

@media screen and (max-width: 20em) {
	#svg-logo #sigle {
		transform: scale(.90) translate(6px, -12px);
	}
	#svg-logo #baseline {
		display: none;
	}
	#svg-logo #moustache {
		transform: scale(.95) translate(-288px, 20px);
	}
}

Sur les mobiles la bannière est simplifiée.

C’est (presque) fini…

Vous pouvez regarder cet exemple dans mes ateliers. Si ça intéresse quelqu’un je peux déposer tout ça sur mon compte Github. Il reste des tests à faire sur plus de navigateurs et les styles sont à affiner pour le fallback mais grosso modo ça tourne :)

Si vous êtes parvenus jusqu’au bout de cet article et que vous avez des remarques ou suggestions à faire, soyez les bienvenus, je suis en plein défrichage, ça m’intéresse !

…et puis il reste le $%*£#& bien agaçant

C’est un souci inexplicable et mystérieux et énervant : lors de la navigation au clavier il y a un outline sur l’objet avant le focus sur le lien. Si quelqu’un sait comment l’éviter je suis preneuse. Je ne comprends pas du tout ce qui se passe, sans même parler de supprimer cette tabulation (mais il faudrait aussi) je n’arrive pas à enlever les pointillés, aucun de ces codes ne produit de résultat :(


Si vous êtes curieux du projet ou si vous souhaitez participer à son amélioration, j’ai ouvert un dépôt Github à cet effet.

Note

[1] Enfin pas tout à fait elle mais une dans le même esprit.