Embeding SVG Images into a Website PDF Print E-mail
Written by webmaster   
Saturday, 05 July 2014 21:13

My personal notes: What I wanted to achieve

From a UX / code point of view,  I wanted two things for my logo:

  • Since it’s the logo of my brand, I wanted it to be clickable so that users can easily go back to the homepage
  • I’m a nice girl and don’t want to penalize people with older browsers, so I wanted to provide some PNG-fallback for our older friends. If possible, the fallback should work without JavaScript.

Taking a look at these two things, I ran some tests, and found a few different code variants to achieve this result. They proved not equally successfull though. Following I’ll show you how good the alternatives will perform.

Here is a visual of what we will build:

SVG final product

You can see a demo here, or fork the code on github

You can take a look at this table to see the SVG support in browsers.

The SVG logo: what is this format, and how did I create it?

SVG stands for Scalable Vector Graphics. It is a markup language that enables us to create two-dimensional graphics that are fully scalable.  It is based on an XML syntax, so you can create and open a SVG file in a text editor. Don’t panic, you don’t need to be a hardcore developer to do so.  http://raphaeljs.com/ for example is a very nice library to generate SVG images in an easier way.

If you’re a designer, you can use your favorite design software to create SVG files. Illustrator and Inkscape will do the job nicely and even Fireworks has a little pluginhttp://fireworks.abeall.com/extensions/commands/Export/ for this task.

Save as SVG with Illustrator

Save a SVG logo with Ilustrator using save as > svg inside the format dropdown

Just remember a few rules when creating a SVG logo:

  • Don’t use complex illustrator gradients, only linear and radial ones
  • Don’t use the photoshop effects provided in Illustrator
  • Be careful and name layers and group layers
  • Always merge shapes in the end when using pathfinder.
  • Transform text into vectors shapes to make sure the result will work on devices that don’t have the font.

To sum it up : Keep your SVG drawing as simple as possible, export it, and test in different browsers to see the result.

For my example, I’m using a simple SVG-logo with no gradients and plain colors. (Many thanks to Geeks and the City for letting me kindly use their logo in this example. The logo is their property, I only use it for the example with their consent. You can re-use the code for your projects, but not the logo.)

1. The < object > embed solution

This is the historical solution to embed SVG in webpages. The big advantage of this method is that the fallback is easy to provide, you simple have to add the .png image in an img tag :

See demo

The code :

1
2
3
4
5
6
7
8
9
<a href="#" >
 
<object data="logo.svg" width="186" height="235"&nbsp; type="image/svg+xml">
 
<img src="/logo.png" width="186" height="235"&nbsp; alt="Logo Geeks and the City" />
 
</object>
 
</a>

Pros:

  • The fallback is simple to provide
  • The fallback does not rely on JavaScript

Cons :

  • The link is not displayed on browsers that support SVG, you have to add a display:block to the link. Then the link is hidden “behind” the SVG object, so you can’t click on the logo but around it
  • Modern browsers with SVG support will download both files SVG and PNG
 

2. The <svg> tag solution with foreignObject as fallback

Since HTML5, you can use a  the new <svg> tag.  Remember when I said that SVG was a markup, you can simply copy the markup inside the SVG tag. All you have to do is open the .svg logo in a text editor, and copy paste the code.

In the foreignObject, we will include an img-tag with the .png fallback

See demo

The code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<a href="#svg_technique" >
 
<svg&nbsp; width="186" height="235">
 
<g id="nyt_x5F_exporter_x5F_info">
 
</g>
 
<g id="nudged">
 
<path style="fill:none;stroke:#000000;stroke-miterlimit:10;" d="M46.397,121.92"/>
 
……
 
<foreignObject width="0" height="0" overflow="hidden">
 
<img src="/logo.png" width="186" height="235"&nbsp; alt="Logo Geeks and the City" />
 
</foreignObject>
 
</svg>
 
</a>

Pros

  • The link now works
  • The fallback works without JavaScript activated

Cons :

  • Due to the copy/pasting of the SVG code, this technique is not very flexible, especially for logos. Every time you change it, you have to upload the code
  • Not all browsers implement the syntax correctly since it’s pretty new

3. The <img> solutions, with different fallbacks

A last way of embedding SVG files is to use the img-tag. Note that the tag was not created for this purpose, so you might encounter problems if you use many JavaScripts to modify your SVG object.

a. The <img> solution with JavaScript on error-fallback

Credits where due, I found this technique on Tavmjong Bah’s blog (a great read if you want to go deeper into the SVG manipulation techniques using JavaScripts). This solution suggests using the error handler to detect the SVG support, and replace the .svg by a .png logo when the browser does not support SVG and triggers and error.

See the demo

The code

1
2
3
4
5
<a href="#catching_error" >
 
<img src="/logo.svg" alt="A sample SVG button." width="186" height="235"&nbsp; alt="Logo Geeks and the City" &nbsp;onerror="this.removeAttribute('onerror'); this.src='logo.png'" />
 
</a>

Pros

  • The link works pretty well
  • The code is very simple and we only need one img-tag

Cons

  • The fallback relies on JavaScript and does not work if deactivated

b. The <img> solution with a CSS background fallback

For this technique, we will only provide the SVG image in the HTML, and instead useModernizr to detect SVG support. If the SVG is supported, the script will add a .svg class to the html, if not, it will add a .no-svg.

See the demo

The HTML code

1
2
3
4
5
<a href="#modernizr_css_fallback" >
 
<img src="/logo.svg" width="186" height="235"&nbsp; alt="Logo Geeks and the City" />
 
</a>

The CSS code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/*** specific for fallbacks **/
 
#modernizr_css_fallback img.logo {
 
display:none;
 
}
 
#modernizr_css_fallback a{
 
display:block;
 
width:186px;
 
height:235px;
 
background-image: url(logo.png);
 
background-color:transparent;
 
text-indent:-999px;
 
color:transparent;
 
margin:0 auto;
 
}
 
.svg #modernizr_css_fallback img.logo {
 
display:block;
 
}
 
.svg #modernizr_css_fallback a{
 
background: none;
 
}

This one gets a little tricky, let’s explain it. In order to make this work without JS activated, we will not use the .no-svg class. First we will hide the image for one simple reason: Internet explorer 8 and browsers that don’t support SVG will otherwise display the title of the img. If we put the background on the img-tag, we will see both the background, and the alt-attribute displayed above.

alt tag shown on IE

Internet explorer shows the alt-tag on top of the background

Instead, we hide the image, and put the background PNG-file in the a-tag.

Now, if SVG is supported, we get the .svg class in the html-tag, and do it all the way around: We display the img-tag, with the SVG in it, and hide the CSS background of the a-tag.

Pros:

  • The link works
  • The fallback works without JavaScript

Cons:

  • Not really a con, but we have to cheat and apply the background to the a-tag
  • If JavaScript is deactivated, browsers that do support SVG will get the PNG-fallback.

c. The <img> method with modernizR SVG detection to provide data-fallback fallback

In this method, we will use the new HTML5 data-attributes to provide the fallback file, coupled with modernizr to swap the image for browsers that do not support SVG.

See demo

The HTML code:

1
2
3
4
5
<a href="#img_modernizr_js_remplacement_bis" >
 
<img src="/logo.svg" alt="A sample SVG button." width="186" height="235" data-fallback="logo.png"&nbsp; alt="Logo Geeks and the City" />
 
</a>

The JavaScript code:

1
2
3
4
5
6
7
8
9
10
11
window.onload = function(){
 
if(!Modernizr.svg) {
 
var imgs = $('img[data-fallback]');
 
imgs.attr('src', imgs.data('fallback'));
 
}
 
}

Using modernizr, we detect the SVG-support. If the SVG is not supported, we replace our logo with a .png one, using JavaScript.

Pros

  • The link works
  • The code is simple and clear

Cons

  • The fallback relies on JavaScript and does not work if it is deactivated

d. The <img> method with JavaScript and < noscript > as fallback

Once again, we use the image-tag, but this time, we will provide a noscript-tag with the .png-image in it, in case JavaScript is deactivated.

See demo

The HTML code:

1
2
3
4
5
<a href="#img_modernizr_js_remplacement_nojs">
 
<noscript><img src="/logo.png" alt="A sample SVG button." width="186" height="235" alt="Logo Geeks and the City" /></noscript>
 
</a>

The JavaScript code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
window.onload = function(){
 
if(Modernizr.svg) {
 
$('#img_modernizr_js_remplacement_nojs .header a').html('<img src="/logo.svg" width="186" height="235" alt="Logo Geeks and the City"/>');
 
}
 
else {
 
$('#img_modernizr_js_remplacement_nojs .header a').html('<img src="/logo.png" width="186" height="235" alt="Logo Geeks and the City">');
 
}
 
}

We detect SVG-support, swap the image for the SVG-logo if supported, and the PNG if not.

Pros

  • The link works
  • Works with JavaScript desactivated

Cons

  • If JavaScript is deactivated, browsers that support SVG will display the noscript PNG-fallback.

Going further: font-icon and htaccess-trick for the road

In this article, I did not mention the font-icon embedding-technique. You can see the Icon Fonts are Awesome page to have a little demo, and find a nice list of icons here. I did not use this technique, because I thought it was not very appropriate and creating a font just for a simple logo was maybe “too much”.  Also, logos should be images (in the wild sense, I include SVGs into images here), so using a font-icon for a logo on a website was not a solution in my opinion.

Also note that you might have to declare the SVG-format in the .htaccess so that the server delivers the correct header. You can do so by adding this to the .htaccess:

1
2
3
AddType image/svg+xml svg svgz
 
AddEncoding gzip svgz

 

 

Last Updated on Monday, 15 May 2017 06:14
 

Dontate your bitcon: 1MWZh7G4TxZj2VTPiJGXNQahTw2WeChBdT