SVG in CSS

July 1, 2022
CSS and SASS Tips and Tricks

SVG stands for Scalable Vector Graphics. They contain XML based markup for two-dimensional vector graphics, which form an image that scales correctly and clearly from large to small. The files compress very well and easily conform to the capabilities of the display.

SVG is great and there are dozens of articles and primers out there to get a good handle on how they work, including one by CSS-Tricks, a few by Mozilla, and dozens of others. I’m not gonna rehash any info that’s already present on the web, but I do want to talk about a way that I commonly use SVG that I think isn’t well-known.

I like having weird backgrounds but hate when they show up all blurry while they load or worse – don’t load at all. I also hate making network requests for an image and it really ruins a design when an image doesn’t scale right. SVG can ensure clearness and proper scaling. And when used directly in CSS, cut down on a network request.


The background-image Property

In CSS, the background-image property accepts a few arguments, including url(../path/to/image.jpeg), linear-gradient(), and any combination thereof.


Getting SVG in to CSS

Using SVG directly in CSS is possible by just passing an SVG as the url() parameter of the background-image property, as shown below.

div {
  background-image: url('data:image/svg+xml;charset=utf-8,<svg>...</svg>);
}

That….works. It’s a little ugly and not well supported. IE11 apparently has a problem, but should we really worry about that? This method is operational in most modern browsers and probably okay for development or testing or demos. But there are some problems with escaping characters that you might not want to deal with in a live environment. For example, the # character (used for colors), as well as double & single quotes, are interpreted differently depending on the browser/platform. If you’re using SASS, this might be exacerbated, depending on your version. This should be mostly okay, but there is a method that solves for these issues.


Encode All The Things!

Base64 encoding will properly encode your hashes and be more compressed, saving what are surely precious bytes. There are lots of methods to encode. PHP, JavaScript, and React all have native methods. CodeIgniter (and most PHP frameworks) has a method that expands on the native method. I’m going to provide a code sample that utilizes the terminal because that’s something I’m fairly certain most of us are going to have. I’m using Bash, but there is probably a similar feature for whatever command-line you’ve got.

I’ll start with the following SVG:

<svg id="visual" viewBox="0 0 100 100" width="100" height="100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
  <rect x="0" y="0" width="100" height="100" fill="#140021"></rect>
  <path d="M72 0L46 0L46 20L35 20L35 40L80 40L80 60L39 60L39 80L87 80L87 100L0 100L0 80L0 80L0 60L0 60L0 40L0 40L0 20L0 20L0 0L0 0Z" fill="#560090"></path>
  <path d="M38 0L10 0L10 20L30 20L30 40L44 40L44 60L50 60L50 80L37 80L37 100L0 100L0 80L0 80L0 60L0 60L0 40L0 40L0 20L0 20L0 0L0 0Z" fill="#9900ff"></path>
</svg>

Which gives us:

I have that saved as steps.svg and in my desktop folder. I’ll navigate to my desktop and start by outputting the file using echo, then I’ll pipe that to base64, which will output the result directly to the window.

cd ~/natenorthway/desktop
echo "$(<steps.svg)" | base64

Running that command provided the following:

PHN2ZyBpZD0idmlzdWFsIiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgd2lkdGg9IjEwMCIgaGVpZ2h0PSIxMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHZlcnNpb249IjEuMSI+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCIgaGVpZ2h0PSIxMDAiIGZpbGw9IiMxNDAwMjEiPjwvcmVjdD48cGF0aCBkPSJNNzIgMEw0NiAwTDQ2IDIwTDM1IDIwTDM1IDQwTDgwIDQwTDgwIDYwTDM5IDYwTDM5IDgwTDg3IDgwTDg3IDEwMEwwIDEwMEwwIDgwTDAgODBMMCA2MEwwIDYwTDAgNDBMMCA0MEwwIDIwTDAgMjBMMCAwTDAgMFoiIGZpbGw9IiM1NjAwOTAiPjwvcGF0aD48cGF0aCBkPSJNMzggMEwxMCAwTDEwIDIwTDMwIDIwTDMwIDQwTDQ0IDQwTDQ0IDYwTDUwIDYwTDUwIDgwTDM3IDgwTDM3IDEwMEwwIDEwMEwwIDgwTDAgODBMMCA2MEwwIDYwTDAgNDBMMCA0MEwwIDIwTDAgMjBMMCAwTDAgMFoiIGZpbGw9IiM5OTAwZmYiPjwvcGF0aD48L3N2Zz4K

Tying it Together

Now, all we need to do is put that in our CSS. We have to prep it with a declaration, though, to let the browser know that what’s in the argument being passed isn’t a URL, but a base64 encoded SVG.

background-image: url(data:image/svg+xml;base64,PHN2ZyBpZD0idmlzdWFsIiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgd2lkdGg9IjEwMCIgaGVpZ2h0PSIxMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHZlcnNpb249IjEuMSI+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCIgaGVpZ2h0PSIxMDAiIGZpbGw9IiMxNDAwMjEiPjwvcmVjdD48cGF0aCBkPSJNNzIgMEw0NiAwTDQ2IDIwTDM1IDIwTDM1IDQwTDgwIDQwTDgwIDYwTDM5IDYwTDM5IDgwTDg3IDgwTDg3IDEwMEwwIDEwMEwwIDgwTDAgODBMMCA2MEwwIDYwTDAgNDBMMCA0MEwwIDIwTDAgMjBMMCAwTDAgMFoiIGZpbGw9IiM1NjAwOTAiPjwvcGF0aD48cGF0aCBkPSJNMzggMEwxMCAwTDEwIDIwTDMwIDIwTDMwIDQwTDQ0IDQwTDQ0IDYwTDUwIDYwTDUwIDgwTDM3IDgwTDM3IDEwMEwwIDEwMEwwIDgwTDAgODBMMCA2MEwwIDYwTDAgNDBMMCA0MEwwIDIwTDAgMjBMMCAwTDAgMFoiIGZpbGw9IiM5OTAwZmYiPjwvcGF0aD48L3N2Zz4K);

That’s definitely not readable or as pretty to look at, but, the results are astounding. It’s supported nearly everywhere and it’s kinda like, the right way to do it. Here’s a CodePen with the results:

See the Pen SVG in CSS by Nate Northway (@the_Northway) on CodePen.


Applications

I’m actually using this on my new website for background images, as well as on some client projects for the same purpose. I’m using this at work, too, in our icons (and for some custom lazy-loading of iframes). I think those are the most common use cases, but if you know of something, drop a comment!


Wrapping Up

If you don’t like using the CLI, don’t use React, and maybe need to use something that’s not PHP or JavaScript, there are some tools to help you. This SVG Encoder spits out everything you might need for SVG in CSS. Scott Jehl also built a cool tool that also provides fallbacks, though it is a grunt.js task, so a little bit of a niche interest is needed there.


Here are some cool links that helped me understand and talk about this:
CSS-Tricks article on SVG
Mozilla Article on SVG
Mozilla Article on SVG + CSS
David Bushell article on…pretty much the same thing
Bash info on base64 function
This SVG Generator was used to create the SVG.

No Comments...yet

Leave a Reply

Your email address will not be published. Required fields are marked *

Previous Post

Does WordPress Power 40% of Websites?

From June 30, 2022

I won’t lie, I rallied against WordPress for a long time, but the claim of powering almost half the web wasn’t the reason.

Read This Article
Next Post

Cool CSS Selectors

From July 4, 2022

One of the spoils of using Sass is the liberal use of nested selectors, allowing a high level of specificity. CSS is closing that gap, though!

Read This Article