Showing posts with label SVG. Show all posts
Showing posts with label SVG. Show all posts

Monday, May 05, 2014

Injecting SVG With JavaScript

Injecting SVG With JavaScript

"Injecting SVG" – it sounds kinda complicated I know, but trust me it's not. It's actually super-simple! Right now you're probably thinking "Why would you use JavaScript to inject SVG markup? What is it? And how does it work?". Let me explain.

Friday, February 07, 2014

Fullscreen Overlay Effects

Some simple and creative overlay styles and effects. From sliding the overlay into the viewport to using SVG morphing shapes, we explore some effects for fullscreen overlays.

Fullscreen Overlay Effects

Wednesday, January 15, 2014

SVG Hover Effect

Friday, December 13, 2013

SVG Icons FTW

SVG Icons FTW

Despite the growing popularity of SVG, its time around and excellent browser support, we have a lack of good vector icon approaches. It's time to fill this gap and use SVG as icons in our web projects.

A lot of great methodologies and principles arose making our CSS more and more modular, structured and flexible. But think about your icons. Using raster graphics for icons means that they are not manageable in CSS. What if we need to change a color of an icon for its hover/active/focus state? For each icon state we need to add one more icon image. What about size? For each icon size we need to add yet another icon image. What about a shape? A shadow? Yup, the same thing. Not very convenient, right? So we are ending up with bloated sprites and style sheets that are hard to maintain and scale.

But fortunately we've had icon fonts coming to the rescue. They allow us to manage all these things more easily and we have the following benefits:

  • It's plain text, which means they can be gzipped to up to 95%
  • It's a vector graphic, which means it can be scaled to any size making it Retina ready
  • It's one source file, which means a minimum of HTTP requests
  • It's a font – you can easily change size, color, shape and add a shadow
  • Browser support for older browsers possible (e.g. IE6)

Unfortunately, icon fonts have some limitations like being monochrome (still) and we can only use styles for texts like e.g. a text-shadow. We can't, for example, use an inset text shadow or apply different colors to the details.

So today we will explore the possibilities of using SVG icons instead.

Using SVG Icons

The icon solution I want to share here with you is based on SVG (Scalable Vector Graphics). Extending the benefits of icon fonts, it will give us some additional super powers:

  • The power of consistently crisp rendering across browsers and operating systems.
  • The power of CSS. We will obtain the ability to style our icons with CSS.
  • The power of SVG filter effects.
  • The power of interactivity. We will be able to use animations with SMIL, CSS or JavaScript.
  • The power of the Markup language.

Currently, SVG looks more like a retired super hero. For humanity's sake, let's kick him off the sofa and send him to the gym.

Getting Started

First, we'll need to get some SVGs to work with. I'm assuming you are familiar with vector graphics and know how to create or where to get a SVG file. Check out this article for a good introduction on how to create and work with SVGs. For this tutorial we'll be using this SVG file. All demos you will see here will actually be working pens, so you will have the opportunity to play with them live.

At this point we have a vector graphic to play with, so let's add an empty SVG document just after the opening body tag.

I will refer to this SVG as "SVG source document" throughout this tutorial.

Let's add the "inner" SVG source into the empty SVG declaration and give this shape a unique ID for future reference.

<!doctype html>
<html>
<head>
    <meta charset=utf-8 />
</head>
<body>
  <!-- SVG SOURCE -->
  <svg height="0" width="0" style="position:absolute;margin-left: -100%;">
    <path id="heart-icon" d="M256,465.559c0,0- 239.054-135.345-239.054-291.062c0-159
       .761,224.692-177.574,239.054-7.756 c17.244-169.692,239.054-152.008,239.054,
       7.756C495.054,330.214,256,465.559,256,465.559z"/>
  </svg>
  <!-- SVG SOURCE ends-->
<body>
<html>

Find this code on Codepen

If your shape consist of many small chunks, you'll need to wrap them all with a g tag and add an ID to that group.

Now we can "use" this graphic wherever we want in our HTML document with the help of use. The xlink:href attribute is a reference to our shape by its ID:

<!doctype html>
<html>
<head>
  <meta charset=utf-8 />
</head>
<body>

<!-- SVG SOURCE —>
...
<!-- SVG SOURCE ends —>

<svg class="icon" viewBox="0 0 32 32"
    <use xlink:href="<strong>#heart-icon</strong>">
</svg>

</body>
</html>


Isn't that nice?

The use element takes nodes from within the SVG document and duplicates them somewhere else. The effect is the same as if the nodes were deeply cloned into a non-exposed DOM and then pasted where the use element is, much like anonymous content and XBL.— Mozilla DN

Thoughtful readers probably noticed the most interesting part of the above pen: we can simply use CSS to style our icons. Take a look:


The set of properties we can work with is pretty large. The most useful and common ones are:

  • width and height
  • icon color by using the fill property
  • stroke by setting stoke or stroke-width

Styling these properties will give us many possibilities. But let's make it even better – let's add our wanted inset shadow.

Adding Filter Effects

Filter effects are the real super powers of SVG and if you are interested in a detailed overview, check out Filter Effects – SVG 1.1 (Second Edition) and SVG Filters by Mike Sierra.

Let's work with some pre-made filters. Fortunately, there are a lot of ready-to-use SVG filters around.

To use a filter effect with our icon we need to declare it in our "SVG source document" with a unique ID for referencing, just like the we did with the icon but now we'll have a filter tag.

<filter id='inset-shadow'>
    <!-- Shadow offset -->
    <feOffset
    dx='0'
    dy='0'
    />

    <!-- Shadow blur -->
    <feGaussianBlur
    stdDeviation='1'
    result='offset-blur'
    />

    <!-- Invert drop shadow to make an inset shadow -->
    <feComposite
    operator='out'
    in='SourceGraphic'
    in2='offset-blur'
    result='inverse'
    />

    <!-- Cut color inside shadow -->
    <feFlood
    flood-color='black'
    flood-opacity='.95'
    result='color'
    />

    <feComposite
    operator='in'
    in='color'
    in2='inverse'
    result='shadow'
    />

    <!-- Placing shadow over element -->
    <feComposite
    operator='over'
    in='shadow'
    in2='SourceGraphic'
/>

Now, let's add the reference to the filter to a new group wrapper:

<svg viewBox="0 0 32 32">
  <g filter="url(#inset-shadow)">
    <use xlink:href="#heart-icon"></use>
  </g>
</svg>

Check out the following examples of SVG filters:

Inset shadow


Drop shadow


More examples


Isn't this awesome?

Adding Interactivity

As I've mentioned at the beginning of this tutorial, we can use SMIL, CSS or JavaScript for animating icons.

So let's bring some life to our icons! We'll create a working animated clock which will be great for showing the possibilities of what we can do.

We will start with an alarm clock icon as the "SVG source document". It consists of different shapes wrapped in a group with the ID #clock-icon for reference.


Icon credits go to visualpharm. License: CC by-nd 3.0.

I've also added some other IDs like #hour-hand, #minute-hand and #second-hand where appropriate for referring to the paths in the animation we will create.

Now, let's declare a rotation 2D transform for each of the clock hands.

For that we'll add a transform value of rotate(0 16 17) where

  • 0 is the amount of degrees the clock hand is rotated
  • 16 17 simply the center of our rotation on the X and Y axis.

So, using this rotation value

<rect id="hour-hand" transform="rotate(320 16 17)" x="15.386" y="10.291" width="1.227" height="7.626"/>

will rotate hour clock hand 320 degrees.

Take a look at the demo:


The next step is to add an animation of the rotation we made above. For this purpose we will use some JavaScript and set a new rotate value every full second:

<script>
    var setTime = function(){
      var date = new Date(),
      MINUTE = 60, HOUR   = 60*MINUTE,
      seconds = date.getSeconds(),
      minutes = (date.getMinutes()*MINUTE) + seconds,
      hours = (date.getHours()*HOUR)+minutes;

      document.getElementById('second-hand').setAttribute('transform', 'rotate('+360*(seconds/MINUTE)+',16,17)');
      document.getElementById('minute-hand').setAttribute('transform', 'rotate('+360*(minutes/HOUR)+',16,17)');
      document.getElementById('hour-hand').setAttribute('transform', 'rotate('+360*(hours/(12*HOUR))+',16,17)');
    }
    setTime();
    var interval = setInterval(setTime,1000);
</script>


Isn't this awesome?

If you are interested in seeing a version using SMIL animation, you can take a look at this demo. Also, check out the CSS version (both demos best viewed in Chrome). Note that SMIL animation support is limited.

Using Media Queries

We can use isolated CSS and especially media queries inside of our SVG icon. That means that we have the ability to change, for instance, a shape of an icon depending on screen size and more. We'll use this kind of inline style for this purpose:

<style>
   <![CDATA[ 
    @media screen and (max-width:810px){
      .hide{
        display: none;
      }
    }
   ]] >
</style>

Try to resize the browser when viewing this pen in a new window to less or more than 810 pixel.


Isn't this... SVG?

More Fun With SVG Icons

SVG Icons FTW

Let's do something fun with all these things we've just gone over. The demo below shows differently sized and filled icons, with some JS animations:


View this demo in full page

In the next demo we'll add some filter effects:


View this demo in full page

Having all these superpowers, the only limit is your imagination.

Browser Support

What we have done so far should work well in all popular modern browsers:

  • IE 9+ (filter effects since IE10)
  • Mozilla 4+
  • Opera 11.6+ (filter effects since Opera 12)
  • Safari 5.1+ (filters since Safari 6)
  • Chrome 14+ (at least)

Performance

After running a couple of tests, it shows that SVG icons are about two times slower compared to using a .wof icon font in Chrome. The time cost of the first paint operation is about 0.05 millisecond per icon or about 1.453ms for an average of 30 icons per user's view.

Conclusion

SVG Icons FTW

Let's look back and analyze what we've done.

Using SVG as icons in our web projects gives us the following advantages:

  • Only one HTTP request
  • Scalable vector and hence intrinsically Retina ready
  • Easy styling of color/size/effects in CSS
  • SVG icons are "light-weight" (the heart icon from my examples has only 189 bytes not gzipped)
  • It's text so it can be gzipped up to 95%
  • Power of SVG filter effects
  • XML like structure
  • We can have multi-colored icons
  • We can make use of isolated styles and media queries
  • We can make use of isolated animations with SMIL, CSS or JS
  • Supported by all major modern browsers

The IconMelon Project

SVG Icons FTW

As you have seen, using SVGs in your web project gives you a lot of possibilities but it would be great to have some kind of boilerplate for the icons itself, the filters and the CSS. So, I've been working on a free and open project called Iconmelon which aims to collect free SVG icon sets and provide a filter and CSS boilerplate. You can create your icon sets and download all the needed files and also submit your own graphics.

SVG Icons FTW

It's a brand new project so if you see any issues or have any feedback please let me know. Please also check out the support us page to see how you can help it grow.

Friday, August 23, 2013

SVG Fallbacks

SVG Fallbacks

There is a very clever technique by Alexey Ten on providing an image fallback for SVG going around the internet recently. It does just what you want in the classic no-SVG-support browsers IE 8- and Android 2.3. If we dig a little deeper we find a some pretty interesting stuff including a bit of unexpected behavior that is a bit of a bummer.

Wednesday, April 03, 2013

Using SVG

Using SVG

Further reading: Why Aren't You Using SVG?

SVG is an image format for vector graphics. It literally means Scalable Vector Graphics. Basically, what you work with in Adobe Illustrator. You can use SVG on the web pretty easily, but there is plenty you should know.

Thursday, September 27, 2012

Why aren’t you using SVG?

Why aren’t you using SVG?
SVG, or Scalable Vector Graphics, is a XML-style markup driven vector graphic rendering engine for the browser. SVG is supported in every browser, except IE < v9 and Android < v3. The same support is available for canvas (except canvas goes all the way back on Android), so the question often surfaces: which one should you use?

Today, we will survey SVG and explain why the question of "which one should I use?" is usually answered by "what am I trying to do?". To get a full list of elements that make up SVG, check out Mozilla's docs on the subject. You can see the SVG DOM API there as well.