Semblance Digital Studio

Design and digital studio for startups, using WordPress as a CMS

  • Home
  • Services
  • Projects
  • Blog
  • Contact
You are here: Home / Blog / SVG & Animation / How to add a responsive SVG, that can be styled and animated, to your web page

How to add a responsive SVG, that can be styled and animated, to your web page

Posted on 27 July 2016 in SVG & Animation ♦ Estimate reading time: 10 minutes ♦ by Elzette Roelofse

The purpose of this article, is a combination of my findings around the internet, searching and learning the best way of adding a responsive SVG image to a web page. At the same it should also have the ability to edit styles and animation from an external JavaScript file.

In general there are six ways to embed SVG files to your web page:

  1. As an image using the <img> element
  2. As a background image in CSS
  3. As an object using the <object> element
  4. As an iframe using an <iframe> element
  5. Using the <embed> element
  6. Inline using the <svg> element

Embedding an inline SVG

When embedding a SVG this way, style rules can be added anywhere in the document to target specific elements of the SVG. Unlike with the other embedding techniques, styles don’t need to be included between the opening and closing <svg> tags to work. It can be styled from eg. an external CSS file.

The downside to this technique though, adding a “code island”, makes the source code look messy and add to the page size. In this format it can also not be cached and end up rendering the same amount of time with every visit to the page.

★ Embedding a SVG using the <object> element

To avoid the SVG “code island”, whilst using advanced features such as CSS and scripting, the HTML5 <object> element is the best option to include an external SVG file.

Advantages to this method:
  • Keep the source code clean
  • Can be cached by the browser
  • Can still access the SVG elements for styling and animation
  • Straight forward to add a fallback image or text for ‘non-svg’ browsers, it will then display the fallback content between the opening and closing <object> tags (see example code below)
<object type="image/svg+xml" data="myImage.svg">
  <div class="fallback-img"></div>
</object>

For browsers that do not support SVG, let it fall back to a raster version of the image. But instead of adding it with <img>, instead add it as a background image via CSS. If you add the image directly using <img>, browsers that support SVG will request both the SVG and the fallback image, resulting in an unnecessary extra HTTP request. With the example above, just add the following to the CSS file (read more about it in David Bushell’s primer to SVG on his blog):

.fallback-img {
  background-image: url(path/to/fallback/myImage.png); 
  /* other styles here */ 
}

Adding CSS

Whilst embedding a SVG using the <object> element, I found styling elements within the SVG via an external CSS file did not work. But it does however when you place the styles within the SVG element inside <style>. The styles (and scripts for that matter) also need to be wrapped between <![CDATA[ ... ]]> to avoid any parsing errors. Eg.:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 68 65">
  <style type="text/css">
    <![CDATA[
    .block { fill: blue; }
    ]]>
  </style>
  <rect class="block" x="0" y="0" width="100" height="100" />
</svg>

Adding scripting

In this example I want to use jQuery animate() or even better Velocity.js, an animation engine with the same API as jQuery animate(). The thing is, using the <object> element to display the SVG and then try selecting elements inside the SVG is not that straightforward. Reason being, jQuery do only understand the HTML DOM, but not the SVG DOM. To get around this, use vanilla JavaScript to wrap everything in a window.onload function. Then select the element with document.getElementById() functions and get the SVG document inside the Object tag using contentDocument.

I found Ben Frain’s article, Select an SVG inside an <object> tag with JavaScript, with code examples very useful to get things going with this approach.

Making it responsive

I use the latest Adobe Illustrator to export the SVG, using the responsive option (also make sure to read Sara Souiedan’s article, Tips for Creating and Exporting Better SVGs for the Web). This delete the height and width attributes, that is necessary to make the image responsive. The viewBox attribute however, need to stay as is.

Unfortunately, because of Internet Explorer, a bit more work needs to be done to make the <object> element display the SVG responsive. First off, explicitly set the width of the <object> to 100% in the CSS file. This works great for all modern browsers, except in IE, where the <object> element always default to 150px high. I use the padding hack by Thierry Koblentz as a workaround. Originally applied making videos in an iframe responsive.

Make sure the <object> element is wrapped in a container.

<div class="object-container">
  <object type="image/svg+xml" data="myImage.svg">
    <div class="fallback-img"></div>
  </object>
</div>

For the container, the following styles need to be applied with the formula indicated:

.object-container {
  height: 0; /* Collapse the container's height */
  width: width-value; /* Specify the width in percentage */
  padding-top: (svg-height ÷ svg-width) × width-value;
  /* The above padding formula makes sure the aspect ratio of the container equals that of the SVG graphic */
  position: relative; /* Create positioning context for SVG */
}

With the height of the container collapsed and a huge bit of padding applied, this will push the <object> element out the bottom of its container. To get it back up within its container, the <object> need to be positioned absolutely. Hence also adding the position: relative to the container. For styling the <object> element inside the container, it will be something like this:

object {
  height: 100%;
  left: 0;
  position: absolute;
  top: 0;
  width: 100%;
}

When using a “code island”…

For a different use case it might be better or necessary to add the SVG as a “code island” instead. If so, the above mentioned technique to make it responsive will still be necessary, but the <svg> element becomes the absolute positioned element instead of <object>. All the styles however can go into the external stylesheet. Animations from a JavaScript can also be from an external JS file, targeting elements directly by referencing them by class or id.

 

Related Posts

  • Some Costumes at Venice Carnival 2010Some Costumes at Venice Carnival 2010
  • BarCamp London 7 #bcl7BarCamp London 7 #bcl7
  • September Reading: JavaScript & JQuerySeptember Reading: JavaScript & JQuery

No Comments

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

semblance logo enquiries@semblance.design © 2022
  • Email
  • Twitter
  • Instagram