Apakah saya menggunakan <img>, <object>, atau <embed> untuk file SVG?

603

Haruskah saya menggunakan <img>,, <object>atau <embed>untuk memuat file SVG ke halaman dengan cara yang mirip dengan memuat jpg, gifatau png?

Apa kode untuk masing-masing untuk memastikan itu berfungsi sebaik mungkin? (Saya melihat referensi untuk memasukkan mimetype atau menunjuk ke rendering SVG mundur dalam penelitian saya dan tidak melihat referensi seni yang bagus).

Asumsikan saya sedang memeriksa dukungan SVG dengan Modernizr dan mundur (mungkin melakukan penggantian dengan <img>tag biasa ) untuk browser yang tidak mampu SVG.

artlung
sumber
2
Secara teoritis, Anda juga dapat memiliki <svg>dari mana Anda ingin merujuk SVG lain. Ini dapat dicapai, misalnya menggunakan <image>.
phk

Jawaban:

636

Saya dapat merekomendasikan SVG Primer (diterbitkan oleh W3C), yang mencakup topik ini: http://www.w3.org/Graphics/SVG/IG/resources/svgprimer.html#SVG_in_HTML

Jika Anda menggunakan <object> maka Anda mendapatkan raster fallback gratis *:

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

*) Yah, tidak sepenuhnya gratis, karena beberapa browser mengunduh kedua sumber daya, lihat saran Larry di bawah ini untuk cara menyiasatinya.

Pembaruan 2014:

  • Jika Anda menginginkan svg non-interaktif, gunakan <img>dengan skrip fallbacks ke versi png (untuk IE yang lebih lama dan android <3). Satu cara bersih dan sederhana untuk melakukan itu:

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

    Ini akan berperilaku seperti gambar GIF, dan jika browser Anda mendukung animasi deklaratif (SMIL) maka mereka akan bermain.

  • Jika Anda ingin svg interaktif, gunakan salah satu <iframe>atau <object>.

  • Jika Anda perlu memberikan browser yang lebih lama kemampuan untuk menggunakan plugin svg, maka gunakan <embed>.

  • Untuk svg dalam css background-imagedan properti serupa, modernizr adalah salah satu pilihan untuk beralih ke gambar mundur, yang lain tergantung pada beberapa latar belakang untuk melakukannya secara otomatis:

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

    Catatan : strategi beberapa latar belakang tidak berfungsi pada Android 2.3 karena mendukung banyak latar belakang tetapi tidak svg.

Bacaan tambahan yang bagus adalah posting blog ini tentang svg fallbacks.

Erik Dahlström
sumber
7
Apa cara yang tepat untuk mengatur ukuran? Apakah saya menyertakan atribut tinggi dan lebar, atau apakah saya menggunakan CSS?
artlung
5
Menggunakan css baik-baik saja, atau mengatur ukuran pada elemen embedding (yaitu: salah satu dari iframe, embed, objek, img) - apa yang terakhir dilakukan adalah menghindari flash-of-unstyled-content sebelum stylesheet yang menentukan ukuran. dimuat. Pastikan juga svg memiliki atribut viewBox, dan hapus atribut width / height dari elemen root svg. Itu akan memberi Anda perilaku crossbrowser terbaik dalam pengalaman saya.
Erik Dahlström
8
Metode ini akan selalu mengunduh file raster. Jawaban ini memastikan bahwa fallback hanya diminta pada browser IE lama.
Larry
3
Perhatikan bahwa di atas tidak berfungsi dengan Plug-in Adobe SVG. Tapi, Anda bisa menjalankan semuanya (browser modern + ASV + MSIE) jika Anda menambahkan <param name="src" value="your.svg" />di dalam <object>tag. Saya telah menghabiskan waktu yang sangat lama untuk mencari tahu bagaimana melakukan semua itu, dan saya pikir saya akhirnya mendapatkannya.
Christopher Schultz
5
Saya pikir semakin cepat orang berhenti mendukung browser kuno semakin cepat kita akan memiliki masyarakat yang memperbarui browser mereka, yang bahkan berjalan secara otomatis dengan browser dari 2012. Satu-satunya alasan adalah tidak memiliki akses gratis ke browser modern, tetapi Firefox misalnya masih mendukung Windows XP (mungkin ke versi 52). Ada SELALU alternatif modern dan gratis.
Neonit
117

Dari IE9 dan di atas Anda dapat menggunakan SVG dalam tag IMG biasa ..

https://caniuse.com/svg-img

<img src="/static/image.svg">
Christian Landgren
sumber
35
Ini tidak berfungsi jika SVG membutuhkan sumber daya lain untuk dimuat. (Font, gambar, ...)
TheHippo
11
Untuk logo atau ikon saya masih akan merekomendasikan menggunakan tag IMG untuk alasan semantik dan pastikan SVG hanyalah ilustrasi vektor.
Christian Landgren
4
Sekarang diterima di mana-mana. @artlung, Anda mungkin ingin mengubah jawaban Anda untuk yang ini.
SteeveDroz
16
Siapa pun yang menggunakan <img/>tag mungkin ingin tahu tentang menambahkan pengidentifikasi Frekuensi SVG , misalnya " <img src="myimage.svg#svgView(preserveAspectRatio(none))" />", yang memungkinkan Anda mengontrol rasio aspek viewBox,, dll, sama seperti dengan definisi SVG sebaris. Bacaan lebih lanjut tentang penskalaan - css-tricks.com/scale-svg
brichins
101

<object>dan <embed>memiliki properti yang menarik: mereka memungkinkan untuk mendapatkan referensi ke dokumen SVG dari dokumen luar (dengan mempertimbangkan kebijakan asal-sama). Referensi kemudian dapat digunakan untuk menghidupkan SVG, mengubah stylesheetnya, dll.

Diberikan

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

Anda kemudian dapat melakukan hal-hal seperti

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
sumber
Saya tidak berpikir Anda akan mendapatkan acara "muat" dari elemen <object>. Tidak didukung.
Steve O'Connor
5
@ SteveO'Connor Saya tidak tahu, mungkin itu tidak didokumentasikan dengan baik, tetapi pasti berfungsi di Firefox, IE11 dan Chrome. Setidaknya dengan file SVG eksternal: Saya tidak bisa membuatnya bekerja dengan data URI.
WGH
Bagus sekali! Menariknya, menambahkan bidang 'id' tampaknya diperlukan ketika Anda memiliki dua file SVG, jika tidak hanya 1 yang akan muncul di browser opera saya?
Bram
Anda mendapatkan yang terbaik dari keduanya sebaris dan dirujuk dengan metode ini!
Brandito
Adalah baik untuk menyadari bahwa hyperlink di dalam SVG tidak akan berfungsi kecuali SVG inline.
Mentalist
26

Pilihan terbaik adalah menggunakan Gambar SVG pada perangkat yang berbeda :)

<img src="your-svg-image.svg" alt="Your Logo Alt" onerror="this.src='your-alternative-image.png'">
Roberth Solís
sumber
3
menarik. tetapi apakah Anda yakin onerrorkebakaran jika svg tidak memberikan? browser apa yang telah Anda uji?
artlung
1
Ya, saya mengujinya pada OS Android seluler, peramban default :)
Roberth Solís
24

Menggunakan srcset

Sebagian besar browser saat ini mendukung srcsetatribut , yang memungkinkan menentukan gambar berbeda untuk pengguna yang berbeda. Misalnya, Anda dapat menggunakannya untuk kepadatan 1x dan 2x piksel, dan browser akan memilih file yang benar.

Dalam hal ini, jika Anda menentukan SVG di srcsetdan browser tidak mendukungnya, itu akan mundur pada src.

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

Metode ini memiliki beberapa manfaat dibandingkan solusi lain:

  1. Itu tidak mengandalkan hack atau skrip aneh
  2. Itu mudah
  3. Anda masih dapat memasukkan teks alt
  4. Browser yang mendukung srcsetharus tahu cara menanganinya sehingga hanya mengunduh file yang dibutuhkan.
Scribblemacher
sumber
5
Mengapa repot mengingat bahwa ada kemungkinan> 99% peramban yang akan mendukung SVG hari ini?
Robert Longson
5
Bagian dari memastikan SEMUA ORANG dapat melihat halaman secara akurat, Google akan lebih mencintaimu!
Hoots
2
Terlihat lebih baik daripada itu, mengingat bahwa pada titik saat ini Anda mendorong gambar mundur ke ~ 10% pengguna.
Volker E.
2
@VolkerE. 10%? caniuse menunjukkan kurangnya dukungan SVG sekitar 2% . Saya masih menggunakan srcset seperti pada jawaban untuk mendukung 2%. Di masa depan, saya berharap browser dapat mengambil informasi seperti srcset dan memilih gambar yang sesuai berdasarkan faktor-faktor seperti kinerja dan ukuran, bukan hanya ukuran perangkat atau dukungan format file.
Scribblemacher
3
Satu-satunya masalah dengan solusi ini adalah ketika browser mendukung SVG tetapi tidak srcset. Seperti IE11, yang secara default kembali ke PNG meskipun mendukung SVG
Hego555
16

Jika Anda perlu SVG Anda sepenuhnya bergaya dengan CSS mereka harus inline di DOM. Ini dapat dicapai melalui injeksi SVG, yang menggunakan Javascript untuk mengganti elemen HTML (biasanya <img>elemen) dengan konten file SVG setelah halaman dimuat.

Berikut adalah contoh minimal menggunakan SVGInject :

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

Setelah gambar dimuat, onload="SVGInject(this)akan memicu injeksi dan <img>elemen akan diganti dengan konten file yang disediakan dalam srcatribut. Ini berfungsi dengan semua browser yang mendukung SVG.

Penafian: Saya adalah rekan penulis SVGInject

Waruyama
sumber
15

Saya pribadi akan menggunakan <svg>tag karena jika Anda melakukannya, Anda memiliki kontrol penuh atasnya . Jika Anda menggunakannya, <img>Anda tidak bisa mengendalikan jeroan SVG dengan CSS dll.

Hal lain adalah dukungan browser .

Cukup buka svgfile Anda dan tempel langsung ke templat.

<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>

kemudian di css Anda, Anda bisa misalnya:

svg {
  fill: red;
}

Beberapa sumber: kiat SVG

LazerBanana
sumber
15

Jika Anda menggunakan tag <img> , maka browser berbasis webkit tidak akan menampilkan gambar yang dipetakan dengan bitmap .

Untuk segala jenis penggunaan SVG tingkat lanjut, termasuk SVG inline menawarkan fleksibilitas yang paling banyak.

Internet Explorer dan Edge akan mengubah ukuran SVG dengan benar , tetapi Anda harus menentukan tinggi dan lebar.

Anda dapat menambahkan onclick, onmouseover, dll. dalam svg, ke bentuk apa pun di SVG: onmouseover = "top.myfunction (evt);"

Anda juga dapat menggunakan font web di SVG dengan memasukkannya dalam style sheet biasa.

Catatan: jika Anda mengekspor SVG dari Illustrator, nama font web akan salah. Anda dapat memperbaiki ini di CSS Anda dan menghindari bermain-main di SVG. Misalnya, Illustrator memberikan nama yang salah kepada Arial, dan Anda dapat memperbaikinya seperti ini:

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

Semua ini berfungsi di semua browser yang dirilis sejak 2013 .

Sebagai contoh, lihat ozake.com . Seluruh situs dibuat dari SVG kecuali untuk formulir kontak.

Peringatan: Font web diubah ukurannya dengan tidak tepat di Safari - dan jika Anda memiliki banyak transisi dari teks biasa ke cetak tebal atau miring, mungkin ada sedikit ruang ekstra atau hilang di titik transisi. Lihat jawaban saya di pertanyaan ini untuk informasi lebih lanjut.

Andrew Swift
sumber
Terima kasih. Hanya menghabiskan 3 jam mencabut rambut saya mencoba mencari tahu mengapa gambar raster tidak muncul di imgtag saya ... Apakah Anda tahu apakah ini secara resmi didokumentasikan di mana saja?
ryebread
@Andrew Swift, Anda mendapatkan hasil visual yang sangat bagus di dev.ozake.com , tetapi ada masalah aksesibilitas serius: mesin pencari mungkin akan kesulitan mengindeks situs (Saya tidak yakin mereka akan mengambil tautan yang tersembunyi di dalam acara SVG) ; situs ini tidak dapat dinavigasi oleh keyboard; Tampaknya pembaca layar akan tersedak ...
interDist
11

Dua sen saya: pada 2019, 93% browser yang digunakan (dan 100% dari dua versi terakhir dari masing-masing dari mereka) dapat menangani <img>elemen dalam SVG :

masukkan deskripsi gambar di sini

Sumber: Dapatkah Saya Menggunakan

Jadi kita dapat mengatakan bahwa tidak ada alasan untuk menggunakannya <object>lagi.

Namun masih memiliki kelebihan :

  • Saat memeriksa (mis. Dengan Alat Dev Chrome) Anda disajikan dengan seluruh markup SVG jika Anda ingin sedikit merusaknya dan melihat perubahan langsung.

  • Ini memberikan implementasi fallback yang sangat kuat jika browser Anda tidak mendukung SVG (tunggu, tetapi semuanya melakukannya!) Yang juga berfungsi jika SVG tidak ditemukan. Ini adalah fitur kunci dari spesifikasi XHTML2, yang seperti betamax atau HD-DVD

Tetapi ada juga kontra :

ffflabs
sumber
3

Menemukan satu solusi dengan CSS murni dan tanpa pengunduhan gambar ganda. Itu tidak indah seperti yang saya inginkan, tetapi berhasil.

<!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>

Idenya adalah untuk memasukkan SVG khusus dengan gaya fallback.

Lebih detail dan proses pengujian dapat Anda temukan di blog saya .

Artru
sumber
0

Fungsi jQuery ini menangkap semua kesalahan dalam gambar svg dan mengganti ekstensi file dengan ekstensi alternatif

Silakan buka konsol untuk melihat kesalahan memuat gambar svg

(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
sumber
-1

Saya sarankan menggunakan kombinasi

<svg viewBox="" width="" height="">
<path fill="#xxxxxx" d="M203.3,71.6c-.........."></path>
</svg>
Grv97
sumber
dapatkah Anda menjelaskan mengapa Anda akan menggunakan pengaturan ini dan mengapa itu berbeda dari jawaban lain?
kvantour
-1

Anda dapat memasukkan SVG menggunakan secara tidak langsung <img> tag HTML dan ini dimungkinkan pada StackOverflow mengikuti apa yang dijelaskan di bawah ini:

Saya telah mengikuti file SVG di PC saya

<?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>

Saya telah mengunggah gambar ini ke https://svgur.com

Setelah unggahan dihentikan, saya mendapatkan URL berikut:

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

Saya kemudian MANUAL (tanpa menggunakan ikon IMAGE) menambahkan tag html berikut

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

dan hasilnya tepat di bawah

Untuk pengguna dengan keraguan, adalah mungkin untuk melihat apa yang telah saya lakukan dalam mengedit jawaban berikut tentang StackOverflow memasukkan gambar SVG

KETERANGAN-1: file SVG harus mengandung <?xml?>elemen. Pada awalnya, saya hanya membuat file SVG yang dimulai langsung dengan <svg>tag dan tidak ada yang berhasil!

KETERANGAN-2: di awal, saya telah mencoba memasukkan gambar menggunakan IMAGEikon Edit Toolbar. Saya tempel URL file SVG saya tetapi StackOverflow tidak menerima metode ini. Itu<img> tag harus ditambahkan secara manual.

Saya harap jawaban ini dapat membantu pengguna lain.

schlebe
sumber