首页 文章

我是否将<img>,<object>或<embed>用于SVG文件?

提问于
浏览
499

我应该使用 <img><object><embed> 以类似于加载 jpggifpng 的方式将SVG文件加载到页面中吗?

每个代码的代码是什么,以确保它尽可能好地工作? (我在我的研究中看到了包括mimetype或指向后备SVG渲染器的参考,并没有看到一个很好的最新参考) .

假设我正在检查带有Modernizr的SVG支持并且为非支持SVG的浏览器退回(可能用普通的 <img> 标签替换) .

10 回答

  • 14

    从IE9及以上版本,您可以在普通的IMG标签中使用SVG .

    https://caniuse.com/svg-img

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

    我可以推荐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>
    

    *)嗯,不完全是免费的,因为有些浏览器下载这两种资源,请参阅Larry关于如何解决这个问题的建议 .

    2014 update:

    • 如果你想要一个非交互式svg,请使用带有脚本回退的 <img> 到png版本(对于较旧的IE和android <3) . 一个干净简单的方法:

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

    这将与GIF图像非常相似,如果您的浏览器支持声明性动画(SMIL),则会播放这些动画 .

    • 如果需要交互式svg,请使用 <iframe><object> .

    • 如果您需要为旧浏览器提供使用svg插件的功能,请使用 <embed> .

    • 对于css background-image 中的svg和类似属性,modernizr是切换到后备图像的一种选择,另一种是依赖于多个背景来自动执行:

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

    Note :多重背景策略在Android 2.3上不起作用,因为它支持多个背景但不支持svg .

    另一个好的读物是关于svg后备的this blogpost .

  • 79

    This jQuery function captures all errors in svg images and replaces the file extension with an alternate extension

    请打开控制台查看 error loading image 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">
    
  • 15

    最好的选择是在不同的设备上使用SVG图像:)

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

    我个人会使用 <svg> 标签,因为如果你这样做,你可以完全控制它 . 如果您在 <img> 中使用它,则无法使用CSS等控制SVG的内部结构 .

    另一件事是browser support .

    只需打开 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 tips

  • 19

    如果您需要使用CSS完全样式化SVG,则必须在DOM中内联 . 这可以通过SVG注入来实现,它使用Javascript在页面加载后用SVG文件的内容替换HTML元素(通常是 <img> 元素) .

    这是使用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的合着者

  • 1

    使用srcset

    大多数current browsers today support the srcset attribute,允许为不同的用户指定不同的图像 . 例如,您可以将其用于1x和2x像素密度,浏览器将选择正确的文件 .

    在这种情况下,如果您在 srcset 中指定了SVG,并且浏览器在 src 上没有't support it, it' ll回退 .

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

    与其他解决方案相比,此方法有几个好处

    • 它不依赖于任何奇怪的黑客或脚本

    • 很简单

    • 您仍然可以包含替代文字

    • 支持 srcset 的浏览器应该知道如何处理它,以便它只下载它需要的文件 .

  • 83

    找到一个纯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 .

    您可以在my blog找到更多详细信息和测试流程 .

  • 8

    如果使用 <img> 标记,则 webkit based browsers 将不会显示 embedded bitmapped images .

    如果您使用内联SVG,则Explorer将不会根据您的CSS调整SVG的大小 .
    Explorer will resize the SVG correctly ,但您必须同时指定高度和宽度 .

    我发现<object>标签是唯一适用于所有浏览器的标签 . 我必须将宽度和高度(在SVG内)更改为100%才能使其正确调整大小 .

    您可以在svg中将 onclick, onmouseover, etc. 添加到SVG中的任何形状:onmouseover = "top.myfunction(evt);"

    您也可以在SVG中使用 web fonts ,将它们包含在常规样式表中 .

    注意: if you are exporting SVG's from Illustrator, the web font names will be wrong. 您可以在CSS中更正此问题,避免在SVG中乱七八糟 . 例如,Illustrator为Arial提供了错误的名称,您可以像这样修复它:

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

    所有这些都适用于 any browser released in the last two years .

    Results at ozake.com (in French). 整个网站由SVG组成,联系表格除外 .

    警告:Web字体未精确调整大小,如果您有大量从纯文本到粗体或斜体的过渡,则过渡点可能会有少量额外或缺少的空间 . 看到我的回答在this question获取更多信息 .

  • 8

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

相关问题