Я использую <img>, <object> или <embed> для файлов SVG?

Должен ли я использовать <img>, <object> или <embed> для загрузки SVG файлов на страницу способом, подобным загрузке jpg, gif или png?

Каков код для каждого, чтобы он работал как можно лучше? (Я вижу ссылки на включение mimetype или указание на резервные SVG-рендереры в своих исследованиях и не вижу хорошей ссылки в данной области).

Предположим, что я проверяю поддержку SVG с помощью Modernizr и отступаю (возможно, заменяя простой тег <img>) для браузеров, не поддерживающих SVG.

Ответ 1

Я могу порекомендовать SVG Primer (опубликовано W3C), который охватывает эту тему: http://www.w3.org/Graphics/SVG/IG/resources/svgprimer.html#SVG_in_HTML

Если вы используете <object>, вы получите бесплатную резервную копию растра *:

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

*) Ну, не совсем бесплатно, потому что некоторые браузеры загружают оба ресурса, см. ниже предложение Ларри о том, как обойти это.

Обновление 2014:

  • Если вы хотите неинтерактивный svg, используйте <img> с script резервными к версии png (для более старых IE и android < 3). Один чистый и простой способ сделать это:

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

    Это будет выглядеть как GIF-образ, и если ваш браузер поддерживает декларативную анимацию (SMIL), тогда они будут воспроизводиться.

  • Если вы хотите интерактивный svg, используйте либо <iframe>, либо <object>.

  • Если вам нужно предоставить старым браузерам возможность использовать плагин svg, используйте <embed>.

  • Для svg в css background-image и подобных свойствах modernizr является одним из вариантов переключения на резервные изображения, другой - в зависимости от нескольких фонов, чтобы сделать это автоматически:

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

    Примечание: стратегия множественных фолов не работает на Android 2.3, потому что она поддерживает несколько фонов, но не svg.

Дополнительным хорошим чтением является этот blogpost на svg fallbacks.

Ответ 2

Начиная с IE9 и выше, вы можете использовать SVG в обычном теге IMG.

https://caniuse.com/svg-img

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

Ответ 3

<object> и <embed> обладают интересным свойством: они позволяют получить ссылку на документ SVG из внешнего документа (принимая во внимание политику того же самого происхождения). Ссылка может затем использоваться для анимации SVG, изменения его таблиц стилей и т.д.

Учитывая

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

Затем вы можете делать такие вещи, как

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");
});

Ответ 4

Лучший вариант - использовать SVG-изображения на разных устройствах:)

<img src="your-svg-image.svg" alt="Your Logo Alt" onerror="this.src='your-alternative-image.png'">

Ответ 5

Используйте srcset

Большинство современных браузеров сегодня поддерживают атрибут srcset, который позволяет указывать разные изображения для разных пользователей. Например, вы можете использовать его для плотности пикселей 1x и 2x, и браузер выберет правильный файл.

В этом случае, если вы укажете SVG в srcset а браузер его не поддерживает, это будет откат на src.

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

Этот метод имеет несколько преимуществ по сравнению с другими решениями:

  1. Это не полагаясь на какие-то странные хаки или скрипты
  2. Это просто
  3. Вы все еще можете включить альтернативный текст
  4. Браузеры, которые поддерживают srcset должны знать, как с ним обращаться, чтобы он загружал только тот файл, который ему нужен.

Ответ 6

Если вы используете теги <img>, то браузеры на основе webkit не будут отображать встроенные растровые изображения.

Если вы используете встроенные SVG, то Explorer не будет изменять размер SVG в соответствии с вашим CSS.
Explorer корректно изменит размер SVG, но вы должны указать как высоту, так и ширину.

Я обнаружил, что тег <object> является единственным, который работает во всех браузерах. Мне пришлось изменить ширину и высоту (внутри SVG) до 100%, чтобы правильно изменить размер.

Вы можете добавить onclick, onmouseover и т.д. Внутри SVG к любой фигуре в SVG: onmouseover = "top.myfunction(evt);"

Вы также можете использовать веб-шрифты в SVG, включив их в свою обычную таблицу стилей.

Примечание. Если вы экспортируете SVG из Illustrator, названия веб-шрифтов будут неправильными. Вы можете исправить это в своем CSS и избежать возни с SVG. Например, Illustrator дает неправильное имя Arial, и вы можете исправить это так:

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

Все это работает в любом браузере, выпущенном за последние два года.

Результаты на ozake.com (на французском). Весь сайт сделан из SVG за исключением контактной формы.

Предупреждение: веб-шрифты не имеют точного размера, и если у вас много переходов от простого текста к жирному или курсиву, в точках перехода может быть небольшое количество лишнего или недостающего пространства. Смотрите мой ответ на этот вопрос для получения дополнительной информации.

Ответ 7

Если вам нужно, чтобы ваши SVG были полностью стилизованы с помощью CSS, они должны быть встроены в DOM. Это может быть достигнуто с помощью внедрения SVG, который использует Javascript для замены элемента HTML (обычно элемента <img>) содержимым файла SVG после загрузки страницы.

Вот минимальный пример использования SVGInject:

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

После загрузки изображения onload="SVGInject(this) запустит внедрение, и элемент <img> будет заменен содержимым файла, предоставленного в атрибуте src. Это работает со всеми браузерами, которые поддерживают SVG.

Отказ от ответственности: я являюсь соавтором SVGInject

Ответ 8

Я бы лично использовал <svg> потому что если вы это делаете, у вас есть полный контроль над ним. Если вы используете его в <img> вы не сможете управлять внутренностями SVG с помощью CSS и т.д.

Другое дело поддержка браузера.

Просто откройте файл svg и вставьте его прямо в шаблон.

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

тогда в вашем CSS вы можете просто, например:

svg {
  fill: red;
}

Некоторый ресурс: советы SVG

Ответ 9

Мои два цента: по состоянию на 2019 год 93% используемых браузеров (и 100% последних двух версий каждой из них) могут обрабатывать SVG в элементах <img>:

enter image description here

Источник: Могу ли я использовать

Таким образом, мы могли бы сказать, что нет причин использовать <object> больше.

Однако у него все еще есть свои плюсы:

  • При проверке (например, с помощью Chrome Dev Tools) вам предоставляется вся разметка SVG на случай, если вы захотите немного подделать ее и увидеть живые изменения.

  • Это обеспечивает очень надежную резервную реализацию в случае, если ваш браузер не поддерживает SVG (подождите, но каждый из них поддерживает!), Что также работает, если SVG не найден. Это была ключевая особенность спецификации XHTML2, которая похожа на betamax или HD-DVD

Но есть и минусы:

Ответ 10

Нашел одно решение с чистым CSS и без двойной загрузки изображения. Это не так красиво, как я хочу, но он работает.

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

Идея состоит в том, чтобы вставить специальный SVG с резервным стилем.

Подробнее и процесс тестирования вы можете найти в в моем блоге.

Ответ 11

Эта функция jQuery захватывает все ошибки в изображениях svg и заменяет расширение файла альтернативным расширением

Откройте консоль, чтобы увидеть изображение загрузки ошибки 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">

Ответ 12

Встроенный блок REF Реализация SVG выполняется в браузерах, если вы используете встроенный блок. Используйте display: table и display: table-cell, а svg - как img для наиболее надежных просмотров. Объекты и фоновые изображения отображаются непредсказуемо. Также имейте в виду опции экспорта Adobe Illustrator и флажок "отзывчивый", который может или не поможет.

2016, и они до сих пор не отсортировали SVG?

Ответ 13

Я рекомендую использовать комбинацию

<svg viewBox="" width="" height="">
<path fill="#xxxxxx" d="M203.3,71.6c-.........."></path>
</svg>