Building a Simple Footer with SVG Icons
Tags: css, codenewbie, svg
Published: 2021-03-16 03:53:09

If you're looking for icons to build any app, there are plenty of libraries and resources available with great premade options, but sometimes you just need something that's custom.

Let's talk about SVGs. An SVG is a scalable vector graphic. That means that no matter its size, it maintains clean lines. A vector graphic can be resized because its shape is defined by mathematical precision. On the other hand, a raster graphic loses its integrity when it is shown larger than its original size. See below for a visual representation with the vector on the left and the raster on the right.

![Vector vs. Raster](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9tpjeqyqwukowi9s8yj0.jpg)

You're probably wondering why even bother creating an SVG if the icon is going to be small anyway? Imagine that you have created all of these icons as PNGs, which is a file type that can be created with a transparent background. If you want to change the background in the app behind the PNG, it's as easy as changing the CSS, but if you want to change the color of the icon itself, it *can't* be done without changing the original icon file and then replacing the image in the app.

Because an SVG is just built with math, it's not only scalable but it's also just code. This means that it is possible to style it with your regular CSS, so if you want to change its fill color, it can be targeted without having to change the image outside of the code.

Also note that because SVGs are just code, another benefit over using PNGs or other image file types is that no requests have to be made to find the images to retrieve them from wherever they are located, resulting in a lighter app.

Sounds pretty neat, right? Let's start building that footer.

For the sake of brevity, because SVGs tend to have a fair amount of code, I'll only show three icons, but you can use as many as you would like. It's tempting to plug in the icons like below, and this will absolutely render them to the page, but those paths are pretty long. Imagine adding links and having to sift through this big chunk of code if you needed to make a change.

```js
<footer>
  <div id='footer-wrap'>
    <svg xmlns='http://www.w3.org/2000/svg' className='footer-icon'>
      <path d='M21.63,29A11,11,0,0,1,19,28.66l-2.46,6.53a18.16,18.16,0,0,0,5.08.81,17.78,17.78,0,0,0,8-1.93l-3.59-6A10.83,10.83,0,0,1,21.63,29Z'/>
      <path d='M39.57,19.11h-7a10.86,10.86,0,0,1-3.88,7.28l3.64,6.08A18,18,0,0,0,39.57,19.11Z'/>
      <path d='M10.61,18a11,11,0,0,1,3.33-7.8L9.65,4.61a17.93,17.93,0,0,0,4,29.49l2.5-6.6A11,11,0,0,1,10.61,18Z'/>
      <path d='M21.63,7a11,11,0,0,1,10.76,9h7.12A18.06,18.06,0,0,0,21.63,0a17.1,17.1,0,0,0-1.88.19L21.08,7C21.26,7,21.45,7,21.63,7Z'/>
      <path d='M18.05,7.68,16.7.73a17.66,17.66,0,0,0-4.58,2l4.31,5.61A12.07,12.07,0,0,1,18.05,7.68Z'/>
    </svg>

    <svg xmlns='http://www.w3.org/2000/svg' className='footer-icon'>
      <path d='M38.07,32.51H7.51l4.22-15.86.19.7a1.51,1.51,0,0,0,.86,1,1.44,1.44,0,0,0,.62.13,1.49,1.49,0,0,0,.69-.16l2.12-1.07,1.28,5.38a1.58,1.58,0,0,0,.89,1.06L23.83,26l7.6,4.65a1.51,1.51,0,0,0,.8.22h5.84a1.72,1.72,0,0,0,1.53-1.74,1.54,1.54,0,0,0-1.53-1.54l-5.25.07-7.49-4.57L20.48,21l-1.59-6.67a1.5,1.5,0,0,0-.85-1,1.47,1.47,0,0,0-.65-.15,1.59,1.59,0,0,0-.69.17l-2.17,1.09L13.19,9.5a1.53,1.53,0,0,0-3,0L7.09,21.29V1.53A1.53,1.53,0,0,0,5.56,0H5.13A1.54,1.54,0,0,0,3.6,1.53V34.47A1.54,1.54,0,0,0,5.13,36H38.07a1.54,1.54,0,0,0,1.53-1.53V34A1.53,1.53,0,0,0,38.07,32.51Z'/>
    </svg>

    <svg xmlns='http://www.w3.org/2000/svg' className='footer-icon'>
      <path d="M14.29,12.43a3.37,3.37,0,0,0,.35.89l.95,1.48c1.08,1.7,2.2,3.45,3.45,5.08A3.56,3.56,0,0,0,21.59,21l.35,0A3,3,0,0,0,24,18.84,3.44,3.44,0,0,0,22.82,16c-1.61-1.21-3.35-2.28-5-3.32l-1.44-.9a4.5,4.5,0,0,0-1-.41l-1.69-.65.33.93C14.15,12,14.22,12.22,14.29,12.43Z"/>
      <path d="M39.46,15.25C38.62,7.65,31.16.54,23.51,0h-.4A3.45,3.45,0,0,0,19.4,3.61c0,.9,0,1.8,0,2.7V7.65a2.91,2.91,0,0,0,.68,2.15,2.19,2.19,0,0,0,1.65.57h0c2.22-.06,2.2-2.15,2.19-2.84V4.91l.55.08a7.8,7.8,0,0,1,1.59.34A12.9,12.9,0,0,1,34.9,16.16c.77,5.28-1.29,9.71-6,12.8a13.17,13.17,0,0,1-7.35,2.21A12.78,12.78,0,0,1,12.1,27.1C7.27,21.81,7,15.25,11.29,9.55c.4-.53.77-1.09,1.13-1.61l.6-.89-.12-.24c-.47-.93-1.24-2.17-2.42-2.17A3,3,0,0,0,8.4,5.86,17.84,17.84,0,0,0,3.72,20,18,18,0,0,0,11.47,32.6,17.52,17.52,0,0,0,21.55,36,17.78,17.78,0,0,0,31.09,33C37.41,29.05,40.3,22.9,39.46,15.25Z"/>
    </svg>
  </div>
</footer>
```

Let's make it easier to maintain. Ideally, it would be nice to find some separation from those long paths. Luckily, there's an element for that. According to [MDN](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/use), "the `<use>` element takes nodes from within the SVG document, and duplicates them somewhere else." Let's push the paths down, placing each one in a `<symbol>` tag and giving them each an individual `#id`. Then, we'll use the `<use>` tag at the top and refer back to the id to reference the symbol.

```js
<footer>
  <div className='footer-wrap'>

    <svg className='footer-icon'>
      <use href='#chart'></use>
    </svg>

    <svg className='footer-icon'>
      <use href='#graph'></use>
    </svg>

    <svg className='footer-icon'>
      <use href='#timer'></use>
    </svg>
  </div>

  <svg xmlns='http://www.w3.org/2000/svg' id='hide-bottom'>
    <symbol id='chart' viewBox='0 0 43.2 36'>
      <path d='M21.63,29A11,11,0,0,1,19,28.66l-2.46,6.53a18.16,18.16,0,0,0,5.08.81,17.78,17.78,0,0,0,8-1.93l-3.59-6A10.83,10.83,0,0,1,21.63,29Z'/>
      <path d='M39.57,19.11h-7a10.86,10.86,0,0,1-3.88,7.28l3.64,6.08A18,18,0,0,0,39.57,19.11Z'/>
      <path d='M10.61,18a11,11,0,0,1,3.33-7.8L9.65,4.61a17.93,17.93,0,0,0,4,29.49l2.5-6.6A11,11,0,0,1,10.61,18Z'/>
      <path d='M21.63,7a11,11,0,0,1,10.76,9h7.12A18.06,18.06,0,0,0,21.63,0a17.1,17.1,0,0,0-1.88.19L21.08,7C21.26,7,21.45,7,21.63,7Z'/>
      <path d='M18.05,7.68,16.7.73a17.66,17.66,0,0,0-4.58,2l4.31,5.61A12.07,12.07,0,0,1,18.05,7.68Z'/>
    </symbol>

    <symbol id='graph' viewBox='0 0 43.2 36'>
      <path d='M38.07,32.51H7.51l4.22-15.86.19.7a1.51,1.51,0,0,0,.86,1,1.44,1.44,0,0,0,.62.13,1.49,1.49,0,0,0,.69-.16l2.12-1.07,1.28,5.38a1.58,1.58,0,0,0,.89,1.06L23.83,26l7.6,4.65a1.51,1.51,0,0,0,.8.22h5.84a1.72,1.72,0,0,0,1.53-1.74,1.54,1.54,0,0,0-1.53-1.54l-5.25.07-7.49-4.57L20.48,21l-1.59-6.67a1.5,1.5,0,0,0-.85-1,1.47,1.47,0,0,0-.65-.15,1.59,1.59,0,0,0-.69.17l-2.17,1.09L13.19,9.5a1.53,1.53,0,0,0-3,0L7.09,21.29V1.53A1.53,1.53,0,0,0,5.56,0H5.13A1.54,1.54,0,0,0,3.6,1.53V34.47A1.54,1.54,0,0,0,5.13,36H38.07a1.54,1.54,0,0,0,1.53-1.53V34A1.53,1.53,0,0,0,38.07,32.51Z'/>
    </symbol>

    <symbol id='timer' viewBox='0 0 43.2 36'>
      <path d="M14.29,12.43a3.37,3.37,0,0,0,.35.89l.95,1.48c1.08,1.7,2.2,3.45,3.45,5.08A3.56,3.56,0,0,0,21.59,21l.35,0A3,3,0,0,0,24,18.84,3.44,3.44,0,0,0,22.82,16c-1.61-1.21-3.35-2.28-5-3.32l-1.44-.9a4.5,4.5,0,0,0-1-.41l-1.69-.65.33.93C14.15,12,14.22,12.22,14.29,12.43Z"/>
      <path d="M39.46,15.25C38.62,7.65,31.16.54,23.51,0h-.4A3.45,3.45,0,0,0,19.4,3.61c0,.9,0,1.8,0,2.7V7.65a2.91,2.91,0,0,0,.68,2.15,2.19,2.19,0,0,0,1.65.57h0c2.22-.06,2.2-2.15,2.19-2.84V4.91l.55.08a7.8,7.8,0,0,1,1.59.34A12.9,12.9,0,0,1,34.9,16.16c.77,5.28-1.29,9.71-6,12.8a13.17,13.17,0,0,1-7.35,2.21A12.78,12.78,0,0,1,12.1,27.1C7.27,21.81,7,15.25,11.29,9.55c.4-.53.77-1.09,1.13-1.61l.6-.89-.12-.24c-.47-.93-1.24-2.17-2.42-2.17A3,3,0,0,0,8.4,5.86,17.84,17.84,0,0,0,3.72,20,18,18,0,0,0,11.47,32.6,17.52,17.52,0,0,0,21.55,36,17.78,17.78,0,0,0,31.09,33C37.41,29.05,40.3,22.9,39.46,15.25Z"/>
    </symbol>
  </svg>
</footer>
```

Notice also that the className has now moved to the `<svg>` tags that wrap the `<use>` elements. From there, all you have to do is add your links and style the footer however you like.

A few extra tidbits about these SVGs. If you notice, each one is made up of paths. Just like with other html elements, you can give the paths a class or an id and style them individually as well. To illustrate this, let's go a little crazy with the path colors.

```js
<symbol id='chart' viewBox='0 0 43.2 36'>
  <path className='path-pink' d='M21.63,29A11,11,0,0,1,19,28.66l-2.46,6.53a18.16,18.16,0,0,0,5.08.81,17.78,17.78,0,0,0,8-1.93l-3.59-6A10.83,10.83,0,0,1,21.63,29Z'/>
  <path d='M39.57,19.11h-7a10.86,10.86,0,0,1-3.88,7.28l3.64,6.08A18,18,0,0,0,39.57,19.11Z'/>
  <path className='path-orange' d='M10.61,18a11,11,0,0,1,3.33-7.8L9.65,4.61a17.93,17.93,0,0,0,4,29.49l2.5-6.6A11,11,0,0,1,10.61,18Z'/>
  <path className='path-purple' d='M21.63,7a11,11,0,0,1,10.76,9h7.12A18.06,18.06,0,0,0,21.63,0a17.1,17.1,0,0,0-1.88.19L21.08,7C21.26,7,21.45,7,21.63,7Z'/>
  <path d='M18.05,7.68,16.7.73a17.66,17.66,0,0,0-4.58,2l4.31,5.61A12.07,12.07,0,0,1,18.05,7.68Z'/>
</symbol>
```

After styling the code above to correspond with the colors matching their classes, the output will look like the image below. The changes will only affect the individual paths on the specified icon.

![Colorful Icon](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jyl95ekn6wi7j0hz0r86.jpg)

And there you have it - all you need to create a footer of scaleable and easily editable and maintainable (and probably many other -ables) icons!