it-swarm.com.ru

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

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

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

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

535
artlung

Я могу порекомендовать учебник по SVG (опубликован 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> с откатами сценария до версии 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.

Дополнительное хорошее прочтение этот пост на svg-ресурсах.

573
Erik Dahlström

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

https://caniuse.com/svg-img

<img src="/static/image.svg">
95
Christian Landgren

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

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

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

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

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

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

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

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

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

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

Если вы используете встроенные 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, за исключением контактной формы.

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

15
Andrew Swift

Если вам нужно, чтобы ваши 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

11
Waruyama

Я бы лично использовал тег <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

10
LazerBanana

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

enter image description here

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

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

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

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

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

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

6
amenadiel

Нашел одно решение с чистым 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 с резервным стилем.

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

2
Artru

Эта функция 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">
0
Andres Separ