738 votes

Dois-je utiliser <img>, <object>, ou <embed> pour les fichiers SVG ?

Dois-je utiliser <img> , <object> o <embed> pour charger des fichiers SVG dans une page de manière similaire au chargement d'un fichier de type jpg , gif o png ?

Quel est le code pour chacun d'entre eux afin de s'assurer qu'il fonctionne aussi bien que possible ? (Dans le cadre de mes recherches, je vois des références à l'inclusion du mimetype ou à l'indication de générateurs de rendu SVG de secours, mais je ne vois pas de bonne référence sur l'état de l'art).

Supposons que je vérifie la prise en charge de SVG avec Modernizr et de revenir en arrière (probablement en remplaçant par une simple <img> ) pour les navigateurs non compatibles SVG.

3 votes

Jetez un coup d'œil sur github.com/jonathantneal/svg4everybody

2 votes

Théoriquement, vous pourriez aussi avoir un <svg> à partir duquel vous souhaitez référencer d'autres SVG. Cela peut être réalisé, par exemple, à l'aide des éléments suivants <image> .

1 votes

Je viens d'écrire un article de blog sur ce sujet : claude-e-e.medium.com/

739voto

Erik Dahlström Points 21519

Je peux vous recommander le SVG Primer (publié par le W3C), qui couvre ce sujet : http://www.w3.org/Graphics/SVG/IG/resources/svgprimer.html#SVG_in_HTML

Si vous utilisez <object> Dans ce cas, vous bénéficiez gratuitement d'un retour au format raster* :

<object data="your.svg" type="image/svg+xml">
  <img src="yourfallback.jpg" />
</object>

*) Enfin, pas tout à fait gratuitement, car certains navigateurs téléchargent les deux ressources, voir la suggestion de Larry ci-dessous pour contourner ce problème.

Mise à jour de 2014 :

  • Si vous voulez un svg non interactif, utilisez <img> avec script fallbacks à la version png (pour les anciens IE et Android < 3). Une façon simple et propre propre et simple pour le faire :

    <img src="your.svg" onerror="this.src='your.png'"> .

    Elle se comportera comme une image GIF et si votre navigateur prend en charge les animations déclaratives (SMIL), celles-ci seront jouées.

  • Si vous voulez un svg interactif, utilisez soit <iframe> o <object> .

  • Si vous devez offrir aux anciens navigateurs la possibilité d'utiliser un plugin svg, utilisez alors <embed> .

  • Pour les svg en css background-image et des propriétés similaires, modernizr est un choix pour passer aux images de repli, un autre est de dépendre de plusieurs arrière-plans pour le faire automatiquement :

    div {
        background-image: url(fallback.png);
        background-image: url(your.svg), none;
    }

    Note la stratégie des arrière-plans multiples ne fonctionne pas sur Android 2.3 car il supporte les arrière-plans multiples mais pas les svg.

Une autre bonne lecture est ce blogpost sur les fallbacks svg.

9 votes

Quelle est la bonne façon de définir une taille ? Dois-je inclure les attributs de hauteur et de largeur, ou dois-je utiliser les CSS ?

6 votes

Il est possible d'utiliser une feuille de style css ou de définir la taille de l'élément d'intégration (iframe, embed, object, img). Cette dernière option permet d'éviter le flash-of-unstyled-content avant le chargement de la feuille de style qui définit la taille. Assurez-vous également que le svg possède un attribut viewBox, et supprimez les attributs width/height de l'élément racine du svg. D'après mon expérience, vous obtiendrez le meilleur comportement inter-navigateurs.

8 votes

Cette méthode téléchargera toujours le fichier raster. Cette réponse garantit que la solution de repli n'est demandée que sur les anciens navigateurs IE.

147voto

Christian Landgren Points 1127

A partir d'IE9 et plus, vous pouvez utiliser SVG dans une balise IMG ordinaire

https://caniuse.com/svg-img

<img src="/static/image.svg">

53 votes

Cela ne fonctionne pas si le SVG nécessite le chargement d'autres ressources. (Polices, images, ...)

15 votes

Pour un logo ou une icône, je recommanderais toujours d'utiliser une balise IMG pour des raisons sémantiques et de s'assurer que le SVG est juste une illustration vectorielle.

5 votes

Maintenant accepté partout. @artlung, vous pourriez vouloir changer votre réponse à celle-ci.

119voto

WGH Points 407

<object> y <embed> ont une propriété intéressante : ils permettent d'obtenir une référence au document SVG à partir du document externe (en tenant compte de la politique de same-origin). Cette référence peut ensuite être utilisée pour animer le SVG, modifier ses feuilles de style, etc.

Étant donné que

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

Vous pouvez alors faire des choses comme

document.getElementById("svg1").addEventListener("load", function() {
    var doc = this.getSVGDocument();
    var rect = doc.querySelector("rect"); // suppose our image contains a <rect>
    rect.setAttribute("fill", "green");
});

1 votes

Je ne pense pas que vous obtiendrez un événement "load" à partir d'un élément <object>. Non pris en charge.

7 votes

@SteveO'Connor Je ne sais pas, ce n'est peut-être pas bien documenté, mais cela fonctionne certainement dans Firefox, IE11 et Chrome. Au moins avec les fichiers SVG externes : Je n'ai pas réussi à le faire fonctionner avec les URI de données.

0 votes

Fonctionne très bien ! Il est intéressant de noter que l'ajout du champ "id" semble être nécessaire lorsque vous avez deux fichiers SVG, sinon un seul s'affiche dans mon navigateur Opera ?

38voto

Scribblemacher Points 592

Utilisez srcset

Le plus Les navigateurs actuels prennent en charge le srcset attribut qui permet d'attribuer des images différentes à des utilisateurs différents. Par exemple, vous pouvez l'utiliser pour une densité de pixels de 1x et 2x, et le navigateur sélectionnera le bon fichier.

Dans ce cas, si vous spécifiez un SVG dans le champ srcset et que le navigateur ne le prend pas en charge, il se rabattra sur l'option src .

<img src="logo.png" srcset="logo.svg" alt="My logo">

Cette méthode présente plusieurs avantages par rapport aux autres solutions :

  1. Il ne s'appuie pas sur des bidouillages ou des scripts bizarres.
  2. C'est simple.
  3. Vous pouvez toujours inclure du texte alt
  4. Les navigateurs qui prennent en charge srcset doit savoir comment le gérer pour qu'il ne télécharge que le fichier dont il a besoin.

28voto

Waruyama Points 1152

Si vous voulez que vos SVG soient entièrement stylisables avec CSS, ils doivent être en ligne dans le DOM. Ceci peut être réalisé grâce à l'injection de SVG, qui utilise Javascript pour remplacer un élément HTML (généralement un élément <img> ) avec le contenu d'un fichier SVG après le chargement de la page.

Voici un exemple minimal utilisant SVGInject :

<html>
<head>
  <script src="svg-inject.min.js"></script>
</head>
<body>
  <img src="image.svg" onload="SVGInject(this)" />
</body>
</html>

Après le chargement de l'image, le onload="SVGInject(this) déclenchera l'injection et le <img> sera remplacé par le contenu du fichier fourni dans l'élément src attribut. Cela fonctionne avec tous les navigateurs qui prennent en charge le format SVG.

Disclaimer : Je suis le co-auteur de SVGInject

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X