SVG is the very best format for icons on an internet site, there’s little doubt about that. It means that you can have sharp icons regardless of the display pixel density, you possibly can change the types of the SVG on hover and you may even animate the icons with CSS or JavaScript.
There are lots of methods to incorporate an SVG on a web page and every method has its personal benefits and downsides. For the final couple of years, I’ve been utilizing a Sass perform to import immediately my icons in my CSS and keep away from having to mess up my HTML markup.
I’ve a Sass checklist with all of the supply codes of my icons. Every icon is then encoded into an information URI with a Sass perform and saved in a customized property on the foundation of the web page.
TL;DR
What I’ve for you here’s a Sass perform that creates a SVG icon library immediately in your CSS.
The SVG supply code is compiled with the Sass perform that encodes them in knowledge URI after which shops the icons in CSS customized properties. You may then use any icon anyplace in your CSS like as if it was an exterior picture.
That is an instance pulled straight from the code of my private website:
.c-filters__summary h2:after {
content material: var(--svg-down-arrow);
place: relative;
prime: 2px;
margin-left: auto;
animation: closeSummary .25s ease-out;
}
Demo
Sass construction
/* All of the icons supply codes */
$svg-icons: (
burger: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0...'
);
/* Sass perform to encode the icons */
@perform svg($identify) {
@return url('knowledge: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 system has each execs and cons, so please take them into consideration earlier than implementing this answer in your venture:
Execs
- There aren’t any HTTP requests for the SVG recordsdata.
- The entire icons are saved in a single place.
- If you might want to replace an icon, you don’t must 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 facet of the icon with CSS.
Cons
- 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 shall be.
I principally use this system for icons fairly than logos or illustrations. An encoded SVG is at all times going to be heavier than its unique file, so I nonetheless load my complicated SVG with an exterior file both with an <img>
tag or in my CSS with url(path/to/file.svg)
.
Encoding SVG into knowledge URI
Encoding your SVG as knowledge URIs isn’t new. In reality Chris Coyier wrote a put up about it over 10 years in the past to elucidate the best way to use this system and why you must (or mustn’t) use it.
There are two methods to make use of an SVG in your CSS with knowledge URI:
- As an exterior picture (utilizing
background-image,
border-image,
list-style-image,…) - Because the content material of a pseudo factor (e.g.
::earlier than
or::after
)
Here’s a fundamental instance exhibiting the way you the best way to use these two strategies:
The principle concern with this explicit implementation is that it’s a must to convert the SVG manually each time you want a brand new icon and it isn’t actually nice to have this lengthy string of unreadable code in your CSS.
That is the place Sass involves the rescue!
Utilizing a Sass perform
Through the use of Sass, we will make our life less complicated by copying the supply code of our SVG immediately in our codebase, letting Sass encode them correctly to keep away from any browser error.
This answer is usually impressed by an current perform developed by Threespot Media and out there in their repository.
Listed below are the 4 steps of this system:
- Create a variable with all of your SVG icons listed.
- Listing all of the characters that must be skipped for an information URI.
- Implement a perform to encode the SVGs to an information URI format.
- Use your perform in your code.
1. Icons checklist
/**
* Add all of the icons of your venture on this Sass checklist
*/
$svg-icons: (
burger: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24.8 18.92" width="24.8" top="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. Listing of escaped characters
/**
* Characters to flee from SVGs
* This checklist means that you can have inline CSS in your SVG code as nicely
*/
$fs-escape-chars: (
' ': '%20',
''': '%22',
'"': '%27',
'#': '%23',
"https://css-tricks.com/": '%2F',
':': '%3A',
'(': '%28',
')': '%29',
'%': '%25',
'<': '%3C',
'>': '%3E',
'': '%5C',
'^': '%5E',
'': '%7C',
'': '%7D',
);
3. Encode perform
/**
* You may name this perform through the use of `svg(nameOfTheSVG)`
*/
@perform svg($identify) {
// Examine 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 knowledge
$icon-map: map-get($svg-icons, $identify);
$escaped-string: '';
$unquote-icon: unquote($icon-map);
// Loop by way of every character in string
@for $i from 1 by way of str-length($unquote-icon) {
$char: str-slice($unquote-icon, $i, $i);
// Examine 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 knowledge
@return url('knowledge:picture/svg+xml, #{$escaped-string} ');
}
4. Add an SVG in your web page
button {
&::after {
/* Import inline SVG */
content material: svg(burger);
}
}
If in case you have adopted these steps, Sass ought to compile your code correctly and output the next:
button::after {
content material: url("knowledge: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()
perform works nice. However its greatest flaw is that an icon that’s wanted in a number of locations in your code shall be duplicated and will enhance your compiled CSS file weight by lots!
To keep away from this, we will retailer all our icons into CSS variables and use a reference to the variable as a substitute of outputting the encoded URI each time.
We’ll preserve the identical code we had earlier than, however this time we’ll first output all of the icons from the Sass checklist into the foundation 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 a substitute of calling the svg()
perform each time we’d like an icon, we’ve got 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 system doesn’t present any optimization on the supply code of the SVG you’re utilizing. Just be sure you don’t go away pointless code; in any other case they are going to be encoded as nicely and can enhance your CSS file dimension.
You may test this nice checklist of instruments and knowledge on the best way to optimize correctly your SVG. My favourite software is Jake Archibald’s SVGOMG — merely drag your file in there and replica the outputted code.
Bonus: Updating the icon on hover
With this system, we can’t choose with CSS particular components of the SVG. For instance, there is no such thing as a solution to change the fill
coloration of the icon when the consumer hovers the button. However there are a number of methods we will use with CSS to nonetheless be capable to modify the look of our icon.
For instance, in case you have a black icon and also you need to have it white on hover, you should 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 perform helpful in your personal initiatives. Let me know what you consider the method — I’d have an interest to understand how you’d make this higher or deal with it otherwise!