With the growing number of screen resolutions, devices that support an internet connection (desktop computer, laptops, but also tablets, mobile, TVs, and even your fridge someday), flexibility and scalability has become more and more important for websites. With the new arrival of the MacBook Pro Retina, this went a step further and brought an HiDPI display that was unknown to the market. This means a whole new challenge for web designers who have to find new ways to handle and make images size more flexible to avoid blurry rasterized effects. In this article, we will see how the SVG-format can help us solve this challenge, using an everyday example of a website header with a clickable logo.
My personal roadmap to this project: 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 successful though. Following I’ll show you how good the alternatives will perform.
Here is a visual of what we will build:
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 an 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 plugin http://fireworks.abeall.com/extensions/commands/Export/ for this task.
Save a SVG logo with Ilustrator using save as > svg inside the format dropdown
Just remember a few rules when creating an 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 :
The code :
<a href="#" > <object class="logo" data="https://www.noupe.comhttps://www.noupe.comhttps://www.noupe.comhttps://www.noupe.comlogo.svg" width="186" height="235" type="image/svg+xml"> <img src="https://www.noupe.comhttps://www.noupe.comhttps://www.noupe.comhttps://www.noupe.comlogo.png" width="186" height="235" 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
The code
<a href="#svg_technique" > <svg class="logo" 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="https://www.noupe.comhttps://www.noupe.comhttps://www.noupe.comhttps://www.noupe.comlogo.png" width="186" height="235" 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.
The code
<a href="#catching_error" > <img class="logo" src="https://www.noupe.comhttps://www.noupe.comhttps://www.noupe.comhttps://www.noupe.comlogo.svg" alt="A sample SVG button." width="186" height="235" alt="Logo Geeks and the City" onerror="this.removeAttribute('onerror'); this.src='https://www.noupe.comhttps://www.noupe.comhttps://www.noupe.comhttps://www.noupe.comlogo.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 use Modernizr 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.
The HTML code
<a href="#modernizr_css_fallback" > <img class="logo" src="https://www.noupe.comhttps://www.noupe.comhttps://www.noupe.comhttps://www.noupe.comlogo.svg" width="186" height="235" alt="Logo Geeks and the City" /> </a>
The CSS code
/*** specific for fallbacks **/ #modernizr_css_fallback img.logo { display:none; } #modernizr_css_fallback a{ display:block; width:186px; height:235px; background-image: url(https://www.noupe.comhttps://www.noupe.comhttps://www.noupe.comhttps://www.noupe.comlogo.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.
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.
The HTML code:
<a href="#img_modernizr_js_remplacement_bis" > <img class="logo" src="https://www.noupe.comhttps://www.noupe.comhttps://www.noupe.comhttps://www.noupe.comlogo.svg" alt="A sample SVG button." width="186" height="235" data-fallback="https://www.noupe.comhttps://www.noupe.comhttps://www.noupe.comhttps://www.noupe.comlogo.png" alt="Logo Geeks and the City" /> </a>
The JavaScript code:
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.
The HTML code:
<a href="#img_modernizr_js_remplacement_nojs"> <noscript><img class="logo" src="https://www.noupe.comhttps://www.noupe.comhttps://www.noupe.comhttps://www.noupe.comlogo.png" alt="A sample SVG button." width="186" height="235" alt="Logo Geeks and the City" /></noscript> </a>
The JavaScript code
window.onload = function(){ if(Modernizr.svg) { $('#img_modernizr_js_remplacement_nojs .header a').html('<img src="https://www.noupe.comhttps://www.noupe.comhttps://www.noupe.comhttps://www.noupe.comlogo.svg" width="186" height="235" alt="Logo Geeks and the City"/>'); } else { $('#img_modernizr_js_remplacement_nojs .header a').html('<img src="https://www.noupe.comhttps://www.noupe.comhttps://www.noupe.comhttps://www.noupe.comlogo.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:
AddType image/svg+xml svg svgz AddEncoding gzip svgz
More on SVG-usage from around the web:
Conclusion
In this article, we saw different techniques to embed a SVG-logo, with a link back to the homepage of the site. I’m not telling you that one method is better than the other, you will have to choose. At the moment, I’m using the last solution on the live website I did this research for, but that’s just personal preferences. There must also be other solutions to achieve this and I would be glad to hear about how you manage this challenge, so don’t hesitate to share your results in the comments! So, will you try to use some SVG logos on your website soon? What is your favorite technique?
(dpe)
Banner Image by Free Photos from Pixabay
Send Comment:
15 Comments:
More than a year ago
Stéphanie, I just came up with a different solution than yours. Hope this helps.
Same window: onmouseover=”this.style.cursor=’pointer’;” onclick=”window.location.href=’ onmouseout=”this.style.cursor=’default’;” background=”
New window: onmouseover=”this.style.cursor=’pointer’;” onclick=”window.open(‘’);”
background=”
Regards,
Nate
More than a year ago
Thanks for this post :)
I'm making my first steps with svg right now so I came back to read this post again.
For the object hidden behind the link, z-index is the savior:
.logo {
position: relative;
z-index: -1;
}
See ya! ;)
More than a year ago
Thanks for the post. I've learned many things from this site. Love it so much..!! :) :)
More than a year ago
[...] Noup September 13, 2012 13 Sep 2012 [...]
More than a year ago
Thanks for good information about svg-placement.
A way to get the link to work with the object method is to add an extra linked div on top of the logo with the logo like this:
More than a year ago
If you have many SVG images on a page, does it make sense to give them a class and id and replace PNG raster images with SVG images when appropriate? I was thinking a for-loop might do the trick:
Clickable SVG Images With PNG Fallback
if (Modernizr.svg) {
svgarray = document.querySelectorAll('.svgrep')
for (var i = 0; i < svgarray.length; i++) {
var myid = svgarray[i].id;
var mysrc = document.getElementById(myid);
var mylink = document.getElementById(myid).src;
mysrc.src = mylink.replace('.png','.svg');
}
}
Mind you, I'm not a web developer, so let me know if I'm out to lunch here, but I think this is close to what you showed in your last example (not exactly, though). Are there any downsides to this approach? I'm thinking that it might be a bit easier to maintain for a page with many images.
Thanks again for the great tutorial!
More than a year ago
This is the best tutorial on all of the internets for implementing clickable SVG images with PNG fallback for older browsers. Thank you!
More than a year ago
Article very interesting and original, thank you !
More than a year ago
Nice write-up of the different methods!
There's a nice solution using IE conditionals and the img tag that doesn't require JS, doesn't require a css fallback, and doesn't make more requests than needed:
More than a year ago
perfect, my website run with worldpress too, thanks for reply me, i'll try it out
More than a year ago
Wow, excellent question, never thought of it. I would say it depends on the client.
More than a year ago
can I embed it into a mail client?
More than a year ago
Sure why could you not ? You an use PHP to generate the HTML templates so yes this would work. I myself use it on WordPress, which PHP behind
More than a year ago
Very clear, but can i use it with PHP
More than a year ago
This is awesome! i got to know the different techniques to embed a SVG-logo, with a link back to the homepage of the site through this post! It is really very useful stuff! I am really happy to found this information on your blog.