Sunday, October 2, 2022
HomeProgrammingHow I Made an Icon System Out of CSS Customized Properties |...

How I Made an Icon System Out of CSS Customized Properties | CSS-Tips

SVG is the very best format for icons on a web site, there may be little question about that. It lets you have sharp icons regardless of the display screen pixel density, you may change the types of the SVG on hover and you’ll even animate the icons with CSS or JavaScript.

There are lots of methods to incorporate an SVG on a web page and every approach has its personal benefits and downsides. For the final couple of years, I’ve been utilizing a Sass operate to import instantly my icons in my CSS and keep away from having to mess up my HTML markup.

I’ve a Sass listing with all of the supply codes of my icons. Every icon is then encoded into a knowledge URI with a Sass operate and saved in a customized property on the basis of the web page.


What I’ve for you here’s a Sass operate that creates a SVG icon library instantly in your CSS.

The SVG supply code is compiled with the Sass operate that encodes them in information URI after which shops the icons in CSS customized properties. You may then use any icon wherever in your CSS like as if it was an exterior picture.

That is an instance pulled straight from the code of my private web site:

.c-filters__summary h2:after {
  content material: var(--svg-down-arrow);
  place: relative;
  high: 2px;
  margin-left: auto;
  animation: closeSummary .25s ease-out;


Sass construction

/* All of the icons supply codes */
$svg-icons: (
  burger: '<svg xmlns="" viewBox="0...'

/* Sass operate to encode the icons */
@operate svg($identify) {
  @return url('information:picture/svg+xml, #{$encodedSVG} ');

/* Retailer every icon right into a customized property */
:root {
  @every $identify, $code in $svg-icons {
    --svg-#{$identify}: #{svg($identify)};

/* Append a burger icon in my button */
.menu::after {
  content material: var(--svg-burger);

This method has each execs and cons, so please take them into consideration earlier than implementing this resolution in your venture:


  • There aren’t any HTTP requests for the SVG recordsdata.
  • All the icons are saved in a single place.
  • If you could replace an icon, you don’t should go over every HTML templates file.
  • The icons are cached alongside along with your CSS.
  • You may manually edit the supply code of the icons.
  • It doesn’t pollute your HTML by including further markup.
  • You may nonetheless change the colour or some side of the icon with CSS.


  • You can’t animate or replace a particular a part of the SVG with CSS.
  • The extra icons you could have, the heavier your CSS compiled file might be.

I largely use this method for icons slightly than logos or illustrations. An encoded SVG is at all times going to be heavier than its unique file, so I nonetheless load my advanced SVG with an exterior file both with an <img> tag or in my CSS with url(path/to/file.svg).

Encoding SVG into information URI

Encoding your SVG as information URIs isn’t new. The truth is Chris Coyier wrote a publish about it over 10 years in the past to elucidate the best way to use this method and why you need to (or mustn’t) use it.

There are two methods to make use of an SVG in your CSS with information URI:

  • As an exterior picture (utilizing background-image,border-image,list-style-image,…)
  • Because the content material of a pseudo aspect (e.g. ::earlier than or ::after)

Here’s a primary instance exhibiting the way you the best way to use these two strategies:

The principle problem with this explicit implementation is that you must convert the SVG manually each time you want a brand new icon and it’s not actually nice to have this lengthy string of unreadable code in your CSS.

That is the place Sass involves the rescue!

Utilizing a Sass operate

By utilizing Sass, we are able to make our life less complicated by copying the supply code of our SVG instantly in our codebase, letting Sass encode them correctly to keep away from any browser error.

This resolution is usually impressed by an present operate developed by Threespot Media and out there in their repository.

Listed below are the 4 steps of this method:

  • Create a variable with all of your SVG icons listed.
  • Record all of the characters that must be skipped for a knowledge URI.
  • Implement a operate to encode the SVGs to an information URI format.
  • Use your operate in your code.

1. Icons listing

* Add all of the icons of your venture on this Sass listing
$svg-icons: (
  burger: '<svg xmlns="" viewBox="0 0 24.8 18.92" width="24.8" peak="18.92"><path d="M23.8,9.46H1m22.8,8.46H1M23.8,1H1" fill="none" stroke="#000" stroke-linecap="spherical" stroke-width="2"/></svg>'

2. Record of escaped characters

* Characters to flee from SVGs
* This listing lets you have inline CSS in your SVG code as properly
$fs-escape-chars: (
  ' ': '%20',
  ''': '%22',
  '"': '%27',
  '#': '%23',
  "": '%2F',
  ':': '%3A',
  '(': '%28',
  ')': '%29',
  '%': '%25',
  '<': '%3C',
  '>': '%3E',
  '': '%5C',
  '^': '%5E',
  '': '%7C',
  '': '%7D',

3. Encode operate

* You may name this operate through the use of `svg(nameOfTheSVG)`
@operate svg($identify) {
  // Test if icon exists
  @if not map-has-key($svg-icons, $identify) {
    @error 'icon “#{$identify}” doesn't exists in $svg-icons map';
    @return false;

  // Get icon information
  $icon-map: map-get($svg-icons, $identify);

  $escaped-string: '';
  $unquote-icon: unquote($icon-map);
  // Loop by every character in string
  @for $i from 1 by str-length($unquote-icon) {
    $char: str-slice($unquote-icon, $i, $i);

    // Test if character is in image map
    $char-lookup: map-get($fs-escape-chars, $char);

    // Whether it is, use escaped model
    @if $char-lookup != null {
        $char: $char-lookup;

    // Append character to escaped string
    $escaped-string: $escaped-string + $char;

  // Return inline SVG information
  @return url('information:picture/svg+xml, #{$escaped-string} ');

4. Add an SVG in your web page

button {
  &::after {
    /* Import inline SVG */
    content material: svg(burger);

When you’ve got adopted these steps, Sass ought to compile your code correctly and output the next:

button::after {
  content material: url("information:picture/svg+xml, %3Csvgpercent20xmlns=%27httppercent3Apercent2Fpercent2Fwww.w3.orgpercent2F2000percent2Fsvgpercent27percent20viewBox=%270percent200percent2024.8percent2018.92percent27percent20width=%2724.8percent27percent20height=%2718.92percent27percent3Epercent3Cpathpercent20d=%27M23.8,9.46H1m22.8,8.46H1M23.8,1H1percent27percent20fill=%27nonepercent27percent20stroke=%27percent23000percent27percent20stroke-linecap=%27roundpercent27percent20stroke-width=%272percent27percent2Fpercent3Epercent3Cpercent2Fsvgpercent3E ");

Customized properties

The now-implemented Sass svg() operate works nice. However its largest flaw is that an icon that’s wanted in a number of locations in your code might be duplicated and will enhance your compiled CSS file weight by quite a bit!

To keep away from this, we are able to retailer all our icons into CSS variables and use a reference to the variable as an alternative of outputting the encoded URI each time.

We are going to maintain the identical code we had earlier than, however this time we are going to first output all of the icons from the Sass listing into the basis of our webpage:

  * Convert all icons into customized properties
  * They are going to be out there to any HTML tag since they're connected to the :root

:root {
  @every $identify, $code in $svg-icons {
    --svg-#{$identify}: #{svg($identify)};

Now, as an alternative of calling the svg() operate each time we want an icon, now we have to make use of the variable that was created with the --svg prefix.

button::after {
  /* Import inline SVG */
  content material: var(--svg-burger);

Optimizing your SVGs

This method doesn’t present any optimization on the supply code of the SVG you’re utilizing. Just be sure you don’t depart pointless code; in any other case they are going to be encoded as properly and can enhance your CSS file measurement.

You may verify this nice listing of instruments and data on the best way to optimize correctly your SVG. My favourite instrument is Jake Archibald’s SVGOMG — merely drag your file in there and duplicate the outputted code.

Bonus: Updating the icon on hover

With this method, we can’t choose with CSS particular elements of the SVG. For instance, there isn’t a solution to change the fill coloration of the icon when the person hovers the button. However there are just a few tips we are able to use with CSS to nonetheless have the ability to modify the look of our icon.

For instance, in case you have a black icon and also you wish to have it white on hover, you need to use the invert() CSS filter. We are able to additionally play with the hue-rotate() filter.

That’s it!

I hope you discover this little helper operate useful in your individual tasks. Let me know what you consider the method — I’d have an interest to know the way you’d make this higher or sort out it in another way!



Please enter your comment!
Please enter your name here

Most Popular

Recent Comments