Verwende ich <img>, <object> oder <embed> für SVG-Dateien?

603

Soll ich <img>, <object>oder <embed>zum Laden von SVG - Dateien in einer Seite in ähnlicher Weise wie Laden einesjpg , gifoder png?

Was ist der Code für jeden, um sicherzustellen, dass er so gut wie möglich funktioniert? (Ich sehe Verweise darauf, den Mimetyp einzubeziehen oder auf Fallback-SVG-Renderer in meine Forschung zu verweisen, und sehe keine Referenz auf dem neuesten Stand der Technik).

Angenommen, ich überprüfe die SVG-Unterstützung mit Modernizr und greife auf <img>nicht SVG-fähige Browser zurück (wahrscheinlich durch einen einfachen Tag).

artlung
quelle
3
Machado
2
Theoretisch könnten Sie auch eine haben, <svg>von der Sie auf andere SVGs verweisen möchten. Dies kann zB mit erreicht werden <image>.
Phk

Antworten:

635

Ich kann den SVG Primer (veröffentlicht vom W3C) empfehlen, der dieses Thema behandelt: http://www.w3.org/Graphics/SVG/IG/resources/svgprimer.html#SVG_in_HTML

Wenn Sie verwenden, erhalten <object>Sie kostenlos Raster-Fallback *:

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

*) Nun, nicht ganz kostenlos, da einige Browser beide Ressourcen herunterladen. Siehe Larry's Vorschlag unten, wie Sie das umgehen können.

Update 2014:

  • Wenn Sie ein nicht interaktives SVG möchten, verwenden Sie es <img>mit Skript-Fallbacks für die PNG-Version (für ältere IE und Android <3). Ein sauberer und einfacher Weg, dies zu tun:

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

    Dies verhält sich ähnlich wie ein GIF-Bild. Wenn Ihr Browser deklarative Animationen (SMIL) unterstützt, werden diese abgespielt.

  • Wenn Sie ein interaktives SVG möchten, verwenden Sie entweder <iframe>oder <object>.

  • Wenn Sie älteren Browsern die Möglichkeit geben müssen, ein SVG-Plugin zu verwenden, verwenden Sie <embed>.

  • Für SVG in CSS background-imageund ähnlichen Eigenschaften ist modernizr eine Option für den Wechsel zu Fallback-Bildern, eine andere hängt von mehreren Hintergründen ab, um dies automatisch zu tun:

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

    Hinweis : Die Strategie für mehrere Hintergründe funktioniert unter Android 2.3 nicht, da sie mehrere Hintergründe unterstützt, jedoch kein SVG.

Eine weitere gute Lektüre ist dieser Blogpost über SVG-Fallbacks.

Erik Dahlström
quelle
7
Wie kann ich eine Größe richtig einstellen? Füge ich Höhen- und Breitenattribute hinzu oder verwende ich CSS?
Artlung
5
Die Verwendung von CSS ist in Ordnung, oder Sie legen die Größe für das Einbettungselement fest (d. H. Entweder Iframe, Einbettung, Objekt, IMG). Letzteres verhindert möglicherweise das Aufblitzen von nicht gestyltem Inhalt vor dem Stylesheet, das die Größe definiert wird geladen. Stellen Sie außerdem sicher, dass das SVG über ein viewBox-Attribut verfügt, und entfernen Sie die Attribute width / height aus dem SVG-Stammelement. Das gibt Ihnen das beste Crossbrowser-Verhalten nach meiner Erfahrung.
Erik Dahlström
8
Diese Methode lädt immer die Rasterdatei herunter. Diese Antwort stellt sicher, dass der Fallback nur in älteren IE-Browsern angefordert wird.
Larry
3
Beachten Sie, dass das oben Gesagte mit dem Adobe SVG-Plug-In nicht funktioniert. Sie können jedoch alles zum Laufen bringen (moderne Browser + ASV + MSIE), wenn Sie <param name="src" value="your.svg" />das <object>Tag hinzufügen . Ich habe sehr lange versucht, herauszufinden, wie man das alles macht, und ich glaube, ich habe es endlich geschafft.
Christopher Schultz
5
Ich denke, je schneller die Leute aufhören, alte Browser zu unterstützen, desto schneller werden wir eine Gesellschaft haben, die ihre Browser auf dem neuesten Stand hält, was ab 2012 sogar automatisch mit einem Browser funktioniert. Die einzige Entschuldigung wäre, keinen freien Zugriff auf einen modernen Browser zu haben, sondern auf Firefox zB unterstützt Windows XP noch (wahrscheinlich bis Version 52). Es gibt IMMER eine moderne und kostenlose Alternative.
Neonit
116

Ab IE9 können Sie SVG in einem normalen IMG-Tag verwenden.

https://caniuse.com/svg-img

<img src="/static/image.svg">
Christian Landgren
quelle
35
Dies funktioniert nicht, wenn für die SVG andere Ressourcen geladen werden müssen. (Schriftarten, Bilder, ...)
TheHippo
10
Für ein Logo oder Symbol würde ich aus semantischen Gründen weiterhin die Verwendung eines IMG-Tags empfehlen und sicherstellen, dass das SVG nur eine Vektorillustration ist.
Christian Landgren
4
Jetzt überall akzeptiert. @artlung, vielleicht möchten Sie Ihre Antwort auf diese ändern.
SteeveDroz
15
Jeder, der das <img/>Tag verwendet, möchte möglicherweise Informationen zum Anhängen von SVG-Verwaltungskennungen erhalten , z. B. " <img src="myimage.svg#svgView(preserveAspectRatio(none))" />", mit denen Sie das Seitenverhältnis viewBoxusw. steuern können , genau wie bei Inline-SVG-Definitionen. Weiterführende Literatur zur Skalierung - css-tricks.com/scale-svg
brichins
101

<object>und <embed>haben eine interessante Eigenschaft: Sie ermöglichen es, einen Verweis auf ein SVG-Dokument aus dem äußeren Dokument zu erhalten (unter Berücksichtigung der Richtlinie mit demselben Ursprung). Die Referenz kann dann verwendet werden, um die SVG zu animieren, ihre Stylesheets zu ändern usw.

Gegeben

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

Sie können dann Dinge wie tun

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");
});
WGH
quelle
Ich glaube nicht, dass Sie ein "Lade" -Ereignis von einem <Objekt> -Element erhalten. Nicht unterstützt.
Steve O'Connor
5
@ SteveO'Connor Ich weiß nicht, vielleicht ist es nicht gut dokumentiert, aber es funktioniert auf jeden Fall in Firefox, IE11 und Chrome. Zumindest bei externen SVG-Dateien: Ich konnte es nicht mit Daten-URIs zum Laufen bringen.
WGH
Funktioniert super! Interessanterweise scheint das Hinzufügen des Felds 'id' erforderlich zu sein, wenn Sie zwei SVG-Dateien haben, andernfalls wird nur eine in meinem Opernbrowser angezeigt?
Bram
Mit dieser Methode erhalten Sie das Beste aus Inline und Referenz!
Brandito
Es ist gut zu wissen, dass Hyperlinks in einer SVG nur funktionieren, wenn die SVG inline ist.
Mentalist
26

Die beste Option ist, SVG-Bilder auf verschiedenen Geräten zu verwenden :)

<img src="your-svg-image.svg" alt="Your Logo Alt" onerror="this.src='your-alternative-image.png'">
Roberth Solís
quelle
3
interessant. Aber sind Sie sicher, dass die onerrorFeuer, wenn SVG nicht rendert? Welche Browser haben Sie getestet?
Artlung
1
Ja, ich teste es auf einem mobilen Android-Betriebssystem, Standardbrowser :)
Roberth Solís
24

Verwenden srcset

Die meisten aktuellen Browser unterstützen heute das srcsetAttribut , mit dem unterschiedliche Bilder für verschiedene Benutzer angegeben werden können. Sie können es beispielsweise für 1x und 2x Pixeldichte verwenden, und der Browser wählt die richtige Datei aus.

Wenn Sie in diesem Fall eine SVG in der angeben srcsetund der Browser diese nicht unterstützt, wird auf die zurückgesetzt src.

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

Diese Methode hat gegenüber anderen Lösungen mehrere Vorteile:

  1. Es ist nicht auf seltsame Hacks oder Skripte angewiesen
  2. Es ist einfach
  3. Sie können weiterhin Alternativtext einfügen
  4. Browser, die dies unterstützen, srcsetsollten wissen, wie sie damit umgehen sollen, damit nur die benötigte Datei heruntergeladen wird.
Scribblemacher
quelle
5
Warum sollte man sich die Mühe machen, da heutzutage eine Wahrscheinlichkeit von> 99% besteht, dass ein Browser SVG unterstützt?
Robert Longson
5
Google wird Sie mehr lieben, um sicherzustellen, dass JEDER die Seite genau sehen kann!
Hoots
2
Sieht besser aus als es ist, da Sie zum aktuellen Zeitpunkt das Fallback-Image auf ~ 10% der Benutzer übertragen.
Volker E.
2
@ VolkerE. 10%? caniuse zeigt einen Mangel an SVG-Unterstützung um 2% . Ich benutze immer noch srcset wie in der Antwort, um die 2% zu unterstützen. Ich hoffe, dass Browser in Zukunft Informationen wie srcset verwenden und das entsprechende Bild auswählen können, basierend auf Faktoren wie Leistung und Größe, nicht nur auf Gerätegröße oder Unterstützung des Dateiformats.
Scribblemacher
3
Das einzige Problem mit dieser Lösung ist, wenn Browser SVG unterstützen, nicht jedoch srcset. Wie IE11, das standardmäßig auf PNG zurückgreift, obwohl es SVG unterstützt
Hego555
16

Wenn Ihre SVGs vollständig mit CSS formatiert werden sollen, müssen sie im DOM inline sein. Dies kann durch SVG-Injection erreicht werden, die Javascript verwendet, um ein HTML-Element zu ersetzen (normalerweise ein<img> Element) durch den Inhalt einer SVG-Datei nachdem die Seite geladen wurde.

Hier ist ein minimales Beispiel für die Verwendung von SVGInject :

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

Nach dem Laden des Bildes onload="SVGInject(this)löst das die Injektion aus und das <img>Element wird durch den Inhalt der in der Datei bereitgestellten Datei ersetztsrc Attribut angegebenen . Dies funktioniert mit allen Browsern, die SVG unterstützen.

Haftungsausschluss: Ich bin Mitautor von SVGInject

Waruyama
quelle
15

Ich würde persönlich ein <svg>Tag verwenden, denn wenn Sie dies tun, haben Sie die volle Kontrolle darüber . Wenn Sie es in verwenden, können <img>Sie die Innereien der SVG nicht mit CSS usw. steuern.

Eine andere Sache ist die Browserunterstützung .

Öffnen Sie einfach Ihre svgDatei und fügen Sie sie direkt in die Vorlage ein.

<svg version="1.0" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 3400 2700" preserveAspectRatio="xMidYMid meet" (click)="goHome();">
  <g id="layer101">
    <path d="M1410 2283 c-162 -225 -328 -455 -370 -513 -422 -579 -473 -654 -486 -715 -7 -33 -50 -247 -94 -475 -44 -228 -88 -448 -96 -488 -9 -40 -14 -75 -11 -78 2 -3 87 85 188 196 165 180 189 202 231 215 25 7 129 34 230 60 100 26 184 48 185 49 4 4 43 197 43 212 0 10 -7 13 -22 9 -13 -3 -106 -25 -208 -49 -102 -25 -201 -47 -221 -51 l-37 -7 8 42 c4 23 12 45 16 49 5 4 114 32 243 62 129 30 240 59 246 66 10 10 30 132 22 139 -1 2 -110 -24 -241 -57 -131 -33 -240 -58 -242 -56 -6 6 13 98 22 107 5 4 135 40 289 80 239 61 284 75 307 98 14 15 83 90 153 167 70 77 132 140 139 140 7 0 70 -63 141 -140 70 -77 137 -150 150 -163 17 -19 81 -39 310 -97 159 -41 292 -78 296 -82 8 -9 29 -106 24 -111 -1 -2 -112 24 -245 58 -134 33 -245 58 -248 56 -6 -7 16 -128 25 -136 5 -4 112 -30 238 -59 127 -29 237 -54 246 -57 11 -3 20 -23 27 -57 6 -28 9 -53 8 -54 -1 -1 -38 7 -81 17 -274 66 -379 90 -395 90 -16 0 -16 -6 3 -102 11 -57 21 -104 22 -106 1 -1 96 -27 211 -57 115 -31 220 -60 234 -66 14 -6 104 -101 200 -211 95 -111 175 -197 177 -192 1 5 -40 249 -91 542 l-94 532 -145 203 c-220 309 -446 627 -732 1030 -143 201 -265 366 -271 367 -6 0 -143 -183 -304 -407z m10 -819 l-91 -161 -209 -52 c-115 -29 -214 -51 -219 -49 -6 1 32 55 84 118 l95 115 213 101 c116 55 213 98 215 94 1 -3 -38 -78 -88 -166z m691 77 l214 -99 102 -123 c56 -68 100 -125 99 -127 -4 -3 -435 106 -447 114 -4 2 -37 59 -74 126 -38 68 -79 142 -93 166 -13 23 -22 42 -20 42 2 0 101 -44 219 -99z"/>
    <path d="M1126 2474 c-198 -79 -361 -146 -363 -147 -2 -3 -70 -410 -133 -805 -12 -73 -20 -137 -18 -143 2 -6 26 23 54 63 27 40 224 320 437 622 213 302 386 550 385 551 -2 2 -165 -62 -362 -141z"/>
    <path d="M1982 2549 c25 -35 159 -230 298 -434 139 -203 283 -413 319 -465 37 -52 93 -134 125 -182 59 -87 83 -109 73 -65 -5 20 -50 263 -138 747 -17 91 -36 170 -42 176 -9 8 -571 246 -661 280 -14 6 -7 -10 26 -57z"/>
    <path d="M1679 1291 c-8 -11 -71 -80 -141 -153 l-127 -134 -95 -439 c-52 -242 -92 -442 -90 -445 6 -5 38 28 218 223 l99 107 154 0 c85 0 163 -4 173 -10 10 -5 78 -79 151 -162 73 -84 136 -157 140 -162 18 -21 18 4 -2 85 -11 46 -58 248 -105 448 l-84 364 -87 96 c-108 121 -183 201 -187 201 -2 0 -10 -9 -17 -19z m96 -488 c33 -102 59 -189 57 -192 -2 -6 -244 -2 -251 4 -5 6 120 375 127 375 4 0 34 -84 67 -187z"/>
    </g>
  </svg>

dann können Sie in Ihrem CSS einfach zB:

svg {
  fill: red;
}

Einige Ressourcen: SVG-Tipps

LazerBanana
quelle
15

Wenn Sie <img> -Tags verwenden, zeigen Webkit-basierte Browser keine eingebetteten Bitmap-Bilder an .

Für jede Art von fortgeschrittener SVG-Verwendung, einschließlich der SVG-Inline, bietet bei weitem die größte Flexibilität.

Internet Explorer und Edge ändern die Größe der SVG-Datei korrekt , Sie müssen jedoch sowohl die Höhe als auch die Breite angeben.

Sie können onclick, onmouseover usw. hinzufügen . innerhalb des SVG zu jeder Form in der SVG hinzufügen: onmouseover = "top.myfunction (evt);"

Sie können auch Web-Schriftarten verwenden in der SVG-Datei verwenden, indem Sie sie in Ihr reguläres Stylesheet aufnehmen.

Hinweis: Wenn Sie SVGs aus Illustrator exportieren, sind die Namen der Webschriftarten falsch. Sie können dies in Ihrem CSS korrigieren und vermeiden, in der SVG herumzuspielen. Zum Beispiel gibt Illustrator Arial den falschen Namen, und Sie können dies folgendermaßen beheben:

@font-face {    
    font-family: 'ArialMT';    
    src:    
        local('Arial'),    
        local('Arial MT'),    
        local('Arial Regular');    
    font-weight: normal;    
    font-style: normal;    
}

All dies funktioniert mit jedem Browser, der seit 2013 veröffentlicht wurde .

Ein Beispiel finden Sie unter ozake.com . Die gesamte Website besteht aus SVGs mit Ausnahme des Kontaktformulars.

Warnung: Die Größe von Web-Schriftarten wird in Safari ungenau geändert. Wenn Sie viele Übergänge von einfachem Text zu fett oder kursiv haben, ist an den Übergangspunkten möglicherweise etwas zusätzlicher oder fehlender Speicherplatz vorhanden. Weitere Informationen finden Sie in meiner Antwort auf diese Frage .

Andrew Swift
quelle
Vielen Dank. Ich habe gerade 3 Stunden damit verbracht, mir die Haare auszureißen, um herauszufinden, warum in meinem imgTag keine Rasterbilder angezeigt wurden ... Wissen Sie, ob dies irgendwo offiziell dokumentiert ist?
Roggenbrot
@ Andrew Swift, auf dev.ozake.com erhalten Sie wirklich schöne visuelle Ergebnisse , aber es gibt schwerwiegende Probleme mit der Barrierefreiheit: Suchmaschinen werden es wahrscheinlich schwer haben, die Website zu indizieren (ich bin nicht sicher, ob sie in SVG-Ereignissen versteckte Links finden). ;; Die Site kann nicht über die Tastatur navigiert werden. scheint, dass Screenreader daran ersticken werden ...
InterDist
11

Meine zwei Cent: Ab 2019 können 93% der verwendeten Browser (und 100% der letzten beiden Versionen von jedem von ihnen) SVG in <img>Elementen verarbeiten:

Geben Sie hier die Bildbeschreibung ein

Quelle: Kann ich verwenden

Wir könnten also sagen, dass es keinen Grund <object>mehr gibt, etwas zu verwenden .

Aber es hat immer noch seine Profis :

  • Bei der Inspektion (z. B. mit Chrome Dev Tools) wird das gesamte SVG-Markup angezeigt, falls Sie etwas daran manipulieren und Live-Änderungen sehen möchten.

  • Es bietet eine sehr robuste Fallback-Implementierung für den Fall, dass Ihr Browser keine SVGs unterstützt (warten Sie, aber jeder von ihnen!), Die auch funktioniert, wenn die SVG nicht gefunden wird. Dies war ein Hauptmerkmal der XHTML2-Spezifikation, die Betamax oder HD-DVD ähnelt

Es gibt aber auch Nachteile :

ffflabs
quelle
3

Es wurde eine Lösung mit reinem CSS und ohne Doppelbild-Download gefunden. Es ist nicht schön wie ich will, aber es funktioniert.

<!DOCTYPE html>
<html>
  <head>
    <title>HTML5 SVG demo</title>
    <style type="text/css">
     .nicolas_cage {
         background: url('nicolas_cage.jpg');
         width: 20px;
         height: 15px;
     }
     .fallback {
     }
    </style>
  </head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" width="0" height="0">
    <style>
    <![CDATA[ 
        .fallback { background: none; background-image: none; display: none; }
    ]]>
    </style>
</svg>

<!-- inline svg -->
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40">
  <switch>
     <circle cx="20" cy="20" r="18" stroke="grey" stroke-width="2" fill="#99FF66" />
     <foreignObject>
         <div class="nicolas_cage fallback"></div>
     </foreignObject>
  </switch>
</svg>
<hr/>
<!-- external svg -->
    <object type="image/svg+xml" data="circle_orange.svg">
        <div class="nicolas_cage fallback"></div>
    </object>
</body>
</html>

Die Idee ist, spezielles SVG mit Fallback-Stil einzufügen.

Weitere Details und Testverfahren finden Sie in meinem Blog .

Artru
quelle
0

Diese jQuery-Funktion erfasst alle Fehler in SVG-Bildern und ersetzt die Dateierweiterung durch eine alternative Erweiterung

Bitte öffnen Sie die Konsole, um den Fehler beim Laden von image svg zu sehen

(function($){
  $('img').on('error', function(){
    var image = $(this).attr('src');
    if ( /(\.svg)$/i.test( image )) {
      $(this).attr('src', image.replace('.svg', '.png'));
    }
  })  
})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<img src="https://jsfiddle.net/img/logo.svg">

Andres Separ
quelle
-1

Ich empfehle die Kombination von

<svg viewBox="" width="" height="">
<path fill="#xxxxxx" d="M203.3,71.6c-.........."></path>
</svg>
Grv97
quelle
Können Sie näher erläutern, warum Sie diese Einstellungen verwenden würden und warum sie sich von anderen Antworten unterscheiden?
kvantour
-1

Sie können eine SVG indirekt mit einfügen <img> HTML-Tags Dies ist in StackOverflow wie folgt möglich:

Ich habe folgende SVG-Datei auf meinem PC

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="350" height="350" viewBox="0 0 350 350">

  <title>SVG 3 Circles Intersection </title>

    <circle cx="110" cy="110" r="100"
            stroke="red"
            stroke-width="3"
            fill="none"
            />
    <text x="110" y="110" 
          text-anchor="middle"
          stroke="red"
          stroke-width="1px"
          > Label
    </text>
    <circle cx="240" cy="110" r="100" 
            stroke="blue" 
            stroke-width="3"
            fill="none"
            />
    <text x="240" y="110" 
          text-anchor="middle" 
          stroke="blue" 
          stroke-width="1px"
          > Ticket
    </text>
    <circle cx="170" cy="240" r="100" 
            stroke="green" 
            stroke-width="3" 
            fill="none"
            />
    <text x="170" y="240" 
          text-anchor="middle" 
          stroke="green" 
          stroke-width="1px"
          > Vecto
    </text>
</svg>

Ich habe dieses Bild auf https://svgur.com hochgeladen

Nachdem der Upload beendet wurde, habe ich folgende URL erhalten:

https://svgshare.com/i/H7d.svg

Ich habe dann MANUELL (ohne IMAGE-Symbol) folgendes HTML-Tag hinzugefügt

<img src="https://svgshare.com/i/Kyp.svg"/>

und das Ergebnis ist knapp darunter

Für Benutzer mit einigen Zweifeln ist es möglich zu sehen, was ich beim Bearbeiten der folgenden Antwort auf StackOverflow beim Einfügen eines SVG-Bildes getan habe

BEMERKUNG-1: Die SVG-Datei muss ein <?xml?>Element enthalten. Zu Beginn habe ich einfach eine SVG-Datei erstellt, die direkt mit dem <svg>Tag beginnt und nichts hat funktioniert!

BEMERKUNG-2: Zu Beginn habe ich versucht, ein Bild mit dem IMAGESymbol von einzufügen Edit Toolbar. Ich füge die URL meiner SVG-Datei ein, aber StackOverflow akzeptiert diese Methode nicht. Das<img> Tag muss manuell hinzugefügt werden.

Ich hoffe, dass diese Antwort anderen Benutzern helfen kann.

schlebe
quelle