Why SVGs will save us

SVG or Scalable Vector Graphics is a format capable of many great things: from building blazing-fast sites, to enabling a better user experience. I like to think of SVG as a party where JavaScript is the event coordinator (“event,” get it?). You’ll soon get a “fill” of what I’m talking about. Okay, enough dad jokes, and onto the party!

What is SVG?

Scalable Vector Graphics (SVG) is an XML-based image format for two-dimensional graphics with support for interactivity and animation.

Source: Icons8

On the left-hand side, we have a crisp and clear SVG image, while on the right-hand side, we have a slightly blurred PNG image.

Although we could add more data to the PNG to make it crisp, we’d be adding more data, which affects performance.

We refer to rasters like PNGs, JPEGs, etc., as bitmaps, which plot blocks or pieces on a map. A bitmap is essentially a representation in which each item corresponds to one or more bits of information.

Here’s a crude example of bitmap-depiction of the letter “A”:

As opposed to bitmaps, vectors like SVGs are made with coordinate points. If you’ve played Battleship as a kid, it’s the same concept. For example, “A2 B3” and so forth.

And, here’s an example of vector depiction over bitmap-depiction of the letter “A”:

The DOM Versus the SVG DOM

There are a couple of differences between the DOM and the SVG DOM.

For the regular DOM that we’re used to seeing across the Web, we use background and border-color as follows:

For SVG graphics, we tend to use fill and stroke as follows:

Sketch comes in handy when dealing with vectors since you can easily copy both the CSS attributes and the SVG code:

People usually shy away from SVGs because they want to avoid dealing with a complicated-looking DOM that visually makes no sense.

As we saw above, the shape produces the following SVG code:

<?xml version="1.0" encoding="UTF-8"?>
<svg width="450px" height="450px" viewBox="0 0 450 450" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 61.2 (89653) - https://sketch.com -->
<title>Group</title>
<desc>Created with Sketch.</desc>
<g id="Page-2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Artboard-Copy-4" transform="translate(-148.000000, -397.000000)" fill="#44D7B6" stroke="#0091FF" stroke-width="14">
<g id="Group" transform="translate(162.000000, 411.000000)">
<circle id="Oval" cx="211" cy="211" r="218"></circle>
</g>
</g>
</g>
</svg>

Trust me. I too was intimidated at first, but I slowly learned that it’s not as scary as I might think.

Let’s attempt to analyze a piece of SVG code that highlights many of its useful properties. For example, this code

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 250">
<g stroke-width="2" fill="transparent">
<rect id="Rectangle" stroke="#2A0AB4" x="5" y="0" width="30" height="30"></rect>
<rect id="Rectangle" stroke="#9939E2" x="80" y="0" width="30" height="30" rx="10"></rect>
<circle id="Oval" stroke="#6DD400" cx="20" cy="65" r="20"></circle>
<ellipse id="Oval" stroke="#0AA916" cx="95" cy="65" rx="20" ry="5"></ellipse>
<polygon id="Path" stroke="#0091FF" points="20 100 25 115 40 115 30 125 35 140 20 130 5 140 10 125 0 115 15 115"></polygon>
<path d="M60,120.5 C73.3333333,103.833333 83.3333333,103.833333 90,120.5 C96.6666667,137.166667 110,137.166667 130,120.5" id="Path" stroke="#44D7B6"></path>
</g>
</svg>

produces the following SVG:

We see this <g> tag, which is similar to a <div> . It stands for “group” and its primary goal is to group objects. In the above example, I’ve used inline styling, but you can apply styles and classes by referencing your selectors in CSS.

As you can see, anything I apply to a group will automatically apply to its children; this is similar to children inheriting attributes from their parents in HTML/CSS.

The fascinating thing is that we were able to create all these graphics using a tiny amount of code, which is not even a byte in filesize!

For all of the shapes we’ve created, we’re simply finding the coordinates, most of which are X and Y coordinates, in the DOM. For example, if we look at this element,

<rect id="Rectangle" stroke="#2A0AB4" x="5" y="0" width="30" height="30"></rect>

the code is placing it within the coordinate system (0 pixels from the top and 5 pixels from the left).

Taking the example of the circle,

<circle id="Oval" stroke="#6DD400" cx="20" cy="65" r="20"></circle>

cx and cy find the center point and the code plots a circle with a radius (indicated by r ) of 20.

So far, we’ve looked at simple shapes, but SVG supports curved commands that allow you to do all sorts of things.

The above shape is a complex Bézier curve along with its many control points.

Bézier Curves

Bézier curves are pretty cool. These curves are related to the Bernstein polynomial and named after Pierre Bézier . Pierre Bézier used this in the 60s to design curves for the bodywork of Renault cars.

He found a way of succinctly describing curves mathematically. This had interesting implications since curves could be shared with others, programmed into machines to match those created by designers, and much more.

Let me give you a high-level overview of Bézier curves.

I’ll illustrate the concept using the simplest Bézier curves, which are quadratic curves .

Quadratic Bézier curves have three control points. The first point is where the curve begins, the second point is to control the curve itself, and the third point is where the curve ends.

Vector-based graphics software today is based on Cubic-Bézier splines. These are curves that have two extra points called control handles, which are positioned away from the curve and control how much it bends.

Think about these control points as a magnet that’s bending a wire towards it. As a result, to change the curve’s shape, you’d drag the control handle instead of directly dragging the curve.

Demofox.org has a great demo that lets you click and drag control points to change the curve. Below is how a cubic Bézier changes when you drag its control points in different directions:

Source: Demofox.org

Paths

A path is a chain of lines and curves that go from one endpoint to the other. When I think about SVGs, I think of drawing on a graph paper without lifting the pencil. Put the pen down, drag it around, and lift it up. Simple.

With Figma, however, you can lift the pencil all you want thanks to its powerful vector network .

Anyway, I take a pencil and go from point (X1, Y1) to (X2, Y2) . At (X2, Y2) , I’ll get this Bézier handle, whose (X_B1, Y_B2) I can pull around to make a curve.

That’s what you’re doing when you write a piece of SVG code. You’re telling the computer about a few coordinates and it draws a curve. You have to admit, that’s pretty cool!

Many will often refer to vectors as paths since the computer draws them from one point to the other, creating a path as it traverses along. Consequently, there’s always a starting point and an endpoint; vectors have a direction to the path.

This becomes evident in Sketch once you select the End type for your open shape or path:

Below is the SVG code that Sketch was kind enough to generate for us:

<svg width="369px" height="206px" viewBox="0 0 369 206" ...>
...
<g stroke="none" stroke-width="1" fill="none" ...>
<g ...>
<path d="M499.805287,140.897465 L504.102535,148.805287 L496.194713,153.102535 L494.284,149.587 L145.168909,339.304775 C146.02402,341.400254 145.183502,343.848123 143.148624,344.953911 C140.964939,346.140564 138.232741,345.332309 137.046089,343.148624 C135.859436,340.964939 136.667691,338.232741 138.851376,337.046089 C140.88645,335.940194 143.397921,336.566919 144.690825,338.424851 L493.807,148.709 L491.897465,145.194713 L499.805287,140.897465 Z M139.328848,337.924736 C137.630426,338.847687 137.001784,340.97273 137.924736,342.671152 C138.847687,344.369574 140.97273,344.998216 142.671152,344.075264 C144.369574,343.152313 144.998216,341.02727 144.075264,339.328848 C143.152313,337.630426 141.02727,337.001784 139.328848,337.924736 Z"></path>
</g>
</g>
</svg>

If this is your first time dealing with SVGs, you might have noticed some extra jargon (in bold) within the <path> element such as the characters d , M , L , and Z , along with random numbers.

Each <path> element comprises a d attribute, which tells the renderer to move to a particular point. The M indicates a moveto , the L s indicate lineto s, and the Z indicates a closepath . These attributes instruct the renderer to start a line, draw a Bézier curve to another point, etc.

Let’s consider a crude example to understand what’s going on. Say we have the following path:

<path d="M100,100 L300,100 L200,300 Z">

Going back to our analogy of drawing on a graph paper without lifting the pencil, here’s how a computer would understand the code:

  • M ark the virtual pencil at the coordinates (X = 100, Y = 100)
  • Draw a L ine to coordinates (X = 300, Y = 100)
  • Draw a L ine to coordinates (X = 200, Y = 300)
  • Close or end ( Z ) the path by connecting back to the starting point

Vectors are extremely basic under the hood. The computer attempts to emulate our motor skills when drawing shapes.

It’s practically impossible to draw two shapes that don’t intersect without lifting the pencil. This may seem like a trivial fact but has some interesting effects, especially when you attempt to flatten shapes.

If you try to flatten shapes that don’t intersect at least once, Sketch will throw an error because that’s going against how SVGs work in the first place:

If you combine the shapes below, however, Sketch will flatten them for you:

And, here’s the resulting shape that’s flattened:

This is similar to the sequence of instructions that a pen plotter might follow as well.

Photograph by Matt Deslauriers

But, how will SVGs save us?

The Web is filled with raster graphics, especially PNGs. What surprises me is that the main culprits of PNGs seem to be icons and logos. Unless you’re utilizing raster images as a fallback for the ancient IE, I’d say that your time is up.

Now that we understand how SVG works under the hood, let’s take a look at the reasons for using SVGs.

Speed

They say “time is money.” To me, that translates to “speed is money.” You know…because physics taught us that speed is inversely proportional to time (yes, I’ve been told that I’m a huge nerd).

PNGs usually have fairly large file sizes, especially when rendered on HDPI displays. One common use case for using PNGs is transparency (i.e. a transparent background so that the image and can take the effect of others behind it). Transparency in images result in ludicrous file sizes and a slower load time since browsers take longer to render/load large files.

SVG helps with frontend optimization by:

  • Reducing the payload of HTTP requests
  • Reducing the number of HTTP requests

Each time your browser wants to render an asset, it needs to make an HTTP request to the server. The more images you have on your webpage, the more HTTP requests it needs to make, slowing down the site.

SVGs are not only smaller in size but also more flexible in that we can embed SVG code inline to our HTML, eliminating any HTTP requests. As we saw earlier, SVG is code, which empowers us to insert it within the DOM.

I, myself, made use of inline SVG for my personal website as a hero image:

And, you can also see that it doesn’t affect my site’s performance at all:

Another issue with raster images is that for responsive design, we might end up using multiple images for different screen sizes.

With SVGs, however, there’s just one piece of code to rule them all.

<svg viewBox="0 0 100 100">
    <circle cx="50" cy="50" r="20" />
</svg>

I know it’s hard to believe that the piece of code above is a graphical item, which is much less than even a byte! And, it’s directly in the HTML, which we will cover in Accessibility and SEO.

Accessibility and SEO

Another upside of SVGs is that search engines can index them! We can make SVGs accessible with just a couple of steps.

Say that you have the following SVG markup:

...<svg 
    class="logo"
    width="752"
    height="126"
    viewBox="0 0 752 126"
    fill="none"
    xmlns="http://www.w3.org/2000/svg"><g 
        fill="none" 
        fill-rule="evenodd" 
        stroke="currentColor" 
        stroke-width="1" 
        class="lines"><path class="el" d="M1.96265 123.989H25.4776V90.8846C28.8932 97.7158 36.3812 102.576 46.7593 102.576C62.9176 102.576 75.9231 90.7533 75.9231 67.107V66.056C75.9231 42.5411 62.9176 30.4552 46.8906 30.4552C36.5125 30.4552 29.4187 35.9726 25.4776 42.5411V32.2943H1.96265V123.989ZM38.4831 84.579C29.9441 84.579 24.8208 78.6674 24.8208 66.9756V65.9246C24.8208 54.3642 29.9441 48.1899 38.4831 48.1899C46.7593 48.1899 52.014 53.9701 52.014 66.056V67.107C52.014 78.4046 47.2848 84.579 38.4831 84.579Z" />...
    ...
...

Here’s how you can make this accessible for screen readers:

...<svg 
class="logo"
width="752"
height="126"
viewBox="0 0 752 126"
fill="none"
xmlns="http://www.w3.org/2000/svg"
aria-labelledby="super-cool-svg"
role="presentation"
>
<title id="super-cool-svg" lang="en">This is a super cool SVG!</title>
<g
fill="none"
fill-rule="evenodd"
stroke="currentColor"
stroke-width="1"
class="lines">
<path class="el" d="M1.96265 123.989H25.4776V90.8846C28.8932 97.7158 36.3812 102.576 46.7593 102.576C62.9176 102.576 75.9231 90.7533 75.9231 67.107V66.056C75.9231 42.5411 62.9176 30.4552 46.8906 30.4552C36.5125 30.4552 29.4187 35.9726 25.4776 42.5411V32.2943H1.96265V123.989ZM38.4831 84.579C29.9441 84.579 24.8208 78.6674 24.8208 66.9756V65.9246C24.8208 54.3642 29.9441 48.1899 38.4831 48.1899C46.7593 48.1899 52.014 53.9701 52.014 66.056V67.107C52.014 78.4046 47.2848 84.579 38.4831 84.579Z" />...
...
...

And, voilà! Do note that this is just the bare minimum that I’ve showcased. There’s a lot more to accessibility and SVGs. For example, you can also identify things by group (i.e. aria-labelledby={`group_id`} ). This is useful in case you’re dealing with graphs, bar charts, etc. to have the screen reader read out each group.

Regardless of whether your SVG content is in a standalone file or embedded into your code, search engines will index them.

Animations

We can easily apply transitions and animations to SVGs. Because SVG has a navigable DOM, the same concepts of the traditional web-based DOM apply to it. We can then attach things to different pieces of our SVG and animate it.

What’s really sweet is line animations, which make it seem like an SVG path is drawing itself. The legend, Jake Archibald pioneered the technique in 2013 and has written an interactive blog post on how to achieve the same. Codrops’s experiment is one of the best I’ve come across.

Let me try explaining this concept in a way that makes the most sense to me. Here goes…

We have an SVG shape that has a stroke. What I didn’t mention before is that strokes can be dashed. We can achieve dashed strokes via a design tool like Sketch/Figma or pure CSS.

In my article, “ 11 advanced Sketch techniques you may not know about ,” I illustrated how to create Apple Watch rings using this technique. You can use the Dash option under Borders in Sketch to achieve dashed strokes:

Alternatively, you can achieve the same feat in CSS with the following snippet:

----------
index.html
----------
<svg ...>
<path class="path" stroke="#000000" ... >
</svg>
----------
index.css
----------
.path {
stroke-dasharray: 20;
}

This gives us dashes that are 20 pixels in length:

We can also apply an offset to our stroke that changes the position of the dashes. Sketch doesn’t allow us to offset the stroke unless you use something like Keyshape or SVGator .

Here’s how to do this in CSS:

----------
index.css
----------
.path {
stroke-dasharray: 200;
animation: dash 0.8s linear;
}
@keyframes dash {
to {
stroke-dashoffset: 2000;
}
}

If the value of your dash (or stroke-dasharray ) is reasonably larger than the length of your path, it will cover the entire shape. It’s as if the entire shape weren’t dashed at all:

What Jake discovered was that increasing both the stroke-dasharray and the stroke-dashoffset to their maximum, and then slowly decreasing the stroke-dashoffset , makes the line draw itself!

In CSS, you’ll want to set the animation-fill-mode attribute to forwards so that the animation retains its final state.

----------
index.css
----------
.path {
stroke-dasharray: 2000;
stroke-dashoffset: 2000;
animation: dash 0.8s linear forwards;
}
@keyframes dash {
to {
stroke-dashoffset: 0;
}
}

Accuracy and Resolution

Let me be clear: it’s not that raster images are bad; raster and vector are both good for different things.

Of course, vectors are undoubtedly better than raster graphics in terms of resolution since vectors offer an infinite resolution. If you’re using PNGs, you’re bound by pixels and that’s so 2001…

Where SVGs really shine is when they’re used as logos, icons, and simple animations. The beauty of SVGs is that you can define a single asset without worrying about its size, color, resolution, or load time.

As a result, SVGs are good for icons, logos, illustrations, charts, animations while rasters are good for photos:

Now you know why websites charge a premium for exporting icons in vector format, along with some other useful things.

Inertia exists all around us. But, it’s important to remember that true innovation lies at the heart of embracing change for the better and taking a leap of faith. SVGs are here to stay, and they’ve already made a huge dent in the digital era.

我来评几句
登录后评论

已发表评论数()

相关站点

热门文章