Breaking down SVGs
Tags: html, css, beginners
Published: 2020-08-04 21:48:50

In the midst of a project deadline bubbling, it can be easy to take whatever assets were handed to you to then "plug and chug" them in the typical patterns that you were taught would make the feature work. In this way, you might look past why something is the way it is or why we might be treating it a particular way. 

I certainly did this with SVGs. I knew they were favorited by designers because their independence from the raster-based pixel world allowed them to scale well without loss of quality. But it was simple for me to export an SVG from a mockup and place it into my React app out of habit, without considering what was really happening in that exported file.

So, I thought I would take a general glance at the inner workings of an SVG and maybe even try to make one myself.

### First, some background info
**What are SVGs?**
Scalable graphic vectors (SVGs) are a *text-based* way of describing images. The two major types of digital graphics you might come across are raster and vector. When you think raster, think a fixed set of pixels. When you think vector, think of customizable equations that can create some shape. It's like drawing with math 😍  

**What's the language SVGs speak in, how do we define one?**
We use Extensible Markup Language (XML), which is great because XML was designed to be both machine and human readable. It's done on a text file that can be created and edited with any software. Since they are text-based, this also makes them easier to localize.

> 💭 *SVG is to graphics what HTML is to text* 

### Creating One
**Shapes**
There are several predefined elements representing shapes that we can use in XML, like:
1. `line`
2. `polygon`
3. `rect`
4. `circle`
...[and more](https://www.w3schools.com/graphics/svg_rect.asp)
They each come with unique attributes (as well as many shared) that allow you to customize the shape.

For example, setting the `cx` and `cy` attributes on a `circle` element allows you to define the coordinates for the center of the circle.

**Good to Know**
* Everything is encapsulated within `<svg></svg>` tags
* You can define some aspects on the `svg` tag itself, for example using attributes like `width="x"` and `height="y"`

**Let's see one!**
```
<svg width="400px" height="400px">
    <circle cx="100" cy="100" r="80" stroke="blue" stroke-width="6" fill="orange" />
    {/* put whatever message you want here as alt text */}
    Your browser is not able to render this SVG.
</svg>
```

That will render into:
![Example 1 Circle](https://dev-to-uploads.s3.amazonaws.com/i/5sfxvf4tvvwph6yghg0j.png)

It's slightly amusing that I'm having to show you what an SVG looks like by uploading it as a PNG but alas, SVGs are an unsupported type on Dev.to as of now.

What's happening in that XML? A few things:
* `r` - sets the radius of the circle
* `stroke` and `stroke-width` - similar to setting `border` in CSS
* `fill` - similar to setting `background-color` in CSS
* `cx` and `cy` - you can't see how these are affecting the SVG in the image I've provided, but I mentioned earlier they define the x/y coordinates for the center of the circle, with the default being 0, 0. I recommend copy/pasting those lines into [Polycursor](http://polycursor.com/SVGEditor.aspx) and playing around with the `cx` and `cy` attributes to see how they actually affect the SVG. 

Side note: you can also write the styles all in a `style` attribute like this: `style="stroke:blue;stroke-width:6;fill:orange"`, but I find that difficult to read. 

**Let's see one more, this time using the polygon tag**
```
<svg height="415" width="500">
    <polygon points="200,200 150,325 185,415" stroke="black" fill="yellow" stroke-width="4" />
    Your browser is not able to render this SVG.
</svg>
```

That will render into:
![Example 2 Polygon](https://dev-to-uploads.s3.amazonaws.com/i/xmgcizjc9j6r0c96c65v.png)

###Filters
If you want to get a little fancier, you can add different effects to your SVGs using filters. All filters are defined within the `<filter>` tags and these tags must be defined within a `<defs>` tag

🤔 Defs? It means definitions of special elements. Anything set up within `<defs>` is not going to show up when the SVG renders, but it's a space for you to define anything you want to use or reuse within the SVG itself. You can add as many elements as you want into this space and then organize them into the image you desire. But in order to do this, you have to label the elements you want to use with a unique ID, so that the id can used as a reference point outside of `<defs>`. Much like in the relationship between HTML and CSS selectors.

What could the contents of a `<def>` look like?
```
<svg height="315" width="315">
  <defs>	
    <filter id="filter-one" x="0" y="0">
      <feGaussianBlur in="SourceGraphic" stdDeviation="20" />
    </filter>
  </defs>
  <rect width="100" height="100" fill="green" filter="url(#filter-one)" />
</svg>
```

That will render into:
![Example 3 Filters](https://dev-to-uploads.s3.amazonaws.com/i/n16ijkqvrvzpzg4ke8ry.png)

What's happening here:
* The `id="filter-one"` is setting a unique id for the filter tag
* Within the filter tag, I can set the kind of filter I want. I wanted to create a blur effect, and you can do this by using `feGaussianBlur`
* `in=SourceGraphic` says to apply the blur effect to the whole element
* `stdDeviation` - the amount of blur, or can be thought of as the spread from the center point
* Finally, I am passing to `<rect>` the unique id of the filter I want applied to it, which I can do with `filter="url(#filter-one)"`

###Working with SVGs

It's worth mentioning you'll rarely find yourself in the position where you need to create an SVG from scratch. 

It's more likely you'll be getting them as a file already from the designer or can extract them into a file from mockups. In that case if you're using React you can [import and use them like you would a component](https://medium.com/@rossbulat/working-with-svgs-in-react-d09d1602a219). If not, I'd recommend using them with an object, as a background image in CSS, or *hesitantly* inline in HTML.

When you're deep in the weeds of some more complex SVGs, the files can get quite complicated. You can also use an SVG editor like [Method Draw](https://editor.method.ac/), [Vectr](https://vectr.com/tmp/cx4JUl5PA/cuNtTkoXg), or [Boxy SVG](https://boxy-svg.com/app) to abstract away from the XML and experience a kind of photoshop-like environment for creating an SVG.

That being said, in the times you may have to deal with altering just a piece of an SVG or fix a broken SVG, it's good to have this basic understanding of how they form.

---
**Notes:**

1. I used [this handy tool](http://polycursor.com/SVGEditor.aspx) to create some quick SVGs for this article.
2. If you want to take your knowledge further, [check out this deep-dive on SVGs](https://css-tricks.com/lodge/svg/).
3. Shoutout to Stop Motion Artist Julie Smith Schneider for the [wonderful GIF on the cover](https://giphy.com/gifs/painting-stop-motion-100gifsproject-yvYKAcGFEnXjnpevKK).