SVGs in our development process

Steven Rathbauer
Building Creative Market
7 min readMay 1, 2018
Illustration by Daniella Valerio

Here at Creative Market, we’re always looking to refine processes, simplify coding and reduce technical debt. From operations to product, we strive to get it right. One of the areas in which our process needed to be updated was our developer build, specifically, our SVG development process.

Creative Market has been around since 2012 so it is only fair that best practices at the time are now considered clunky and outdated. Until recently we had been using a combination of mostly JPGs and PNGs when it came to images and icons on our site. There are some obvious pitfalls with using pixel based images. Scalability is the biggest one, because nowadays you need at least two versions of any image to support high density displays. This in and of itself creates technical overhead to develop solutions that dynamically serve the correct image for the current users display. In addition to the scalability issues, we also have to deal with file size and render blocking fetching of these images. Sure, these can be cached so future page loads are faster but that doesn’t fix initial loading delays. What should we do?!

We turned to SVGs

It was clear that using SVGs was the best decision moving forward.

  • They are supported in pretty much every modern browser.
  • They can be extremely lightweight with minimal file sizes.
  • They can be processed and minified to reduce the size even further.
  • Best of all, they are scalable! It is right in the name, Scalable Vector Graphics.

Now we just had to agree on the best method to serve these new image types. We obviously could just go about delivering the images the same way we had with JPGs and PNGs, but that’s no fun. We need a better way to use and deliver these files!

The Proof Of Concept

We spent some time developing a POC for this scenario where pretty much everything was static. Clearly if we decided on this, we would need to make a full featured task and conversion process to do all of the heavy lifting for us. In the mean time, we needed to see that it would work!

The idea was to use the CSS property, content, to delivery SVGs on a given elements “before” or “after” pseudo-element. After many iterations and some trial and error we were able to deliver a solution that is cross-browser compatible and just plain awesome!

Here is an example of how we can inject an inline SVG into the content property using the url function.

Inline SVG Example (Extra markup included for demo purposes)

It may seem like a lot of work for such a small image, and it was. However, the gulp task and SCSS mixins we wrote to automate most of this work makes the initial R&D totally worth it!

Converting SVGs into something SCSS can use

We clearly want to be able to use this for more than just simple icons. We want to be able to throw any SVG file we receive from our design team into a folder and automatically have that file be processed, optimized and output into something that our SCSS files know what to do with. This is where a custom gulp task and SCSS mixin came into play.

We spent a fair amount of time writing a robust and extensive gulp task to do most of the conversion heavy lifting. The task is incorporated into a few npm scripts we have setup so that it will run whether we are building for a production deploy or running a local dev server.

The gulp task runs through a slew of synchronous pipes to process the SVG files the way we need them.

  • We use gulp.src to get all SVG files that we want to run through this process from a designated directory.
  • Then we store the filenames of the files, after performing some modifications, into a local map variable so that we can check for duplicates and increment the outputted variable name if duplicates do exist. Files like some-name.svg and some.name.svg end up being converted into the same name so while they may not be the same file, we do not want our outputted variables to be the same.
  • After that we send all of the files to be processed through a gulp plugin called gulp-imagemin using its own external plugin called svgo. This plugin for the most part has its default options set up well but we have some specific needs, so we make sure to set those overrides during the call of that function.
  • Now that the files have been optimized and minified per our settings we send the files through an additional custom function we wrote that performs some magic on the contents of the SVG files. We perform some very specific replacements in the code with additionally specific keywords that we look for later on when the SCSS variable maps are used in our custom mixin. This allows us to inject in custom colors instead of using whatever color was already defined in the SVG file.
  • Finally we concatenate all files in their new, optimized, minified and formatted syntax into a singular SCSS component file that is later imported into our SCSS process.

When this process has completed we are left with a singular SCSS file, containing SCSS variables which are declared as SCSS maps containing details about the SVG. This includes the SVG content itself, any default width and height value that was present in the file, how many colors appeared in the SVG as well as the default values for those colors. Now that we have all of this information at our fingertips what can we do with this?

Using the new generated SCSS variables

We have a brand spanking new generated SCSS component file, so we imported it within our SCSS global file in order for our mixins and functions to be aware of these new SCSS variables.

Then we developed an equally robust SCSS mixin that is responsible for using a given SCSS variable map and turning that into automatically generated, dynamic and compilable SCSS.

The mixin takes a couple of arguments, only one of which is required for it to run properly.

  • SVG variable map name: required
  • List of colors
  • List of stop-colors (this is most common in SVGs with gradients)
  • Psuedo-element type
  • Dimensions included or not

In the mixin itself we process the SCSS variable map by iterating through a few conditions, loops and additional SCSS functions which are responsible for some extra string replacement.

Within these steps we perform the necessary actions to swap out the specific keywords that we injected earlier in the gulp tasks with either new colors we pass into the mixin or the default colors that existed in the original SVG file. Once the final content has been generated after running through the mixin it is output to a new content CSS property within the CSS selector where you included the mixin.

Why this makes us (frontend dev’s) excited

All of this work, and for what??

Well now that we have all of this groundwork setup we can add an inline SVG as easy as the following 1 line, yes one singular line of code!

And if we want to define some of those optional arguments we can do it, without even needing to define them in order or include all of them if we only want to define the first and last argument!!

If you notice in that last example we pass our arguments using a map with the spread operator after it. This tells the mixin to accept our arguments and use the map keys to decide which optional arguments will be overwritten by our passed values. By doing this we can pass the 1st, 2nd and 5th argument and not have to worry about the other two in the middle, essentially telling the mixin: “just use those default values you know about already, we’ll provide the rest”.

TL;DR

We needed a solution for big, clunky un-scalable pixel based images on our site. We knew we wanted to move towards SVGs but we needed a way to do that where development wasn’t slowed down and application performance would be improved.

We developed a fully dynamic and automated gulp task coupled with a SCSS mixin to then have the ability to include an SVG on demand while we write our SCSS files.

Not only that but we can either use the SVG as it was originally designed with the predetermined colors and dimensions, or pass our own new properties to the mixin and generate a new SVG based off of the same single file.

It was a plethora of work, headaches, some tears and definitely some trial and error. Now that it is all said and done we have a completely custom process to use SVGs in our development process and it works seamlessly across multiple project environments!

END OF LINE.

We’re always looking for amazing people to join the Creative Market team. We value our culture as much as we value our mission, so if helping creators turn passion into opportunity sounds like something you’d love to do with a group of folks who feel the same way, then check out our job openings and apply today!

--

--