An SVG That Isn’t All… SVG

When you think of SVG, what do you think of? Vector graphics, right? Maybe some stuff like this?

svg1

That’s good. SVG absolutely excels at graphics like that. It’s unbeatable quality and file size.

But SVG isn’t just a syntax to draw stuff. It’s more than that. Let’s take a look at a few more things SVG can do, which might be a bit eye-opening for some of you:

  1. You can set type in SVG;
  2. You can set raster graphics in SVG;
  3. And you can have interactions and animations in SVG.

Let’s incorporate all of these into a single SVG so you can see how that all works. And I’ll throw in some bonuses along the way.

NOTE: The graphics in this blog post will be .png files due to blogging platform limitations. Not browser limitations, though. Everything presented here is pretty well supported across all browsers. If you’d like to see the actual SVG, check it out here.

1) STARTING WITH SOME VECTOR GRAPHICS

Here’s our stage, so to speak:

<svg viewBox=“0 0 300 180”>
</svg>

Within that, I can draw vector stuff. Like <circle>, <polygon>, or any of the other SVG drawing stuff.

<svg viewBox=“0 0 300 180”>
 <polygon points=” … “>

 <circle/>
 <circle/>
 <circle/>
</svg>

Here’s an example of some fairly simple vector graphics on our SVG stage:

svg2

2) ADDING RASTER GRAPHICS

In HTML, we have the <img> element. It’s not that different in SVG! It’s like this:

<svg viewBox=“0 0 300 180”>
 …

 <image xlink:href=“/images/wonder-woman.jpg”  width=“945” height=“370” />
</svg>

That will plop that image right into the SVG. Note the width and height attributes to control its size. We can also use x and y attributes to control the position, or a transform attribute to nudge and size things as well.

svg3

3) CLIPPING RASTER WITH VECTOR

Let’s combine vector and raster for a moment. We really have no choice but to make our raster graphic a rectangle. We could use alpha transparency to kind of fake other shapes, but we can be even more efficient than that.

Say we want to clip that raster graphic into a circle. That’s no problem with <clipPath> in SVG. Let’s define one:

<svg viewBox=“0 0 300 180”>

 <defs>
   <clipPath id=“circle”>
     <circle cx=“150” cy=“65” r=“50” />
   </clipPath>
 </defs>

 …
</svg>

That <circle> will not draw itself – it’s just the definition of a circle in this case, defining the clipping path. You apply it to some other element and whatever is inside of that area will be shown (the rest will be hidden).

If we apply it to our image (applying it to a wrapping element is helpful, so we can nudge things around independent of the clipping), we get what we want:

svg4

4) SETTING TYPE IN SVG

As there is a slightly different element for images within SVG, so too is there a slightly different element for text.

In HTML, we have lots of them: <h2>, <p>, <li>, <dd>, you name it. In SVG there is basically one: <text>.

You can set where you want it to be placed with x and y coordinates, alongside expected attributes like font-family and font-size. In our example, we’re going to center the type by positioning it at x=”50%” and using text-anchor=”middle”.

<svg viewBox=“0 0 300 180”>
 …

 <text x=“50%” y=“140” text-anchor=“middle” font-size=“26” font-family=“‘flood-std’, sans-serif” fill=“white”>
   Wonder Woman
 </text>

 …
</svg>

See the ‘flood-std’ font family there? Not a normal web-safe font, right? Remember this is just regular ol’ web type like we use in HTML here. We can use web fonts! I’m loading up the font Flood, via Typekit, just to demonstrate that fact.

I’ll add a little bit more type, also centered, but a different size, color, and with letter-spacing:

svg5

5) GRADIENTS

Here’s a tiny little bonus: SVG can define gradients. Such as this simple transparent -> white -> transparent one:

<svg viewBox=“0 0 300 180”>

 <defs>
   …

   <linearGradient id=“grad” x1=“0%” y1=“0%” x2=“100%” y2=“0%”>
     <stop offset=“0%” stop-color=‘white’ stop-opacity=“0” />
     <stop offset=“50%” stop-color=‘white’ stop-opacity=“0.33” />
     <stop offset=“100%” stop-color=‘white’ stop-opacity=“0” />
   </linearGradient>
 </defs>

</svg>

We’ll use that to fill a line between the text, just for funzies:

svg6wgradient

6) LIGHT ANIMATION

Some of the stuff we’ve done so far, we could have done in CSS. For example, we could set the font-family for the text in CSS like:

text {
 font-family: ‘flood-std’, sans-serif;
}

That would be more efficient than setting it as an attribute on every text element, should there be many. The lesson here, though, is that CSS applies to SVG as well. Cool, yeah? Including stuff like animation.

How about we fiddle with those rings for a hover effect?

svg:hover > circle {
 transition: 0.3s transform, 0.2s stroke;
 transform-origin: center center;
 stroke: red;
}
svg:hover > circle:nth-of-type(2) {
 transform: scale(0.89);
}
svg:hover > circle:nth-of-type(3) {
 transform: scale(0.75);
}

Right on:

animated-svg

CSS certainly isn’t the only way to animate SVG, though – there are three ways. If you’re doing anything even slightly complex, you won’t regret checking out Greensock.

WHY? SCALING.

Oh, right. Why the heck are we doing this in SVG instead of HTML? Well, remember all those vectors in there. SVG is so efficient at drawing that stuff in a way that will result in both high quality and a low file size.

We decided we wanted raster graphics in there, and raster is raster, so that’ll be about the same regardless of where we use it.

You might argue we have less control over type in SVG and less semantics. True in some sense, not true in others. We have some really cool type control possibilities in SVG, like setting type on a path.

But the most important thing? Scalability! Everything scales nicely according to our aspect ratio on our SVG stage:

scaling-svg

FINAL DEMO

It’s here.

FUTURE STUFF

It’s quite unclear what SVG 2 is and if it will come to pass. But there is a spec that defines that even more HTML content can be embedded into SVG. Namely: video, audio, iframe, and canvas. After this example, I think we can see why that could be cool. SVG truly is a cross-medium format!

Comments

  • Great article.

    I would just suggest this piece of CSS for a better behavior when leaving hover:

    svg > circle {
    transition: 0.3s transform, 0.2s stroke;
    transform-origin: 50% 50%;
    }

    svg:hover > circle {
    transition: 0.3s transform, 0.2s stroke;
    stroke: red;
    }

    • Edwin

      You can remove the transition in svg:hover > circle {}

  • its like flash never happened…

  • jayfreestone

    Masking a bitmap using SVG is very cool, and has really good support. Peter Hrynkow detailed how to use it to fake transparency on a JPG: http://peterhrynkow.com/how-to-compress-a-png-like-a-jpeg/

    The biggest problem is the lack of srcset support, so it’s kind of one step forward two steps back, which I try and hack around here: https://www.jayfreestone.com/journal/masking-bitmaps-with-svg/

  • Chris Weed

    Thank you for the article, it wasn’t much more than I already had exposure to BUT it did trigger an ah-ha moment. I’m currently using canvas to produce images for a board game I’m working on. After reading this I’m tempted to try and build the images with SVG instead, it would produce more scalable images and I could still use some raster stuff.
    Good work

Related Articles