Best Practice for Using Svg Images

What are the best practices for images/svgs being used for multple img elements?

a svg file can be used as many times as you need in the src attribute. There's nothing wrong using the same file multiple times.

e.g.

<img class="image-1" src="src/chance.svg" />
<img class="image-2" src="src/chance.svg" />

.image-1 {
// styles here
}
.image-2 {
// styles here
}

The approaches to using SVG images

The answer is, should you be worrying about who's looking at your code? SVG inline will always bloat your HTML depending how complex the drawn SVG is. Inline does in some respect have better performance implications due to the fact it's being loaded directly with the HTML as opposed to loading the SVG externally when using it, for example, as an <img>. However, it's practically unnoticeable and should be the least priority when coming down to performance.

The disadvantages of inline SVG:

  • Bloats code
  • Cannot be cached by the browser
  • No fallback available
  • IE, without XHTML (and that's if SVG is supported) doesn't support SVG technically, though this is a low priority and we shouldn't care about it in the current world of the web. Still, it's primarily a disadvantage to those ancient warriors.

The advantages of inline SVG:

  • I can't think of any, seriously. Other nosey people can see it?
  • Actually, those without CSS enabled can see it.

The disadvantages of using <img> with SVG:

  • Again, limited fallback support (You can use Modernizr to replace the .svg extension with .png, but then you rely on the user having javascript enabled)
  • Limited styling options with the SVG

The advantages of using <img> with SVG:

  • Semantically better than bloating all your code
  • Readability in your codebase is better for a) yourself and b) other developers who might be working on the project too.
  • Better maintainability.

Alternative methods:

You can use the following methods you provided in your question (and below) about using <object>, <embed> and <iframe>, although, these also limit the use cases and would need declaring in every HTML document, which can get messy as you progress in a project, whether it be large or small.

The 'better approach':

Disclaimer: By no means is the a 'better for everyone' method. This is simply how I would declare my SVG elements for reusability and gives me full control of identifying my assets when using SVG.

The biggest pitfall for using inline SVG in your HTML is the fallback support. I have always used SVG as a background image (unless it's a webfont I'm using for icons etc.), purely because I can create a .png version and write the fallback in my CSS, like so:

.icon {
display: inline-block;
vertical-align: baseline;
background-repeat: no-repeat;
background-position: center center;
background-size: contain;
}

.icon--16 {
width: 16px;
height: 16px;
}

/* Always declare the PNG before the SVG. */
.icon--foo-blue {
background-image: url('foo-blue.png'); /* Fallback */
background-image: url('foo-blue.svg'), none; /* Modern */
}

.icon--foo-green {
background-image: url('foo-green.png'); /* Fallback */
background-image: url('foo-green.svg'), none; /* Modern */
}

Then, use it:

<span class="icon icon--16 icon--foo-blue"></span>
<span class="icon icon--16 icon--foo-green"></span>

The disadvantage of this:

  • No support for CSS styling, however, we should be aware of why we are styling SVG in our CSS. If you're using more colours than your website uses then there is generally something not right. Declaring 4 files for the same SVG but in a different colour is not bad practise as it allows us to cache these in the browser for later, throughout any webpage which in the answer constructed below completely removes this purpose. Take advantage of caching on the server/within the browser!

And of course, it depends what kind of image you are trying to render to the user. If you're going to use large SVG files for showcasing something, for example, I would probably think about what kind of users I'm targeting; that being, those on modern browsers because I might want to include fancy inline SVG animations etc.

It really depends on personal preference too. There is no major red flags for using SVG inline to this day, but we still have some heart for those back in the stone ages of less-than IE9. And, not to forget, Android is quirky with SVG too!

EDIT: It seems like there is a large debate over inline SVG's. One word of warning is, there is no reusability doing this. If you're showcasing a fancy website with fancy SVG animations, then by all means, build your entire page in SVG for crying out loud. No one is stopping you. It's personal preference. But for icons, where you will more than likely reuse throughout a project, please, declare them outside your HTML as it gives you greater control in the long run and not because you need a different colour here and there. Think about it. :)

What are best practices for using SVG icons on Android?

For Android older than Lollipop, your best practice for SVG on Android is going to be to use a tool to convert your SVG to PNG at the size(s) you're interested in. Existing SVG support for Android is not comprehensive of what you're likely to find in an SVG file, and even if it were, the support is not built into the OS so using them directly for icons is definitely out.

Beginning with Lollipop (API 21) see What are best practices for using SVG icons on Android?. Thanks to @MarkWhitaker @AustynMahoney for pointing this out.

Do I use img, object, or embed for SVG files?

I can recommend the SVG Primer (published by the W3C), which covers this topic: http://www.w3.org/Graphics/SVG/IG/resources/svgprimer.html#SVG_in_HTML

If you use <object> then you get raster fallback for free*:

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

*) Well, not quite for free, because some browsers download both resources, see Larry's suggestion below for how to get around that.

2014 update:

  • If you want a non-interactive svg, use <img> with script fallbacks
    to png version (for older IE and android < 3). One clean and simple
    way to do that:

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

    This will behave much like a GIF image, and if your browser supports declarative animations (SMIL) then those will play.

  • If you want an interactive svg, use either <iframe> or <object>.

  • If you need to provide older browsers the ability to use an svg plugin, then use <embed>.

  • For svg in css background-image and similar properties, modernizr is one choice for switching to fallback images, another is depending on multiple backgrounds to do it automatically:

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

    Note: the multiple backgrounds strategy doesn't work on Android 2.3 because it supports multiple backgrounds but not svg.

An additional good read is this blogpost on svg fallbacks.

What is the easiest way to use SVG images in Android?

First, you need to import SVG files by the following simple steps.

 1. Right click on your project's drawable folder (app/res/drawable)
2. Click New
3. Select Vector Asset

If the image is available on your computer, select the local svg file.

After that, select the image path. An option to change the size of the image is also available on the right side of the dialog if you want to. In this way, the SVG image is imported into your project.

After that, for using this image, use the same procedure:

@drawable/ic_image_name


Related Topics



Leave a reply



Submit