Modify SVG colors using CSS variables [duplicate] - css
Placing the SVG output directly inline with the page code I am able to simply modify fill colors with CSS like so:
polygon.mystar {
fill: blue;
}
circle.mycircle {
fill: green;
}
This works great, however I'm looking for a way to modify the "fill" attribute of an SVG when it's being served as a BACKGROUND-IMAGE.
html {
background-image: url(../img/bg.svg);
}
How can I change the colors now? Is it even possible?
For reference, here are the contents of my external SVG file:
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="320px" height="100px" viewBox="0 0 320 100" enable-background="new 0 0 320 100" xml:space="preserve">
<polygon class="mystar" fill="#3CB54A" points="134.973,14.204 143.295,31.066 161.903,33.77 148.438,46.896 151.617,65.43 134.973,56.679
118.329,65.43 121.507,46.896 108.042,33.77 126.65,31.066 "/>
<circle class="mycircle" fill="#ED1F24" cx="202.028" cy="58.342" r="12.26"/>
</svg>
You can use CSS masks, With the 'mask' property, you create a mask that is applied to an element.
.icon {
background-color: red;
-webkit-mask-image: url(icon.svg);
mask-image: url(icon.svg);
}
For more see this great article: https://codepen.io/noahblon/post/coloring-svgs-in-css-background-images
I needed something similar and wanted to stick with CSS. Here are LESS and SCSS mixins as well as plain CSS that can help you with this. Unfortunately, it's browser support is a bit lax. See below for details on browser support.
LESS mixin:
.element-color(#color) {
background-image: url('data:image/svg+xml;utf8,<svg ...><g stroke="#{color}" ... /></g></svg>');
}
LESS usage:
.element-color(#fff);
SCSS mixin:
#mixin element-color($color) {
background-image: url('data:image/svg+xml;utf8,<svg ...><g stroke="#{$color}" ... /></g></svg>');
}
SCSS usage:
#include element-color(#fff);
CSS:
// color: red
background-image: url('data:image/svg+xml;utf8,<svg ...><g stroke="red" ... /></g></svg>');
Here is more info on embedding the full SVG code into your CSS file. It also mentioned browser compatibility which is a bit too small for this to be a viable option.
One way to do this is to serve your svg from some server side mechanism.
Simply create a resource server side that outputs your svg according to GET parameters, and you serve it on a certain url.
Then you just use that url in your css.
Because as a background img, it isn't part of the DOM and you can't manipulate it.
Another possibility would be to use it regularly, embed it in a page in a normal way, but position it absolutely, make it full width & height of a page and then use z-index css property to put it behind all the other DOM elements on a page.
Yet another approach is to use mask. You then change the background color of the masked element. This has the same effect as changing the fill attribute of the svg.
HTML:
<glyph class="star"/>
<glyph class="heart" />
<glyph class="heart" style="background-color: green"/>
<glyph class="heart" style="background-color: blue"/>
CSS:
glyph {
display: inline-block;
width: 24px;
height: 24px;
}
glyph.star {
-webkit-mask: url(star.svg) no-repeat 100% 100%;
mask: url(star.svg) no-repeat 100% 100%;
-webkit-mask-size: cover;
mask-size: cover;
background-color: yellow;
}
glyph.heart {
-webkit-mask: url(heart.svg) no-repeat 100% 100%;
mask: url(heart.svg) no-repeat 100% 100%;
-webkit-mask-size: cover;
mask-size: cover;
background-color: red;
}
You will find a full tutorial here: http://codepen.io/noahblon/blog/coloring-svgs-in-css-background-images (not my own). It proposes a variety of approaches (not limited to mask).
Use the sepia filter along with hue-rotate, brightness, and saturation to create any color we want.
.colorize-pink {
filter: brightness(0.5) sepia(1) hue-rotate(-70deg) saturate(5);
}
https://css-tricks.com/solved-with-css-colorizing-svg-backgrounds/
It's possible with Sass!
The only thing you have to do is to url-encode your svg code. And this is possible with a helper function in Sass. I've made a codepen for this. Look at this:
http://codepen.io/philippkuehn/pen/zGEjxB
// choose a color
$icon-color: #F84830;
// functions to urlencode the svg string
#function str-replace($string, $search, $replace: '') {
$index: str-index($string, $search);
#if $index {
#return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
}
#return $string;
}
#function url-encode($string) {
$map: (
"%": "%25",
"<": "%3C",
">": "%3E",
" ": "%20",
"!": "%21",
"*": "%2A",
"'": "%27",
'"': "%22",
"(": "%28",
")": "%29",
";": "%3B",
":": "%3A",
"#": "%40",
"&": "%26",
"=": "%3D",
"+": "%2B",
"$": "%24",
",": "%2C",
"/": "%2F",
"?": "%3F",
"#": "%23",
"[": "%5B",
"]": "%5D"
);
$new: $string;
#each $search, $replace in $map {
$new: str-replace($new, $search, $replace);
}
#return $new;
}
#function inline-svg($string) {
#return url('data:image/svg+xml;utf8,#{url-encode($string)}');
}
// icon styles
// note the fill="' + $icon-color + '"
.icon {
display: inline-block;
width: 50px;
height: 50px;
background: inline-svg('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 30 30" enable-background="new 0 0 30 30" xml:space="preserve">
<path fill="' + $icon-color + '" d="M18.7,10.1c-0.6,0.7-1,1.6-0.9,2.6c0,0.7-0.6,0.8-0.9,0.3c-1.1-2.1-0.4-5.1,0.7-7.2c0.2-0.4,0-0.8-0.5-0.7
c-5.8,0.8-9,6.4-6.4,12c0.1,0.3-0.2,0.6-0.5,0.5c-0.6-0.3-1.1-0.7-1.6-1.3c-0.2-0.3-0.4-0.5-0.6-0.8c-0.2-0.4-0.7-0.3-0.8,0.3
c-0.5,2.5,0.3,5.3,2.1,7.1c4.4,4.5,13.9,1.7,13.4-5.1c-0.2-2.9-3.2-4.2-3.3-7.1C19.6,10,19.1,9.6,18.7,10.1z"/>
</svg>');
}
.icon {
width: 48px;
height: 48px;
display: inline-block;
background: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/18515/heart.svg) no-repeat 50% 50%;
background-size: cover;
}
.icon-orange {
-webkit-filter: hue-rotate(40deg) saturate(0.5) brightness(390%) saturate(4);
filter: hue-rotate(40deg) saturate(0.5) brightness(390%) saturate(4);
}
.icon-yellow {
-webkit-filter: hue-rotate(70deg) saturate(100);
filter: hue-rotate(70deg) saturate(100);
}
codeben article and demo
Now you can achieve this on the client side like this:
var green = '3CB54A';
var red = 'ED1F24';
var svg = '<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="320px" height="100px" viewBox="0 0 320 100" enable-background="new 0 0 320 100" xml:space="preserve"> <polygon class="mystar" fill="#'+green+'" points="134.973,14.204 143.295,31.066 161.903,33.77 148.438,46.896 151.617,65.43 134.973,56.679 118.329,65.43 121.507,46.896 108.042,33.77 126.65,31.066 "/><circle class="mycircle" fill="#'+red+'" cx="202.028" cy="58.342" r="12.26"/></svg>';
var encoded = window.btoa(svg);
document.body.style.background = "url(data:image/svg+xml;base64,"+encoded+")";
Fiddle here!
Download your svg as text.
Modify your svg text using javascript to change the paint/stroke/fill color[s].
Then embed the modified svg string inline into your css as described here.
If you are trying to use and SVG directly on CSS with url() like this;
a:before {
content: url('data:image/svg+xml; utf8, <svg xmlns="http://www.w3.org/2000/svg" x="0" y="0" viewBox="0 0 451 451"><path d="M345.441,2...
You should encode the # to %23, otherwise it won't work.
<svg fill="%23FFF" ...
You can store the SVG in a variable. Then manipulate the SVG string depending on your needs (i.e., set width, height, color, etc). Then use the result to set the background, e.g.
$circle-icon-svg: '<svg xmlns="http://www.w3.org/2000/svg"><circle cx="10" cy="10" r="10" /></svg>';
$icon-color: #f00;
$icon-color-hover: #00f;
#function str-replace($string, $search, $replace: '') {
$index: str-index($string, $search);
#if $index {
#return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
}
#return $string;
}
#function svg-fill ($svg, $color) {
#return str-replace($svg, '<svg', '<svg fill="#{$color}"');
}
#function svg-size ($svg, $width, $height) {
$svg: str-replace($svg, '<svg', '<svg width="#{$width}"');
$svg: str-replace($svg, '<svg', '<svg height="#{$height}"');
#return $svg;
}
.icon {
$icon-svg: svg-size($circle-icon-svg, 20, 20);
width: 20px; height: 20px; background: url('data:image/svg+xml;utf8,#{svg-fill($icon-svg, $icon-color)}');
&:hover {
background: url('data:image/svg+xml;utf8,#{svg-fill($icon-svg, $icon-color-hover)}');
}
}
I have made a demo too, http://sassmeister.com/gist/4cf0265c5d0143a9e734.
This code makes a few assumptions about the SVG, e.g. that <svg /> element does not have an existing fill colour and that neither width or height properties are set. Since the input is hardcoded in the SCSS document, it is quite easy to enforce these constraints.
Do not worry about the code duplication. gzip compression makes the difference negligible.
You can use the brightness filter, any value greater than 1 makes the element brighter, and any value less than 1 makes it darker. So, we can make those light SVG’s dark, and vice versa, for example, this will make the svg darker:
filter: brightness(0);
In order to change the color and not only brightness level we can use sepia filter along with hue-rotate, brightness, for example:
.colorize-blue {
filter: brightness(0.5) sepia(1) hue-rotate(140deg) saturate(6);
}
You can create your own SCSS function for this. Adding the following to your config.rb file.
require 'sass'
require 'cgi'
module Sass::Script::Functions
def inline_svg_image(path, fill)
real_path = File.join(Compass.configuration.images_path, path.value)
svg = data(real_path)
svg.gsub! '{color}', fill.value
encoded_svg = CGI::escape(svg).gsub('+', '%20')
data_url = "url('data:image/svg+xml;charset=utf-8," + encoded_svg + "')"
Sass::Script::String.new(data_url)
end
private
def data(real_path)
if File.readable?(real_path)
File.open(real_path, "rb") {|io| io.read}
else
raise Compass::Error, "File not found or cannot be read: #{real_path}"
end
end
end
Then you can use it in your CSS:
.icon {
background-image: inline-svg-image('icons/icon.svg', '#555');
}
You will need to edit your SVG files and replace any fill attributes in the markup with fill="{color}"
The icon path is always relative to your images_dir parameter in the same config.rb file.
Similar to some of the other solutions, but this is pretty clean and keeps your SCSS files tidy!
In some (very specific) situations this might be achieved by using a filter. For example, you can change a blue SVG image to purple by rotating the hue 45 degrees using filter: hue-rotate(45deg);. Browser support is minimal but it's still an interesting technique.
Demo
If you wanna swap in a simple way from white to black or some like that, try this:
filter: invert(100%);
for monochrome background you could use a svg with a mask, where the background color should be displayed
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" preserveAspectRatio="xMidYMid meet" focusable="false" style="pointer-events: none; display: block; width: 100%; height: 100%;" >
<defs>
<mask id="Mask">
<rect width="100%" height="100%" fill="#fff" />
<polyline stroke-width="2.5" stroke="black" stroke-linecap="square" fill="none" transform="translate(10.373882, 8.762969) rotate(-315.000000) translate(-10.373882, -8.762969) " points="7.99893906 13.9878427 12.7488243 13.9878427 12.7488243 3.53809523"></polyline>
</mask>
</defs>
<rect x="0" y="0" width="20" height="20" fill="white" mask="url(#Mask)" />
</svg>
and than use this css
background-repeat: no-repeat;
background-position: center center;
background-size: contain;
background-image: url(your/path/to.svg);
background-color: var(--color);
Since this comes up on Google despite the age, I thought I might as well give a solution that I'm employing in the distant future of 2022 after looking at the options here.
This is really just the mask solution from before, but on a pseudo-element.
.icon {
height: 1.5rem;
width: 1.5rem;
}
.icon::before {
content: "";
display: block;
width: 100%;
height: 100%;
mask-repeat: no-repeat;
mask-position: center;
mask-size: contain;
mask-image: url("path/to/svg/icon.svg");
-webkit-mask-repeat: no-repeat;
-webkit-mask-position: center;
-webkit-mask-size: contain;
-webkit-mask-image: url("path/to/svg/icon.svg");
}
This works in all major browsers today, although obviously you can't have an SVG with multiple colors using this. That's the cost of business if the site doesn't let you inject them inline, or if you don't fancy doing font icons, etc.
Late to the show here, BUT, I was able to add a fill color to the SVG polygon, if you're able to directly edit the SVG code, so for example the following svg renders red, instead of default black. I have not tested outside of Chrome though:
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="500px" height="500px" viewBox="0 0 500 500" enable-background="new 0 0 500 500" xml:space="preserve">
<polygon
fill="red"
fill-rule="evenodd" clip-rule="evenodd" points="452.5,233.85 452.5,264.55 110.15,264.2 250.05,390.3 229.3,413.35
47.5,250.7 229.3,86.7 250.05,109.75 112.5,233.5 "/>
</svg>
The only way i found for this, and to be cross browser (aka bulletproof), is to render the SVG with PHP and pass Query String to set the color.
The SVG, here called "arrow.php"
<?php
$fill = filter_input(INPUT_GET, 'fill');
$fill = strtolower($fill);
$fill = preg_replace("/[^a-z0-9]/", '', $fill);
if(empty($fill)) $fill = "000000";
header('Content-type: image/svg+xml');
echo '<?xml version="1.0" encoding="utf-8"?>';
?>
<svg xmlns="http://www.w3.org/2000/svg" width="7.4" height="12" viewBox="0 0 7.4 12">
<g>
<path d="M8.6,7.4,10,6l6,6-6,6L8.6,16.6,13.2,12Z" transform="translate(-8.6 -6)" fill="#<?php echo htmlspecialchars($fill); ?>" fill-rule="evenodd"/>
</g>
</svg>
Then you call the image like this
.cssclass{ background-image: url(arrow.php?fill=112233); }
Works only with PHP. And remember that everytime you change the color value, your browser will load a new image.
scss create function
#function url-svg($icon) {
#return url("data:image/svg+xml;utf8,#{str-replace($icon, "#", "%23")}");
}
scss use
url-svg('<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M13.125 0H1.875C0.84082 0 0 0.84082 0 1.875V10.3125C0 11.3467 0.84082 12.1875 1.875 12.1875H4.6875V14.6484C4.6875 14.9355 5.01563 15.1025 5.24707 14.9326L8.90625 12.1875H13.125C14.1592 12.1875 15 11.3467 15 10.3125V1.875C15 0.84082 14.1592 0 13.125 0Z" fill="#8A8A8F"/></svg>')
css generated
url('data:image/svg+xml;utf8,<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M13.125 0H1.875C0.84082 0 0 0.84082 0 1.875V10.3125C0 11.3467 0.84082 12.1875 1.875 12.1875H4.6875V14.6484C4.6875 14.9355 5.01563 15.1025 5.24707 14.9326L8.90625 12.1875H13.125C14.1592 12.1875 15 11.3467 15 10.3125V1.875C15 0.84082 14.1592 0 13.125 0Z" fill="%238A8A8F"/></svg>')
The str-replace function is used from bootstrap.
Here is another solution using a gradient and a monochrome icon as background and background-blend-mode to colorize the icon.
It requires the background-color to be white, else the whole background gets colored. I only tested on Chrome.
.colored-background {
background-image: linear-gradient(45deg, green, green), url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23000000%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E');
background-color: #fff;
background-blend-mode: lighten, normal;
background-repeat: no-repeat;
background-position: center, center right .8em;
background-size: auto, 0.6em;
color: red;
display: inline-flex;
align-items: center;
padding: 0.5em;
padding-right: 2em;
height: 1.6em;
width: auto;
border: 1px solid gray;
}
.bg {
background-color: #ddd;
padding: 1em;
}
<div class="bg">
<div class="colored-background">green icon from black svg</div>
</div>
Related to a closed question that is linked to here, but not related directly to this question.
So in case, anyone needs actually to replace src like in the linked question, there is already an answer there. Furthermore if anyone is coming from Vue, and the src path is change on compile, I've come up with a different solution.
In my case, the parent element is a link, but it could be anything really.
<a
v-for="document in documents" :key="document.uuid"
:href="document.url"
target="_blank"
class="item flex align-items-center gap-2 hover-parent"
>
<img alt="documents" class="icon" src="../assets/PDF.svg" />
<strong>{{ document.name }}</strong>
<img class="itemImage ml-auto hide-on-parent-hover" src="../assets/download-circular-button.svg" />
<img class="itemImage ml-auto show-on-parent-hover" src="../assets/download-circular-button-hover.svg" />
</a>
.hover-parent .show-on-parent-hover { display: none }
.hover-parent .hide-on-parent-hover { display: block }
.hover-parent:hover .show-on-parent-hover { display: block }
.hover-parent:hover .hide-on-parent-hover { display: none }
So the solution here is not to change src attribute, but instead to put both <img> elements in the DOM and only display the one that is needed.
If you don't have a parent element that's supposed to be hovered on, you can simply wrap both images in a div.
<div class="hover-parent" >
<img class="hide-on-parent-hover" src="../assets/download-circular-button.svg" />
<img class="show-on-parent-hover" src="../assets/download-circular-button-hover.svg" />
</div>
You might also change CSS to the following, so the .hover-parent ancestor must be a direct parent:
.hover-parent > .show-on-parent-hover { display: none }
.hover-parent > .hide-on-parent-hover { display: block }
.hover-parent:hover > .show-on-parent-hover { display: block }
.hover-parent:hover > .hide-on-parent-hover { display: none }
This is my favorite method, but your browser support must be very progressive. With the mask property you create a mask that is applied to an element. Everywhere the mask is opaque, or solid, the underlying image shows through. Where it’s transparent, the underlying image is masked out, or hidden. The syntax for a CSS mask-image is similar to background-image.look at the codepenmask
A lot of IFs, but if your pre base64 encoded SVG starts:
<svg fill="#000000
Then the base64 encoded string will start:
PHN2ZyBmaWxsPSIjMDAwMDAw
if the pre-encoded string starts:
<svg fill="#bfa76e
then this encodes to:
PHN2ZyBmaWxsPSIjYmZhNzZl
Both encoded strings start the same:
PHN2ZyBmaWxsPSIj
The quirk of base64 encoding is every 3 input characters become 4 output characters. With the SVG starting like this then the 6-character hex fill color starts exactly on an encoding block 'boundary'.
Therefore you can easily do a cross-browser JS replace:
output = input.replace(/MDAwMDAw/, "YmZhNzZl");
But tnt-rox answer above is the way to go moving forward.
Related
How to display icon from svg sprite in pseudo element with ruby on rails
I want to create a menu like this Home > where the right arrow is an icon in an svg sprite. I would like to place the > as a psuedo element in the css selector so that i can make any menu have the right arrow just by adding the css selector .menu-arrow. I am trying to do this in ruby on rails 6 with no success. I have tried adding the svg icon sprite as a background content but it doesn't seem to work correctly. My svg sprite path to svg sprite: app/assets/images/sprites.svg <svg aria-hidden="true" style="position: absolute; width: 0; height: 0; overflow: hidden;" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <defs> <symbol id="icon-check-solid" viewBox="0 0 32 32"> <path d="M10.869 27.463l-10.4-10.4c-0.625-0.625-0.625-1.638 0-2.263l2.263-2.263c0.625-0.625 1.638-0.625 2.263 0l7.006 7.006 15.006-15.006c0.625-0.625 1.638-0.625 2.263 0l2.263 2.263c0.625 0.625 0.625 1.638 0 2.263l-18.4 18.4c-0.625 0.625-1.638 0.625-2.263-0z"></path> </symbol> <symbol id="icon-chevron-down-solid" viewBox="0 0 28 32"> <path d="M12.939 23.842l-12.146-12.146c-0.586-0.586-0.586-1.536 0-2.121l1.417-1.417c0.585-0.585 1.533-0.586 2.119-0.002l9.672 9.626 9.672-9.626c0.586-0.583 1.534-0.582 2.119 0.002l1.417 1.417c0.586 0.586 0.586 1.536 0 2.121l-12.146 12.146c-0.586 0.586-1.536 0.586-2.121 0z"></path> </symbol> </defs> </svg>` My css class .menu-arrow { &::after { content: ''; display: inline-block; height: 2rem; width: 2rem; background-image: asset-url("images/sprites.svg#icon-chevron-down-solid"); transform: rotate(90deg) scale(1.5); fill: var(--color-white); color: var(--color-white); font-weight: 700; border: 1px solid red; } } } How do i make this work?
This article suggests the #id in the CSS url is referencing a view rather than a symbol You can certainly use your sprite as an inline SVG (shadow) DOM element via use, and make a helper to streamline the process (see this) For your chevron specifically, you can achieve an almost identical graphic element using your pseudo element without a background (borders on two sides with rounded corners and rotated 45deg). I made a pen here that demonstrates this approach
How to make specific shaped divs
I am working on a project that has a map on it. Each section of the map highlights as you hover over it, and it hyperlinks to a corresponding website. On some of the areas, I can just size a div and absolutely place it with overlaying background image set to opacity:0. On Hover I change the opacity to 1 and all is good. Some of the other areas are too specific of a shape, so I've used transform to rotate the div, but I can't get specific enough. I'm getting too much overlap. Maybe I'm going about this the wrong way. I'm looking for any help. I've tried many things and I'm in a rut. Here is where I'm at now. https://jsfiddle.net/4w3emy4o/2/ <div class="erieBasin"> <div id="essex"></div> <div id="thames"></div> <div class="kettle"></div> <div class="close"></div> </div> .erieBasin { position:absolute; width:900px; height:589px; z-index:100; background-image: url(http://i67.tinypic.com/2h4b23k.jpg); } #essex { position:absolute; top:270px; left:275px; width:91px; height:72px; background-image: url(http://i63.tinypic.com/28s6cew.jpg); opacity: 0; } #essex:hover { opacity:1; } #thames { position:absolute; top:222px; left:325px; width:215px; height:60px; background-image: url(http://i66.tinypic.com/2nl8dwx.jpg); -ms-transform: rotate(-32deg); /* IE 9 */ -webkit-transform: rotate(-32deg); /* Safari */ transform: rotate(-32deg); opacity: 0; } #thames:hover { opacity:1; }
Although I like freestock's answer, I want to suggest a different approach. There is an element, that is specifically designed for such purposes: map. You can define polygons with it. The basic usage is: <img src="shapes.png" usemap="#shapes" > <map name="shapes"> <area shape=rect coords="50,50,100,100"> <area shape=rect coords="25,25,125,125" href="red.html" > <area shape=poly coords="450,25,435,60,400,75,435,90,450,125,465,90,500,75,465,60" href="yellow.html"> </map> example taken from the w3 link
SVG alternative:. 1- SVG Clip-path On this first snippet there's a svg clip-path ( helper: clip-path-generator ) applied on an image and a blury clone without the clip-path, both inside a container. A low opacity color layer was added to let the highlight even more clear. The clip-path area gets highlighted on :hover ps.1: made with the polygonal lasso tool quick and careless since its just an example. ps.2: on this clip-path generator, you can click and drag a picture from your Desktop into the canvas. You can easily find more clip-path generators around the web like this one. ps.3: you can build svg shapes on graphic softwares (like Inkscape or Adobe Illustrator) instead. body { margin: 0; background: lavender; } .clipped { cursor: pointer; } .clipped:hover { -webkit-filter: contrast(200%); /* Chrome, Safari, Opera */ filter: contrast(200%); } .container { position: relative; vertical-align: bottom; display: inline-block; border: 4px solid indigo; box-sizing: border-box; overflow: hidden; } .color { position: absolute; top: 0; left: 0; width:100%; height:100%; background-color: red; opacity: 0.2; } .back { -webkit-filter: blur(2px); /* Chrome, Safari, Opera */ filter: blur(2px); } .clipped { position: absolute; top:0; left:0; } #clip1 { /*Chrome,Safari*/ -webkit-clip-path: polygon(578px 230px,581px 228px,584px 228px,587px 230px,591px 232px,597px 236px,618px 239px,624px 238px,642px 241px,667px 245px,674px 245px,677px 243px,666px 238px,661px 240px,653px 238px,647px 233px,643px 234px,627px 234px,624px 230px,634px 223px,639px 225px,638px 221px,646px 213px,652px 207px,656px 204px,660px 206px,668px 203px,678px 200px,686px 203px,690px 199px,715px 195px,713px 192px,714px 186px,711px 188px,705px 188px,694px 185px,692px 180px,688px 183px,686px 178px,672px 175px,664px 181px,663px 176px,659px 175px,642px 172px,641px 170px,634px 168px,634px 160px,631px 157px,625px 157px,625px 155px,619px 155px,597px 158px,587px 167px,589px 171px,584px 173px,574px 183px,574px 186px,567px 188px,565px 189px,577px 190px,579px 193px,578px 196px,575px 196px,569px 202px,567px 206px,562px 210px,569px 215px,572px 217px,574px 226px); /*Firefox*/ clip-path: url("#clipPolygon"); /* iOS support inline encoded svg file*/ -webkit-mask: url(data:image/svg+xml;charset=utf-8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiIHdpZHRoPSIwIiBoZWlnaHQ9IjAiPgogIDxjbGlwUGF0aCBpZD0ic3ZnQ2xpcCI+CiAgICA8cGF0aCBpZD0ic3ZnUGF0aCIgZD0iTTU3OCwyMzAgTDU4MSwyMjggNTg0LDIyOCA1ODcsMjMwIDU5MSwyMzIgNTk3LDIzNiA2MTgsMjM5IDYyNCwyMzggNjQyLDI0MSA2NjcsMjQ1IDY3NCwyNDUgNjc3LDI0MyA2NjYsMjM4IDY2MSwyNDAgNjUzLDIzOCA2NDcsMjMzIDY0MywyMzQgNjI3LDIzNCA2MjQsMjMwIDYzNCwyMjMgNjM5LDIyNSA2MzgsMjIxIDY0NiwyMTMgNjUyLDIwNyA2NTYsMjA0IDY2MCwyMDYgNjY4LDIwMyA2NzgsMjAwIDY4NiwyMDMgNjkwLDE5OSA3MTUsMTk1IDcxMywxOTIgNzE0LDE4NiA3MTEsMTg4IDcwNSwxODggNjk0LDE4NSA2OTIsMTgwIDY4OCwxODMgNjg2LDE3OCA2NzIsMTc1IDY2NCwxODEgNjYzLDE3NiA2NTksMTc1IDY0MiwxNzIgNjQxLDE3MCA2MzQsMTY4IDYzNCwxNjAgNjMxLDE1NyA2MjUsMTU3IDYyNSwxNTUgNjE5LDE1NSA1OTcsMTU4IDU4NywxNjcgNTg5LDE3MSA1ODQsMTczIDU3NCwxODMgNTc0LDE4NiA1NjcsMTg4IDU2NSwxODkgNTc3LDE5MCA1NzksMTkzIDU3OCwxOTYgNTc1LDE5NiA1NjksMjAyIDU2NywyMDYgNTYyLDIxMCA1NjksMjE1IDU3MiwyMTcgNTc0LDIyNiB6Ii8+CiAgPC9jbGlwUGF0aD4KICA8cGF0aCBpZD0ic3ZnTWFzayIgZD0iTTU3OCwyMzAgTDU4MSwyMjggNTg0LDIyOCA1ODcsMjMwIDU5MSwyMzIgNTk3LDIzNiA2MTgsMjM5IDYyNCwyMzggNjQyLDI0MSA2NjcsMjQ1IDY3NCwyNDUgNjc3LDI0MyA2NjYsMjM4IDY2MSwyNDAgNjUzLDIzOCA2NDcsMjMzIDY0MywyMzQgNjI3LDIzNCA2MjQsMjMwIDYzNCwyMjMgNjM5LDIyNSA2MzgsMjIxIDY0NiwyMTMgNjUyLDIwNyA2NTYsMjA0IDY2MCwyMDYgNjY4LDIwMyA2NzgsMjAwIDY4NiwyMDMgNjkwLDE5OSA3MTUsMTk1IDcxMywxOTIgNzE0LDE4NiA3MTEsMTg4IDcwNSwxODggNjk0LDE4NSA2OTIsMTgwIDY4OCwxODMgNjg2LDE3OCA2NzIsMTc1IDY2NCwxODEgNjYzLDE3NiA2NTksMTc1IDY0MiwxNzIgNjQxLDE3MCA2MzQsMTY4IDYzNCwxNjAgNjMxLDE1NyA2MjUsMTU3IDYyNSwxNTUgNjE5LDE1NSA1OTcsMTU4IDU4NywxNjcgNTg5LDE3MSA1ODQsMTczIDU3NCwxODMgNTc0LDE4NiA1NjcsMTg4IDU2NSwxODkgNTc3LDE5MCA1NzksMTkzIDU3OCwxOTYgNTc1LDE5NiA1NjksMjAyIDU2NywyMDYgNTYyLDIxMCA1NjksMjE1IDU3MiwyMTcgNTc0LDIyNiB6IiAgLz4KPC9zdmc+) no-repeat; } <div class=container> <img class=back src="http://i67.tinypic.com/2h4b23k.jpg" alt=img> <div class=color></div> <img id=clip1 class=clipped src="http://i67.tinypic.com/2h4b23k.jpg" alt=img onClick="window.location.href = 'http://erca.org/'"> </div> <svg width="0" height="0"> <clipPath id="clipPolygon"> <polygon points="578 230,581 228,584 228,587 230,591 232,597 236,618 239,624 238,642 241,667 245,674 245,677 243,666 238,661 240,653 238,647 233,643 234,627 234,624 230,634 223,639 225,638 221,646 213,652 207,656 204,660 206,668 203,678 200,686 203,690 199,715 195,713 192,714 186,711 188,705 188,694 185,692 180,688 183,686 178,672 175,664 181,663 176,659 175,642 172,641 170,634 168,634 160,631 157,625 157,625 155,619 155,597 158,587 167,589 171,584 173,574 183,574 186,567 188,565 189,577 190,579 193,578 196,575 196,569 202,567 206,562 210,569 215,572 217,574 226"> </polygon> </clipPath> </svg> 2- SVG shape Second snippet, more simple: single pic without filters/clip-path plus a solid svg shape made on Adobe Illustrator with the pen tool: #container { position: relative; } svg { position: absolute; top: 0; left: 0; } polygon { cursor: pointer; opacity: 0.6; fill: green; } polygon:hover { opacity: 0.8; fill: red; } <div id=container> <img src="http://i67.tinypic.com/2h4b23k.jpg" alt=pic> <svg x="0px" y="0px" width="900px" height="589px" viewBox="0 0 900 589"> <polygon onClick="window.location.href = 'http://erca.org/'" points="364.333,317.333 357,311 348,310.667 347,307.667 349.333,305.667 352.333,305 351.667,302.333 349.667,300.667 351,292.667 353,291 356.667,292.667 357.333,295 359.333,283.667 369,276.333 370.667,269.667 371,258.333 374.667,260 384,257.333 391.333,253.333 392.333,256.667 396.667,253.333 399.667,257 406,254 406.667,251.333 413.667,246.333 416.667,246.333 419.333,244.667 419.333,239.333 425,239.333 426,233 435,228.333 438.667,231 442,227 451.334,221.333 456,221 455,209.333 461.667,208 463.334,206 463.334,200.333 472,199 476.667,197.333 476.334,195 473.667,194 480.334,193 487.334,191 487.334,187 489.667,184 492.334,187 497,184.333 506,183 510.667,184 516.667,190.667 510,188.333 505.334,189.667 505,196 508.334,196.667 511.334,199 507.667,202.667 509,205 510.334,206.667 515.667,205.667 523,206.667 523.667,208 517.334,213.333 515,215.333 513,215.333 511.667,219.333 507.667,218.667 509,224 506,226.667 504.334,229.333 501,231.333 493.334,231.333 496,232.667 492.667,233.667 492.334,235.667 486.667,236.667 481,242.333 478,243.333 473,249.333 468,252.333 462,256.333 457.667,261 448.667,267.333 447.667,272.333 448,277.333 446,279.667 445,283.667 445,286.333 441.333,288.667 439.333,287 440.667,281 438.667,280.667 435,280.667 433,282.667 432.667,287 428.333,286.333 422.667,286.667 410.667,291 399.667,297 399.667,298.333 395.333,299.333 384.667,305.333 380.667,307 375.667,310.333 371,313 "/> </svg></div> 3- Multiple SVG shapes On this 3rd snippet theres several SVG paths automatically generated by the Adobe Illustrator 'trace image' feature. #container { position: relative; } svg { position: absolute; top: 0; left: 0; } path { cursor: pointer; opacity: 0.6; fill: green; } path:hover { opacity: 0.8; fill: red; } <div id=container> <img src="http://i67.tinypic.com/2h4b23k.jpg" alt=pic> <svg x="0px" y="0px" width="900px" height="589px" viewBox="0 0 900 589" > <path fill-rule="evenodd" clip-rule="evenodd" fill="#C8C3D9" d="M621,1c-0.636,1.399-0.761,2.768-0.419,4.341 c1.288,5.921-1.485,9.547-7.905,10.679c-0.95,0.167-2.531,0.377-2.684,0.898c-1.604,5.508-4.256,2.165-6.962,1.147 c-4.679-1.76-5.131,3.151-6.943,5.281c-3.527,4.146-5.729,9.505-11.569,11.264c-1.419,0.428-1.953,1.404-2.299,2.891 c-0.71,3.05-2.289,5.953-2.643,9.017c-0.671,5.813-4.39,5.419-8.105,4.179c-2.642-0.881-3.365-0.332-3.359,2.167 c0.009,4.188-3.457,7.866-1.296,12.546c0.842,1.823,0.274,4.33-3.159,5.473c-2.983,0.992-3.423,4.852-2.261,7.854 c1.438,3.717-1.079,4.791-3.444,5.985c-2.556,1.289-5.006,2.491-7.343-0.882c-2.991-4.316-6.322-8.387-10.6-11.637 c-3.953-3.005-12.177-2.994-15.286,0.469c-0.489,0.545-0.911,1.771-0.633,2.284c1.83,3.369,0.619,7.16,1.848,10.807 c1.311,3.889-2.386,7.726-4.255,11.417c-1.538,3.039-3.374-0.044-5.052,0.043c-1.697,0.088-6.197-2.187-3.298,3.035 c1.008,1.814-0.603,1.767-1.466,2.357c-3.137,2.146-6.206,4.12-4.275,8.977c0.929,2.339-2.713,5.296,0.35,7.795 c1.486,1.213,1.08,2.853,1.468,4.281c1.473,5.423-0.634,8.65-4.091,12.339c-3.202,3.417-0.505,8.896-2.967,12.843 c-2.478,3.972-4.549,7.736-8.539,11.184c-7.964,6.881-18.967,4.844-26.576,11.621c-3.059,2.724-12.111,0.939-13.022-2.76 c-1.326-5.387-1.95-9.334-8.728-7.408c-0.107,0.03-0.533-0.488-0.539-0.758c-0.148-6.147-5.59-8.284-8.714-12.242 c-2.616-3.315-2.942-8.495-4.056-12.907c-0.349-1.38,1.187-1.665,2.218-2.233c9.833-5.427,20.175-10.22,25.302-21.328 c0.867-1.88,1.934-3.697,1.381-5.619c-1.202-4.176-0.723-8.294-0.009-12.382c1.189-6.809,0.988-13.581,0.194-20.396 c-1.816-15.602-1.411-31.279-1.292-46.932C460.038,17.966,458.553,9.496,457,1C511.667,1,566.333,1,621,1z"/> <path fill-rule="evenodd" clip-rule="evenodd" fill="#C8C3D9" d="M654,1c-1.459,4.093-2.451,7.463,3.889,8.63 c2.641,0.486,0.557,4.53-0.251,5.708c-2.024,2.95-1.739,4.355,1.1,6.399c2.42,1.742,1.534,5.813-1.242,6.345 c-2.741,0.525-2.993,1.515-1.683,3.643c1.161,1.886,1.613,3.65-0.93,4.954c-1.075,0.552-1.649,1.594-1.379,2.938 c0.391,1.936,9.94,10.392,11.923,10.52c6.692,0.435,9.054,3.03,7.106,9.193c-0.749,2.37-0.68,4.82-1.629,7.093 c-1.699,4.071-0.15,6.377,3.749,6.83c-3.163,4.634-5.624,9.72-6.222,15.303c-0.681,6.361-4.133,10.502-9.287,13.319 c-4.215,2.305-4.483,2.578-0.778,6.031c1.454,1.354,3.263,2.433,4.394,4.008c1.738,2.422,5.572,3.85,2.437,8.526 c-2.145,3.198,2.735,5.244,4.477,7.81c3.456,5.092,8.597,8.285,13.326,11.952c2.838,2.2,1.724,6.142,3.908,8.83 c2.632,3.237,6.126,6.185,6.084,10.974l0.021-0.016c-1.344,0.014-2.687,0.027-4.03,0.041c-0.095-0.073-0.19-0.146-0.285-0.219 c0.11,0.058,0.222,0.115,0.332,0.173c1.663,1.468,3.472,2.84,3.64,5.426c-2.015,0.84-3.79-0.621-5.667-0.399 c-1.424-1.277-3.134-1.837-5.004-1.995c-0.725-1.096-1.695-1.817-3.024-1.996c-2.773-3.101-7.28-5.208-10.078-3.263 c-3.538,2.46-7.716,3.731-10.993,6.593c2.444-0.464,5.746-0.583,6.852-2.201c4.523-6.622,9.499-1.483,14.263-1.173 c0.352,1.656,1.682,1.832,3.019,1.996c1.328,1.516,3.094,1.933,5.001,1.997c0.26,1.08,0.169,2.573,1.901,2.287 c2.654-0.439,4.746,1.129,7.095,1.769l-0.063-0.059c0.33,0.332,0.66,0.665,0.99,0.997l0.078,0.086c0,1.824,0,3.648,0,5.474 c1.039-1.736,1.496-3.439,0.612-5.169c0.265-0.256,0.53-0.512,0.795-0.768c0.971,4.885,5.968,6.076,8.737,9.348 c1.701,2.01,5.149,2.066,7.431,1.447c5.988-1.624,11.214,1.253,16.764,1.999c2.883,0.388,5.468,1.907,8.689,1.217 c2.896-0.62,3.501,2.743,3.408,4.254c-0.146,2.39-0.949,6.021-4.659,4.932c-3.617-1.062-6.592-1.194-9.538,1.383 c-1.153,1.01-2.597,0.322-3.749-0.356c-3.121-1.843-6.277-3.152-10.535-0.404c2.106-7.662-3.097-6.917-6.721-7.154 c-5.736-0.376-11.12-0.367-15.694-5.201c-1.467-1.551-5.282-0.905-5.277-4.864c0.001-0.843-1.523-0.992-2.592-0.87 c-3.587,0.41-7.128,0.412-10.521-1.16c-1.245-0.577-3.062-0.892-3.768,0.189c-2.468,3.775-4.699,1.733-7.863,0.856 c-6.231-1.727-12.831-2.236-19.316-2.854c-1.343-0.128-2.2-0.072-2.614-1.35c-0.708-2.185-2.231-2.735-4.406-3.288 c-3.385-0.861-3.124-4.222-3.127-6.961c-0.004-4.049-1.406-6.059-5.722-4.599c-0.312,0.105-0.788,0.417-0.902,0.315 c-5.343-4.809-10.547-0.277-15.832,0.099c-4.289,0.306-8.663,0.191-12.938-0.293c-3.081-0.35-3.781-7.101-0.749-9.654 c3.717-3.13,4.754-5.617,0.393-9.094c-1.753-1.397-1.614-4.155-1.551-6.44c0.078-2.83-0.568-4.931-4.012-4.703 c-5.134,0.34-7.73-3.567-10.224-6.853c-1.228-1.618-2.159-3.59-3.654-5.145c-0.934-0.971-1.568-1.847-0.232-3.351 c2.548-2.866,1.308-5.649-2.715-5.854c-2.35-0.119-3.493,0.116-2.215-2.814c1.361-3.121-2.762-1.951-3.471-3.714 c0.292-0.406,0.546-0.818,0.856-1.184c1.353-1.589,5.25-1.969,3.479-4.977c-1.381-2.346-4.454-1.646-6.904-1.001 c-1.11,0.293-2.152,0.845-3.352,1.33c-0.644-1.307-1.034-2.764-0.384-3.741c2.414-3.624,3.686-6.994,0.554-11.017 c-0.921-1.184-1.085-3.425,1.324-4.537c4.451-2.056,5.894-5.44,4.704-10.28c-1.581-6.427,1.897-10.801,8.45-9.804 c4.261,0.648,4.884-0.493,5.07-4.514c0.135-2.928,0.716-6.037,1.264-9.032c0.223-1.219,0.521-2.85,1.933-3.322 c6.363-2.13,9.415-7.516,12.709-12.674c2.687-4.207,5.984-2.49,9.011-0.744c2.817,1.627,4.507,2.378,3.991-2.127 c-0.485-4.242,3.521-2.279,4.419-2.089c2.909,0.618,4.872,1.149,4.632-2.914c-0.09-1.516,1.628-2.002,2.318-3.101 c0.68-1.083,2.357-2.304,1.431-3.446c-3.565-4.395-0.121-5.811,2.851-7.572C627.85,1.771,627.88,1.309,628,1 C636.667,1,645.333,1,654,1z M627.774,96.561c0.114,0.042,0.229,0.084,0.344,0.126c-0.078-0.141-0.156-0.28-0.234-0.421 C627.847,96.364,627.811,96.462,627.774,96.561z"/> <path fill-rule="evenodd" clip-rule="evenodd" fill="#C8C3D9" d="M802,1c-0.426,3.974-5.394,6.576-9.513,4.525 c-2.843-1.416-5.139-2.34-7.427,0.611c-0.272,0.351-0.907,0.709-1.295,0.638c-7.041-1.294-11.535,5.22-17.9,5.816 c-5.02,0.472-9.374,2.919-14.091,4.253c-1.397,0.396-3.277,0.732-4.415,0.124c-6.881-3.686-12.454,0.396-18.314,2.767 c-1.063,0.431-2.364,1.708-3.163,0.877c-5.367-5.586-12.122-0.241-17.975-2.441c-2.52-0.947-5.66-0.19-7.36-3.167 c-0.561-0.981-1.691-1.009-2.686-0.942c-5.136,0.341-10.402,0.158-15.354,1.314c-3.036,0.708-5.997,2.834-8.817,4.229 c-4.017,1.989-7.229,0.527-10.744,0.866c-4.286-0.727-4.203-3.537-2.052-5.922c3.287-3.644,0.969-5.944-1.745-7.097 C655.403,5.862,655.939,3.73,657,1C705.333,1,753.667,1,802,1z"/> <path fill-rule="evenodd" clip-rule="evenodd" fill="#C8C3D9" d="M377.034,231.039c-2.095,0.656-3.039,3.054-5.38,3.424 c-2.867,0.452-4.274-0.133-6.533-2.822c-5.705-6.793-0.559-12.35,0.548-18.314c0.729-3.926,2.179-7.622-0.117-11.549 c-0.699-1.194-0.134-2.814,0.318-4.324c1.044-3.481,2.462-6.877,2.575-10.63c0.122-4.067,1.5-7.21,5.979-8.651 c3.294-1.061,2.326-4.714,1.17-6.239c-2.172-2.869-0.053-2.504,1.445-2.82c6.979-1.472,14.012-2.721,20.936-4.414 c3.675-0.899,7.367-2.261,8.507-6.67c0.492-1.906,2.325-2.103,3.78-2.874c6.585-3.492,11.701-8.476,14.175-15.628 c0.865-2.503,2.878-1.622,4.336-2.19c1.428-0.558,1.915,0.805,2.176,2.029c0.552,2.598,1.178,5.18,1.694,7.784 c0.618,3.117,2.132,5.284,5.343,6.337c3.519,1.155,4.234,4.119,2.619,6.945c-1.763,3.084-0.617,3.779,2.129,4.005 c0.644,0.053,1.305-0.149,1.956-0.142c2.082,0.025,5.723,2.936,6.368,5.051c0.461,1.512,9.039,7.033,10.531,6.388 c2.639-1.14,5.846-0.763,8.066-2.167c8.357-5.285,18.569-5.563,27.011-10.479c2.251-1.312,2.41-3.805,3.597-5.709 c0.754-1.209,1.065-3.389,2.81-2.681c1.51,0.612,0.878,2.709,0.437,4.062c-2.568,7.857-6.248,15.012-13.566,19.557 c-2.477,1.537-3.346,3.274-2.438,6.223c1.071,3.481-1.568,6.72-5.221,7.573c-3.253,0.761-7.87-0.61-8.115,5.45 c-0.077,1.902-3.144,2.633-5.504,2.255c-3.302-0.53-5.572,0.272-5.774,4.181c-0.117,2.289-1.632,3.772-3.832,3.941 c-3.197,0.245-4.688,1.791-4.033,4.839c1.794,8.363-5.457,9.4-9.985,12.746c-4.739,3.501-10.943,3.074-15.83,6.216 c-1.899,1.221-3.715,2.204-4.005,4.671c-0.039,0.331-0.063,0.933-0.162,0.948c-5.838,0.88-6.214,8.414-11.737,9.628 c-3.102,0.682-5.476,2.481-7.102,5.074c-0.792,1.264-1.602,2.465-2.996,1.985c-3.834-1.317-7.611,1.294-11.419-0.066 c-0.672-0.24-1.992-0.089-2.325,0.375c-2.836,3.949-7.436,3.187-11.277,4.403c-0.766,0.242-1.604,0.511-2.373,0.428 c-1.097-0.119-3.534-9.888-2.905-10.821c0.732-1.088,2.352-1.452,1.698-3.641c-2.19-7.343-0.208-9.713,7.658-9.866 c0.329-0.007,0.658-0.058,1.825-0.165c-1.998-0.509-3.245-0.782-4.464-1.149c-1.291-0.389-2.6-0.821-2.635-2.54 c2.291-3.906,0.413-6.242-3.01-7.998c-0.688-2.771,3.086-4.252,1.998-7.552c-1.996,2.396-4.075,4.355-1.954,7.513 C374.69,225.783,378.237,227.526,377.034,231.039z M409.229,234.246c-0.189-0.194-0.381-0.386-0.576-0.574 c0.108-0.894,0.216-1.787,0.323-2.681l0.172-0.143l-0.137,0.177c-6.573,4.952-13.984,5.702-21.92,3.872 c9.794,3.404,19.137,1.464,29.509-1.315C413.275,232.726,411.271,233.622,409.229,234.246z M387.193,211.881 c-7.218-1.396-7.218-1.396-8.229,2.738C381.812,213.672,384.503,212.776,387.193,211.881z"/> <path fill-rule="evenodd" clip-rule="evenodd" fill="#C8C3D9" d="M558.16,88.179c0.58,6.603,0.58,6.603,11.612,5.345 c-0.596,1.087-1.541,1.646-2.642,2.118c-3.789,1.623-4.415,3.504-0.313,5.597c0.927,0.473,1.911,1.089,1.866,2.149 c-0.244,5.699,3.357,5.012,7.987,3.74c-5.516,7.755,1.912,11.103,4.421,15.652c1.604,2.908,3.72,7.709,9.146,6.74 c1.13-0.202,1.565,1.131,1.777,2.093c0.788,3.561,1.402,7.103,5.055,9.188c1.153,0.658,0.195,1.628-0.682,2.294 c-4.853,3.684-5.207,8.313-2.829,13.549c0.32,0.705,0.546,2.151,0.246,2.338c-5.873,3.652-6.453,11.752-12.69,15.039 c-3.34,1.76-5.692,4.687-7.738,7.604c-2.935,4.185-5.099,4.87-9.127,1.652c-3.963-3.165-14.702-3.195-19.99-0.743 c-2.924,1.355-6.414,1.97-9.663,2.021c-4.246,0.066-7.815,1.783-11.196,3.74c-2.596,1.503-4.641,1.232-6.088-0.761 c-5.609-7.726-13.104-5.796-20.268-3.843c-2.964,0.808-4.958,0.415-7.528-1.492c2.348-1.879,4.751-3.54,6.845-5.526 c6.834-6.485,9.552-14.298,9.787-23.916c0.16-6.58-1.96-14.657,5.369-19.678c2.277-1.56,1.857-11.045,0.605-13.203 c-2.896-4.989-3.097-10.98,0.854-14.332c2.201-1.867,3.317-6.591,8.07-4.635c0.898,0.37,1.736-1.261,2.505-2.146 c5.018-5.775,5.704-12.458,4.448-19.652c-0.864-4.953,1.776-7.305,6.898-6.422c4.947,0.853,7.105,5.112,10.169,8.236 c1.735,1.77,3.185,3.815,4.791,5.713c2.301,2.718,4.82,4.041,7.926,1.115C557.91,87.896,558.035,88.036,558.16,88.179z"/> <path fill-rule="evenodd" clip-rule="evenodd" fill="#C8C3D9" d="M350.393,309.262c4.419-1.638,4.624-4.51,3.326-8.054 c-0.846-2.309-0.276-4.546,1.089-7.227c3.142,4.104,4.908,2.597,5.589-1.303c0.882-5.046,2.727-8.743,7.496-11.918 c4.146-2.761,6.746-8.107,5.562-14.072c-0.509-2.563-0.416-4.323,3.442-4.89c3.93-0.576,8.261-0.77,11.842-3.1 c0.921-0.599,1.629-1.023,2.481,0.146c0.331,0.454,1.567,0.897,1.64,0.799c3.882-5.332,10.535-1.058,15.475-4.889 c5.665-4.393,6.402-3.441,13.354-12.226c0.786-0.994,1.914-1.268,3.091-1.404c1.672-0.193,2.61-1.086,3.171-2.71 c1.667-4.835,5.245-6.225,10.439-6.523c4.248-0.244,7.716-3.642,11.396-5.885c0.546-0.333,0.856-1.03,1.369-1.443 c4.185-3.368,6.484-6.305,6.863-11.347c0.355-4.721,5.65-2.063,6.678-5.301c0.909-2.864,0.884-6.229,5.748-5.824 c3.486,0.29,6.877-1.422,7.921-5.38c0.597-2.265,2.29-2.107,3.864-2.336c3.451-0.501,7.196-0.484,7.258-5.517 c0.009-0.767,0.895-1.751,1.735-1.427c5.754,2.215,10.214-2.694,15.611-2.779c1.977-0.03,3.449,0.037,4.005,1.733 c0.846,2.582-1.8,1.626-2.84,2.216c-2.492,1.414-4.876,3.53-8.354,2.04c4.377,2.044,4.959,8.251,11.049,8.428 c-1.296,2.432-2.811,4.452-1.098,7c1.335,1.984,2.342,3.337,5.125,2.377c2.433-0.84,5.12-0.938,8.275,0.446 c-4.607,3.379-9.447,5.452-12.699,9.595c-0.734,0.935-1.441,1.717-1.671,2.921c-1.178,6.172-4.55,8.858-10.574,10.728 c-4.596,1.426-9.162,3.742-13,6.644c-8.216,6.212-15.94,13.071-23.895,19.631c-1.024,0.844-2.416,1.426-2.46,2.938 c-0.069,2.388-1.465,2.591-3.359,2.468c-2.561-0.168-4.239,1.68-6.157,2.95c-0.749,0.496-1.497,1.377-0.54,1.926 c3.563,2.045,0.965,5.43,1.806,8.101c0.77,2.445-1.615,4.237-4.186,4.567c-2.425,0.312-4.978,0.627-7.34,0.198 c-3.26-0.591-5.939-1.114-6.6,3.301c-0.185,1.238-1.322,1.726-2.702,1.635c-9.302-0.614-17.793,2.171-25.235,7.385 c-7.75,5.429-16.35,9.031-24.742,13.12c-4.212,2.052-8.158,4.461-11.301,7.978c-1.176,1.314-2.453,2.025-3.782,0.663 c-1.841-1.886-3.265-4.035-6.116-4.823C355.919,310.118,353.311,309.975,350.393,309.262z M468.999,218.988 c1.001,0.698,1.862,1.837,3.442,1.094c-0.89-1.531-2.38-0.634-3.478-1.051c-0.396-1.292-1.165-1.987-2.517-1.309 c-1.877,0.942-1.081,2.832-1.408,4.322c-3.108,0.046-4.899,3.008-7.782,3.53c-3.745,0.68-5.836,3.165-7.214,6.466 c-1.074,0.314-2.266-1.008-3.461,0.171c1.362,1.046,2.424,0.786,3.418-0.226c1.956-0.921,4.771-1.086,5.934-2.24 c3.658-3.636,3.368-3.929,8.174-1.98c-0.5-2.164-1.235-4.308,0.874-5.769C466.076,220.669,466.365,218.264,468.999,218.988z M442.853,234.325c-0.278,0-0.557-0.003-0.834,0.014c-0.008,0-0.004,0.202-0.006,0.311c0.278,0.001,0.557,0.002,0.835,0.003 C442.848,234.544,442.848,234.435,442.853,234.325z"/> <path fill-rule="evenodd" clip-rule="evenodd" fill="#C8C3D9" d="M573.974,217.017c1.159-2.683,2.744-5.366-0.009-8.045 c0.269-0.069,0.536-0.14,0.805-0.209c-0.074-0.117-0.147-0.234-0.221-0.352c-0.182,0.202-0.362,0.404-0.543,0.607 c-0.798,0.211-1.949,0.158-2.337,0.677c-2.41,3.228-4.624,2.451-6.951-0.354c1.768-1.251,4.003-1.907,4.234-5.118 c0.172-2.383,2.715-5.166,5.033-5.743c3.841-0.956,6.362-3.646,6.6-6.496c0.246-2.954-3.771-3.951-6.67-4.84 c2.941-6.566,7.265-11.184,14.091-13.003c1.752-0.468,2.443-1.596,1.435-2.852c-2.139-2.663-0.05-3.9,1.464-5.31 c2.042-1.9,4.526-3.252,5.878-5.959c0.886-1.774,2.989-1.038,4.591-0.962c7.021,0.333,13.999,0.298,20.709-2.2 c1.218-0.454,1.404,0.436,1.737,1.133c0.622,1.304,1.653,2.67,3.015,1.871c4.936-2.895,3.765,1.031,3.946,3.377 c0.304,3.905,0.256,7.996,5.841,8.061c1.186,0.014,1.593,0.96,2.162,1.804c1.534,2.273,2.595,6.38,6.244,1.836 c0.227-0.282,1.499,0.203,2.255,0.43c3.957,1.189,7.976,1.885,12.128,1.791c0.931-0.021,2.263-0.511,2.741,0.585 c2.43,5.561,5.165,3.19,7.707,0.266c1.457-1.676,2.832-1.9,4.793-1.099c1.984,0.811,4.041,1.465,6.285,1.301 c1.843-0.134,2.796,1.134,4.205,2.23c4.011,3.12,8.975,4.98,13.386,7.632c3.545,2.132,7.832,0.371,11.256,2.544 c0.813,0.517,2.496-1.585,2.414,0.659c-0.039,1.073-0.617,2.479-2.313,2.861c-3.234,0.73-6.379,1.856-9.61,2.604 c-5.912,1.367-11.822,2.834-17.811,3.752c-3.203,0.491-8.96,0.853-9.421-0.334c-1.483-3.827-5.156-3.897-7.356-6.106 c-0.124-0.124-0.563,0.064-1.051,0.138c-0.447,2.492,2.271,1.789,3.16,2.953c0.985,1.289,3.781,1.411,3.003,3.851 c-0.718,2.249-3.001,1.57-4.756,1.697c-4.282,0.309-8.638-0.457-12.825,1.288c-2.045,0.852-3.523,1.884-4.976,3.721 c-3.333,4.217-6.671,9.107-11.186,11.519c-4.335,2.316-8.171,5.2-12.202,7.833c-2.721,1.778-4.488,4.386-2.629,8.022 c1.278,2.5-0.518,2.971-2.365,2.827c-11.115-0.863-22.184-1.949-31.722-8.644c-2.586-1.815-5.273-3.12-8.625-3.242 c-7.425-0.271-8.035-1.439-5.496-9.043c0.579,2.534,3.426,2.889,4.67,4.851c0.555,0.875-2.536,1.679,0.07,2.108 c0.718,0.119,1.671-0.299,1.881-1.273c0.228-1.056-0.08-1.987-1.053-2.544C577.73,219.056,575.846,218.047,573.974,217.017z M581.986,200.97c0.332-0.332,0.665-0.665,0.998-0.998c4.132-3.227,6.46-8.467,12.001-10.121 c-7.747,2.024-7.747,2.024-11.958,10.164c-0.332,0.333-0.666,0.665-0.999,0.998c-0.339,0.338-0.678,0.677-1.018,1.015 c-0.323,0.67-0.647,1.339-0.972,2.009c-0.681,0.324-1.361,0.649-2.041,0.975c-0.031,0.312-0.916,0.401-0.233,0.897 c0.065-0.314,0.131-0.629,0.197-0.942c0.679-0.327,1.356-0.655,2.035-0.982c0.325-0.665,0.65-1.33,0.976-1.995 C581.311,201.648,581.648,201.31,581.986,200.97z"/> <path fill-rule="evenodd" clip-rule="evenodd" fill="#C8C3D9" d="M359.599,337.555c-2.142-3.257-3.584-5.479-5.056-7.683 c-3.299-4.94-10.645-7.911-16.383-6.871c-4.896,0.887-9.532,2.402-13.899,4.784c-4.921,2.684-10.783,1.667-15.843,3.952 c-0.69,0.312-1.986-0.265-2.803-0.758c-6.143-3.711-12.589-6.699-19.409-8.976c-2.101-0.701-3.59-2.31-2.139-5.079 c1.509-2.88-0.795-5.964-0.097-8.819c1.407-5.754,1.661-11.479,1.605-17.392c-0.034-3.599,0.883-8.313,6.78-7.685 c0.722,0.077,1.726-0.262,2.235-0.772c4.94-4.941,13.406-5.865,19.976-3.15c5.89,2.435,12.251,5.232,18.362,5.139 c4.632-0.072,10.009-0.016,14.51-1.907c3.706-1.556,7.154-0.385,10.695-0.696c1.726-0.151,1.946,0.883,1.729,2.204 c-0.35,2.135-0.716,4.269-1.144,6.39c-0.229,1.14-0.317,2.454-2.16,1.289c-3.146-1.989-4.191,0.369-4.837,2.748 c-0.472,1.74-0.745,3.618-0.646,5.409c0.152,2.749,0.814,5.381-2.798,6.656c-1.145,0.404-1.731,2.048-0.965,3.479 c0.856,1.602,2.248,2.397,4.08,2.381c4.199-0.04,7.746,1.26,10.674,4.473c1.636,1.796,2.764,3.573,1.346,5.71 C360.557,326.688,360.754,331.77,359.599,337.555z"/> <path fill-rule="evenodd" clip-rule="evenodd" fill="#C8C3D9" d="M541.897,223.594c-3.604,0.122-7.297,0.694-10.816-0.561 c-5.817-2.074-11.211,0.934-16.826,1.188c-1.28,0.058-2.6,1.087-3.253-0.841c-0.505-1.493,0.432-2.113,1.417-3.187 c3.281-3.573,7.521-5.716,11.332-8.491c1.007-0.732,2.707-1.17,2.341-2.856c-0.393-1.804-1.928-2.77-3.62-2.958 c-2.467-0.275-4.972-0.215-7.461-0.262c-2.909-0.054-4.855-0.672-2.687-4.082c1.311-2.062,1.185-3.836-1.397-4.709 c-1.893-0.64-4.271-0.857-3.526-3.724c0.787-3.029,4.292-3.276,5.672-2.524c6.29,3.427,11,0.154,16.242-2.471 c4.63-2.318,10.469-0.52,14.932-2.778c3.862-1.955,7.172-3.44,11.502-2.286c2.143,0.571,4.03,1.374,6.358,2.927 c-3.896,1.44-7.563,1.757-10.987,3.326c-7.2,3.302-12.261,8.819-17.555,14.205c-2.596,2.64-2.939,6.886,0.041,8.116 c4.356,1.797,3.778,6.981,7.686,8.622C542.083,220.581,542.348,222.236,541.897,223.594z"/> <path fill-rule="evenodd" clip-rule="evenodd" fill="#C8C3D9" d="M553.266,210.74c1.375,4.441,4.651,7.87,6.453,12.037 c-9.276,3.021-16.313-0.348-19.465-9.296c-0.489-1.389-1.227-2.224-2.675-2.618c-3.632-0.988-3.353-4.164-1.764-5.849 c7.02-7.442,14.258-15.02,25.419-15.558c4.25-0.205,8.46,2.007,12.905,0.556c1.266-0.413,2.682,0.501,2.996,2.034 c0.327,1.595-1.028,2.82-2.067,3.037c-5.313,1.104-6.646,6.026-9.528,9.445c-0.416,0.493-0.531,1.238-0.945,1.733 c-1.026,1.229-4.618,0.979-3.122,3.356c1.208,1.918,2.093,4.865,5.429,5.125c3.201,0.249,3.031,3.473,3.738,5.578 c0.418,1.244-0.271,3.252-2.216,3.245c-2.49-0.009-5.436,1.354-7.225-1.712c-2.014-3.449-4.002-6.913-6.003-10.369 C554.856,210.899,554.445,210.425,553.266,210.74z M546.033,213.039c-1.264,1.095-1.085,2.113,0.369,3.304 c-0.156-1.266-0.285-2.304-0.414-3.342c0.182-0.222,0.381-0.433,0.534-0.673c0.04-0.062-0.063-0.214-0.1-0.325 C546.293,212.349,546.163,212.693,546.033,213.039z M549.6,205.654c-2.092-0.381-4.03,0.289-5.804,1.431 c-0.07,0.045,0.332,1.353,0.765,1.566C547.44,210.073,547.553,206.323,549.6,205.654z"/> </svg> </div>
Can you try an imagemap? They are pretty lightweight and there are lots of easy to use generators out there now: https://www.image-maps.com/
SVG fill in CSS? [duplicate]
Placing the SVG output directly inline with the page code I am able to simply modify fill colors with CSS like so: polygon.mystar { fill: blue; } circle.mycircle { fill: green; } This works great, however I'm looking for a way to modify the "fill" attribute of an SVG when it's being served as a BACKGROUND-IMAGE. html { background-image: url(../img/bg.svg); } How can I change the colors now? Is it even possible? For reference, here are the contents of my external SVG file: <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="320px" height="100px" viewBox="0 0 320 100" enable-background="new 0 0 320 100" xml:space="preserve"> <polygon class="mystar" fill="#3CB54A" points="134.973,14.204 143.295,31.066 161.903,33.77 148.438,46.896 151.617,65.43 134.973,56.679 118.329,65.43 121.507,46.896 108.042,33.77 126.65,31.066 "/> <circle class="mycircle" fill="#ED1F24" cx="202.028" cy="58.342" r="12.26"/> </svg>
You can use CSS masks, With the 'mask' property, you create a mask that is applied to an element. .icon { background-color: red; -webkit-mask-image: url(icon.svg); mask-image: url(icon.svg); } For more see this great article: https://codepen.io/noahblon/post/coloring-svgs-in-css-background-images
I needed something similar and wanted to stick with CSS. Here are LESS and SCSS mixins as well as plain CSS that can help you with this. Unfortunately, it's browser support is a bit lax. See below for details on browser support. LESS mixin: .element-color(#color) { background-image: url('data:image/svg+xml;utf8,<svg ...><g stroke="#{color}" ... /></g></svg>'); } LESS usage: .element-color(#fff); SCSS mixin: #mixin element-color($color) { background-image: url('data:image/svg+xml;utf8,<svg ...><g stroke="#{$color}" ... /></g></svg>'); } SCSS usage: #include element-color(#fff); CSS: // color: red background-image: url('data:image/svg+xml;utf8,<svg ...><g stroke="red" ... /></g></svg>'); Here is more info on embedding the full SVG code into your CSS file. It also mentioned browser compatibility which is a bit too small for this to be a viable option.
One way to do this is to serve your svg from some server side mechanism. Simply create a resource server side that outputs your svg according to GET parameters, and you serve it on a certain url. Then you just use that url in your css. Because as a background img, it isn't part of the DOM and you can't manipulate it. Another possibility would be to use it regularly, embed it in a page in a normal way, but position it absolutely, make it full width & height of a page and then use z-index css property to put it behind all the other DOM elements on a page.
Yet another approach is to use mask. You then change the background color of the masked element. This has the same effect as changing the fill attribute of the svg. HTML: <glyph class="star"/> <glyph class="heart" /> <glyph class="heart" style="background-color: green"/> <glyph class="heart" style="background-color: blue"/> CSS: glyph { display: inline-block; width: 24px; height: 24px; } glyph.star { -webkit-mask: url(star.svg) no-repeat 100% 100%; mask: url(star.svg) no-repeat 100% 100%; -webkit-mask-size: cover; mask-size: cover; background-color: yellow; } glyph.heart { -webkit-mask: url(heart.svg) no-repeat 100% 100%; mask: url(heart.svg) no-repeat 100% 100%; -webkit-mask-size: cover; mask-size: cover; background-color: red; } You will find a full tutorial here: http://codepen.io/noahblon/blog/coloring-svgs-in-css-background-images (not my own). It proposes a variety of approaches (not limited to mask).
Use the sepia filter along with hue-rotate, brightness, and saturation to create any color we want. .colorize-pink { filter: brightness(0.5) sepia(1) hue-rotate(-70deg) saturate(5); } https://css-tricks.com/solved-with-css-colorizing-svg-backgrounds/
It's possible with Sass! The only thing you have to do is to url-encode your svg code. And this is possible with a helper function in Sass. I've made a codepen for this. Look at this: http://codepen.io/philippkuehn/pen/zGEjxB // choose a color $icon-color: #F84830; // functions to urlencode the svg string #function str-replace($string, $search, $replace: '') { $index: str-index($string, $search); #if $index { #return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace); } #return $string; } #function url-encode($string) { $map: ( "%": "%25", "<": "%3C", ">": "%3E", " ": "%20", "!": "%21", "*": "%2A", "'": "%27", '"': "%22", "(": "%28", ")": "%29", ";": "%3B", ":": "%3A", "#": "%40", "&": "%26", "=": "%3D", "+": "%2B", "$": "%24", ",": "%2C", "/": "%2F", "?": "%3F", "#": "%23", "[": "%5B", "]": "%5D" ); $new: $string; #each $search, $replace in $map { $new: str-replace($new, $search, $replace); } #return $new; } #function inline-svg($string) { #return url('data:image/svg+xml;utf8,#{url-encode($string)}'); } // icon styles // note the fill="' + $icon-color + '" .icon { display: inline-block; width: 50px; height: 50px; background: inline-svg('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 30 30" enable-background="new 0 0 30 30" xml:space="preserve"> <path fill="' + $icon-color + '" d="M18.7,10.1c-0.6,0.7-1,1.6-0.9,2.6c0,0.7-0.6,0.8-0.9,0.3c-1.1-2.1-0.4-5.1,0.7-7.2c0.2-0.4,0-0.8-0.5-0.7 c-5.8,0.8-9,6.4-6.4,12c0.1,0.3-0.2,0.6-0.5,0.5c-0.6-0.3-1.1-0.7-1.6-1.3c-0.2-0.3-0.4-0.5-0.6-0.8c-0.2-0.4-0.7-0.3-0.8,0.3 c-0.5,2.5,0.3,5.3,2.1,7.1c4.4,4.5,13.9,1.7,13.4-5.1c-0.2-2.9-3.2-4.2-3.3-7.1C19.6,10,19.1,9.6,18.7,10.1z"/> </svg>'); }
.icon { width: 48px; height: 48px; display: inline-block; background: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/18515/heart.svg) no-repeat 50% 50%; background-size: cover; } .icon-orange { -webkit-filter: hue-rotate(40deg) saturate(0.5) brightness(390%) saturate(4); filter: hue-rotate(40deg) saturate(0.5) brightness(390%) saturate(4); } .icon-yellow { -webkit-filter: hue-rotate(70deg) saturate(100); filter: hue-rotate(70deg) saturate(100); } codeben article and demo
Now you can achieve this on the client side like this: var green = '3CB54A'; var red = 'ED1F24'; var svg = '<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="320px" height="100px" viewBox="0 0 320 100" enable-background="new 0 0 320 100" xml:space="preserve"> <polygon class="mystar" fill="#'+green+'" points="134.973,14.204 143.295,31.066 161.903,33.77 148.438,46.896 151.617,65.43 134.973,56.679 118.329,65.43 121.507,46.896 108.042,33.77 126.65,31.066 "/><circle class="mycircle" fill="#'+red+'" cx="202.028" cy="58.342" r="12.26"/></svg>'; var encoded = window.btoa(svg); document.body.style.background = "url(data:image/svg+xml;base64,"+encoded+")"; Fiddle here!
Download your svg as text. Modify your svg text using javascript to change the paint/stroke/fill color[s]. Then embed the modified svg string inline into your css as described here.
If you are trying to use and SVG directly on CSS with url() like this; a:before { content: url('data:image/svg+xml; utf8, <svg xmlns="http://www.w3.org/2000/svg" x="0" y="0" viewBox="0 0 451 451"><path d="M345.441,2... You should encode the # to %23, otherwise it won't work. <svg fill="%23FFF" ...
You can store the SVG in a variable. Then manipulate the SVG string depending on your needs (i.e., set width, height, color, etc). Then use the result to set the background, e.g. $circle-icon-svg: '<svg xmlns="http://www.w3.org/2000/svg"><circle cx="10" cy="10" r="10" /></svg>'; $icon-color: #f00; $icon-color-hover: #00f; #function str-replace($string, $search, $replace: '') { $index: str-index($string, $search); #if $index { #return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace); } #return $string; } #function svg-fill ($svg, $color) { #return str-replace($svg, '<svg', '<svg fill="#{$color}"'); } #function svg-size ($svg, $width, $height) { $svg: str-replace($svg, '<svg', '<svg width="#{$width}"'); $svg: str-replace($svg, '<svg', '<svg height="#{$height}"'); #return $svg; } .icon { $icon-svg: svg-size($circle-icon-svg, 20, 20); width: 20px; height: 20px; background: url('data:image/svg+xml;utf8,#{svg-fill($icon-svg, $icon-color)}'); &:hover { background: url('data:image/svg+xml;utf8,#{svg-fill($icon-svg, $icon-color-hover)}'); } } I have made a demo too, http://sassmeister.com/gist/4cf0265c5d0143a9e734. This code makes a few assumptions about the SVG, e.g. that <svg /> element does not have an existing fill colour and that neither width or height properties are set. Since the input is hardcoded in the SCSS document, it is quite easy to enforce these constraints. Do not worry about the code duplication. gzip compression makes the difference negligible.
You can use the brightness filter, any value greater than 1 makes the element brighter, and any value less than 1 makes it darker. So, we can make those light SVG’s dark, and vice versa, for example, this will make the svg darker: filter: brightness(0); In order to change the color and not only brightness level we can use sepia filter along with hue-rotate, brightness, for example: .colorize-blue { filter: brightness(0.5) sepia(1) hue-rotate(140deg) saturate(6); }
You can create your own SCSS function for this. Adding the following to your config.rb file. require 'sass' require 'cgi' module Sass::Script::Functions def inline_svg_image(path, fill) real_path = File.join(Compass.configuration.images_path, path.value) svg = data(real_path) svg.gsub! '{color}', fill.value encoded_svg = CGI::escape(svg).gsub('+', '%20') data_url = "url('data:image/svg+xml;charset=utf-8," + encoded_svg + "')" Sass::Script::String.new(data_url) end private def data(real_path) if File.readable?(real_path) File.open(real_path, "rb") {|io| io.read} else raise Compass::Error, "File not found or cannot be read: #{real_path}" end end end Then you can use it in your CSS: .icon { background-image: inline-svg-image('icons/icon.svg', '#555'); } You will need to edit your SVG files and replace any fill attributes in the markup with fill="{color}" The icon path is always relative to your images_dir parameter in the same config.rb file. Similar to some of the other solutions, but this is pretty clean and keeps your SCSS files tidy!
If you wanna swap in a simple way from white to black or some like that, try this: filter: invert(100%);
In some (very specific) situations this might be achieved by using a filter. For example, you can change a blue SVG image to purple by rotating the hue 45 degrees using filter: hue-rotate(45deg);. Browser support is minimal but it's still an interesting technique. Demo
for monochrome background you could use a svg with a mask, where the background color should be displayed <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" preserveAspectRatio="xMidYMid meet" focusable="false" style="pointer-events: none; display: block; width: 100%; height: 100%;" > <defs> <mask id="Mask"> <rect width="100%" height="100%" fill="#fff" /> <polyline stroke-width="2.5" stroke="black" stroke-linecap="square" fill="none" transform="translate(10.373882, 8.762969) rotate(-315.000000) translate(-10.373882, -8.762969) " points="7.99893906 13.9878427 12.7488243 13.9878427 12.7488243 3.53809523"></polyline> </mask> </defs> <rect x="0" y="0" width="20" height="20" fill="white" mask="url(#Mask)" /> </svg> and than use this css background-repeat: no-repeat; background-position: center center; background-size: contain; background-image: url(your/path/to.svg); background-color: var(--color);
Since this comes up on Google despite the age, I thought I might as well give a solution that I'm employing in the distant future of 2022 after looking at the options here. This is really just the mask solution from before, but on a pseudo-element. .icon { height: 1.5rem; width: 1.5rem; } .icon::before { content: ""; display: block; width: 100%; height: 100%; mask-repeat: no-repeat; mask-position: center; mask-size: contain; mask-image: url("path/to/svg/icon.svg"); -webkit-mask-repeat: no-repeat; -webkit-mask-position: center; -webkit-mask-size: contain; -webkit-mask-image: url("path/to/svg/icon.svg"); } This works in all major browsers today, although obviously you can't have an SVG with multiple colors using this. That's the cost of business if the site doesn't let you inject them inline, or if you don't fancy doing font icons, etc.
Late to the show here, BUT, I was able to add a fill color to the SVG polygon, if you're able to directly edit the SVG code, so for example the following svg renders red, instead of default black. I have not tested outside of Chrome though: <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="500px" height="500px" viewBox="0 0 500 500" enable-background="new 0 0 500 500" xml:space="preserve"> <polygon fill="red" fill-rule="evenodd" clip-rule="evenodd" points="452.5,233.85 452.5,264.55 110.15,264.2 250.05,390.3 229.3,413.35 47.5,250.7 229.3,86.7 250.05,109.75 112.5,233.5 "/> </svg>
The only way i found for this, and to be cross browser (aka bulletproof), is to render the SVG with PHP and pass Query String to set the color. The SVG, here called "arrow.php" <?php $fill = filter_input(INPUT_GET, 'fill'); $fill = strtolower($fill); $fill = preg_replace("/[^a-z0-9]/", '', $fill); if(empty($fill)) $fill = "000000"; header('Content-type: image/svg+xml'); echo '<?xml version="1.0" encoding="utf-8"?>'; ?> <svg xmlns="http://www.w3.org/2000/svg" width="7.4" height="12" viewBox="0 0 7.4 12"> <g> <path d="M8.6,7.4,10,6l6,6-6,6L8.6,16.6,13.2,12Z" transform="translate(-8.6 -6)" fill="#<?php echo htmlspecialchars($fill); ?>" fill-rule="evenodd"/> </g> </svg> Then you call the image like this .cssclass{ background-image: url(arrow.php?fill=112233); } Works only with PHP. And remember that everytime you change the color value, your browser will load a new image.
scss create function #function url-svg($icon) { #return url("data:image/svg+xml;utf8,#{str-replace($icon, "#", "%23")}"); } scss use url-svg('<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M13.125 0H1.875C0.84082 0 0 0.84082 0 1.875V10.3125C0 11.3467 0.84082 12.1875 1.875 12.1875H4.6875V14.6484C4.6875 14.9355 5.01563 15.1025 5.24707 14.9326L8.90625 12.1875H13.125C14.1592 12.1875 15 11.3467 15 10.3125V1.875C15 0.84082 14.1592 0 13.125 0Z" fill="#8A8A8F"/></svg>') css generated url('data:image/svg+xml;utf8,<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M13.125 0H1.875C0.84082 0 0 0.84082 0 1.875V10.3125C0 11.3467 0.84082 12.1875 1.875 12.1875H4.6875V14.6484C4.6875 14.9355 5.01563 15.1025 5.24707 14.9326L8.90625 12.1875H13.125C14.1592 12.1875 15 11.3467 15 10.3125V1.875C15 0.84082 14.1592 0 13.125 0Z" fill="%238A8A8F"/></svg>') The str-replace function is used from bootstrap.
Here is another solution using a gradient and a monochrome icon as background and background-blend-mode to colorize the icon. It requires the background-color to be white, else the whole background gets colored. I only tested on Chrome. .colored-background { background-image: linear-gradient(45deg, green, green), url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23000000%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E'); background-color: #fff; background-blend-mode: lighten, normal; background-repeat: no-repeat; background-position: center, center right .8em; background-size: auto, 0.6em; color: red; display: inline-flex; align-items: center; padding: 0.5em; padding-right: 2em; height: 1.6em; width: auto; border: 1px solid gray; } .bg { background-color: #ddd; padding: 1em; } <div class="bg"> <div class="colored-background">green icon from black svg</div> </div>
Related to a closed question that is linked to here, but not related directly to this question. So in case, anyone needs actually to replace src like in the linked question, there is already an answer there. Furthermore if anyone is coming from Vue, and the src path is change on compile, I've come up with a different solution. In my case, the parent element is a link, but it could be anything really. <a v-for="document in documents" :key="document.uuid" :href="document.url" target="_blank" class="item flex align-items-center gap-2 hover-parent" > <img alt="documents" class="icon" src="../assets/PDF.svg" /> <strong>{{ document.name }}</strong> <img class="itemImage ml-auto hide-on-parent-hover" src="../assets/download-circular-button.svg" /> <img class="itemImage ml-auto show-on-parent-hover" src="../assets/download-circular-button-hover.svg" /> </a> .hover-parent .show-on-parent-hover { display: none } .hover-parent .hide-on-parent-hover { display: block } .hover-parent:hover .show-on-parent-hover { display: block } .hover-parent:hover .hide-on-parent-hover { display: none } So the solution here is not to change src attribute, but instead to put both <img> elements in the DOM and only display the one that is needed. If you don't have a parent element that's supposed to be hovered on, you can simply wrap both images in a div. <div class="hover-parent" > <img class="hide-on-parent-hover" src="../assets/download-circular-button.svg" /> <img class="show-on-parent-hover" src="../assets/download-circular-button-hover.svg" /> </div> You might also change CSS to the following, so the .hover-parent ancestor must be a direct parent: .hover-parent > .show-on-parent-hover { display: none } .hover-parent > .hide-on-parent-hover { display: block } .hover-parent:hover > .show-on-parent-hover { display: block } .hover-parent:hover > .hide-on-parent-hover { display: none }
This is my favorite method, but your browser support must be very progressive. With the mask property you create a mask that is applied to an element. Everywhere the mask is opaque, or solid, the underlying image shows through. Where it’s transparent, the underlying image is masked out, or hidden. The syntax for a CSS mask-image is similar to background-image.look at the codepenmask
A lot of IFs, but if your pre base64 encoded SVG starts: <svg fill="#000000 Then the base64 encoded string will start: PHN2ZyBmaWxsPSIjMDAwMDAw if the pre-encoded string starts: <svg fill="#bfa76e then this encodes to: PHN2ZyBmaWxsPSIjYmZhNzZl Both encoded strings start the same: PHN2ZyBmaWxsPSIj The quirk of base64 encoding is every 3 input characters become 4 output characters. With the SVG starting like this then the 6-character hex fill color starts exactly on an encoding block 'boundary'. Therefore you can easily do a cross-browser JS replace: output = input.replace(/MDAwMDAw/, "YmZhNzZl"); But tnt-rox answer above is the way to go moving forward.
How to apply clipPath to a div with the clipPath position being relative to the div position
Not sure if I've formulated the title properly, but here goes the question. I have an SVG path of a cloud-like shape which I would like to use in CSS with the clip-path property. <path d="M46.9819755,61.8637972 C42.0075109,66.8848566 35.0759468,70 27.4091794,70 C12.2715076,70 0,57.8557238 0,42.875 C0,32.9452436 5.3914988,24.2616832 13.4354963,19.534921 C14.8172134,8.52285244 24.3072531,0 35.8087666,0 C43.9305035,0 51.0492374,4.2498423 55.01819,10.6250065 C58.2376107,8.87215568 61.9363599,7.875 65.8704472,7.875 C78.322403,7.875 88.4167076,17.8646465 88.4167076,30.1875 C88.4167076,32.1602271 88.1580127,34.0731592 87.6723639,35.8948845 L87.6723639,35.8948845 C93.3534903,38.685457 97.2583784,44.4851888 97.2583784,51.1875 C97.2583784,60.6108585 89.5392042,68.25 80.0171204,68.25 C75.4841931,68.25 71.3598367,66.5188366 68.2822969,63.6881381 C65.5613034,65.4654463 62.3012892,66.5 58.7971106,66.5 C54.2246352,66.5 50.0678912,64.7384974 46.9819755,61.8637972 Z" fill="lightblue" /> When I add an SVG element in HTML and define <clipPath> with that path, the browser positions the clipping path in the top-left corner. If I apply a margin to the clipped element, the mask is not linked and stays in its initial position. Other similar threads state that the clipPathUnits="objectBoundingBox" attribute should be added to the <clipPath> object, but that doesn't seem to solve my problem. I even transformed the path from absolute to relative and tried it like that, but got the same result. Is it possible to somehow link the clipping path with the clipped element so that when positioning is applied to the clipped element, the clipping path moves as well? Here is the relative path, if it helps: <path d="M46.9819755,61.8637972c-4.974,5.021,-11.906,8.136,-19.573,8.136c-15.137,0,-27.409,-12.144,-27.409,-27.125c0,-9.93,5.392,-18.613,13.436,-23.34c1.381,-11.012,10.871,-19.535,22.373,-19.535c8.122,0,15.24,4.25,19.209,10.625c3.22,-1.753,6.918,-2.75,10.852,-2.75c12.452,0,22.547,9.99,22.547,22.313c0,1.972,-0.259,3.885,-0.745,5.707l0,0c5.682,2.791,9.586,8.59,9.586,15.293c0,9.423,-7.719,17.062,-17.241,17.062c-4.533,0,-8.657,-1.731,-11.735,-4.562c-2.721,1.778,-5.981,2.812,-9.485,2.812c-4.572,0,-8.729,-1.761,-11.815,-4.636z fill="lightblue" /> As well as some test HTML/CSS. (I've set the left property to 10px so that you see the clipping issue occur) .clippedElement { width: 200px; height: 200px; position: absolute; left: 10px; top: 0; background-color: lightblue; -webkit-clip-path: url(#cloudClip); -moz-clip-path: url(#cloudClip); clip-path: url(#cloudClip); } <svg> <defs> <clipPath id="cloudClip"> <path d="M46.9819755,61.8637972 C42.0075109,66.8848566 35.0759468,70 27.4091794,70 C12.2715076,70 0,57.8557238 0,42.875 C0,32.9452436 5.3914988,24.2616832 13.4354963,19.534921 C14.8172134,8.52285244 24.3072531,0 35.8087666,0 C43.9305035,0 51.0492374,4.2498423 55.01819,10.6250065 C58.2376107,8.87215568 61.9363599,7.875 65.8704472,7.875 C78.322403,7.875 88.4167076,17.8646465 88.4167076,30.1875 C88.4167076,32.1602271 88.1580127,34.0731592 87.6723639,35.8948845 L87.6723639,35.8948845 C93.3534903,38.685457 97.2583784,44.4851888 97.2583784,51.1875 C97.2583784,60.6108585 89.5392042,68.25 80.0171204,68.25 C75.4841931,68.25 71.3598367,66.5188366 68.2822969,63.6881381 C65.5613034,65.4654463 62.3012892,66.5 58.7971106,66.5 C54.2246352,66.5 50.0678912,64.7384974 46.9819755,61.8637972 Z" /> </clipPath> </defs> </svg> <div class="clippedElement"></div>
Thanks to Robert's comment, I was able to solve the issue I had. Here is a PHP snippet I used to convert the absolute path to relative, so that the values are between 0 and 1. $absolute_path = "M46.9819755,61.8637972 C42.0075109,66.8848566 35.0759468,70 27.4091794,70 C12.2715076,70 0,57.8557238 0,42.875 C0,32.9452436 5.3914988,24.2616832 13.4354963,19.534921 C14.8172134,8.52285244 24.3072531,0 35.8087666,0 C43.9305035,0 51.0492374,4.2498423 55.01819,10.6250065 C58.2376107,8.87215568 61.9363599,7.875 65.8704472,7.875 C78.322403,7.875 88.4167076,17.8646465 88.4167076,30.1875 C88.4167076,32.1602271 88.1580127,34.0731592 87.6723639,35.8948845 L87.6723639,35.8948845 C93.3534903,38.685457 97.2583784,44.4851888 97.2583784,51.1875 C97.2583784,60.6108585 89.5392042,68.25 80.0171204,68.25 C75.4841931,68.25 71.3598367,66.5188366 68.2822969,63.6881381 C65.5613034,65.4654463 62.3012892,66.5 58.7971106,66.5 C54.2246352,66.5 50.0678912,64.7384974 46.9819755,61.8637972 Z"; function regex_callback($matches) { static $count = -1; $count++; $width = 98; $height = 70; if($count % 2) { return $matches[0] / $height; } else { return $matches[0] / $width; } } $relative_path = preg_replace_callback('(\d+(\.\d+)?)', 'regex_callback', $absolute_path); Since the clipping path is not rectangular, I couldn't divide the values with one number, but had to use the width and the height of the clipping path itself. .clippedElement { width: 98px; height: 70px; position: absolute; left: 10px; top: 0; background-color: lightblue; -webkit-clip-path: url(#cloudClip); -moz-clip-path: url(#cloudClip); clip-path: url(#cloudClip); } <svg width="98" height="70"> <defs> <clipPath id="cloudClip" clipPathUnits="objectBoundingBox"> <path d="M0.47940791326531,0.88376853142857 C0.42864807040816,0.95549795142857 0.3579178244898,1 0.27968550408163,1 C0.12521946530612,1 0,0.82651034 0,0.6125 C0,0.47064633714286 0.055015293877551,0.34659547428571 0.13709690102041,0.2790703 C0.15119605510204,0.12175503485714 0.24803319489796,0 0.36539557755102,0 C0.44827044387755,0 0.52091058571429,0.060712032857143 0.56141010204082,0.15178580714286 C0.59426133367347,0.12674508114286 0.63200367244898,0.1125 0.67214742040816,0.1125 C0.79920819387755,0.1125 0.90221130204082,0.25520923571429 0.90221130204082,0.43125 C0.90221130204082,0.45943181571429 0.89957155816327,0.48675941714286 0.89461595816327,0.51278406428571 L0.89461595816327,0.51278406428571 C0.95258663571429,0.55264938571429 0.99243243265306,0.63550269714286 0.99243243265306,0.73125 C0.99243243265306,0.86586940714286 0.91366534897959,0.975 0.81650122857143,0.975 C0.77024686836735,0.975 0.72816159897959,0.95026909428571 0.69675813163265,0.90983054428571 C0.66899289183673,0.93522066142857 0.63572744081633,0.95 0.59997051632653,0.95 C0.55331260408163,0.95 0.51089684897959,0.92483567714286 0.47940791326531,0.88376853142857 Z"></path> </clipPath> </defs> </svg> <div class="clippedElement"></div>
how to change svg fill color when used as base-64 background image data?
I'm using SVG for a project, loaded in css like this: background-image: url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20xmlns%3Axlink%3D%22http%3A//www.w3.org/1999/xlink%22%20version%3D%221.1%22%20x%3D%220px%22%20y%3D%220px%22%20width%3D%2222px%22%20height%3D%2238px%22%20viewBox%3D%220%200%2022%2038%22%20enable-background%3D%22new%200%200%2022%2038%22%20xml%3Aspace%3D%22preserve%22%3E%3Cstyle%3E.style0%7Bfill%3A%09%23f47216%3B%7D%3C/style%3E%3Cpath%20d%3D%22M2.643%2038c-0.64%200-1.282-0.231-1.79-0.699c-1.074-0.988-1.143-2.661-0.154-3.735l13.13-14.258L0.664%204.4%20c-0.967-1.094-0.865-2.765%200.229-3.732s2.765-0.864%203.7%200.229L19.37%2017.592c0.898%201%200.9%202.545-0.035%203.542L4.588%2037.1%20C4.067%2037.7%203.4%2038%202.6%2038z%22%20class%3D%22style0%22/%3E%3C/svg%3E'); I have some hover states to highlight by changing the fill color of the arrow. For now, I'm simply applying the same svg data with the fill portion (fill%3A%09%23f47216%3B%7D%3C where f47216 is the color) changed with the right/new color. Works pretty well. Though, I'd like to know if there's maybe some other smarter method.
Use filter property of CSS. For me I wanted to change the color of the icon to white on Hover: filter: grayscale(1) brightness(2);
Or if you want to do it dynamically try : var green = '3CB54A'; var red = 'ED1F24'; var svg = '<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="320px" height="100px" viewBox="0 0 320 100" enable-background="new 0 0 320 100" xml:space="preserve"> <polygon class="mystar" fill="#'+green+'" points="134.973,14.204 143.295,31.066 161.903,33.77 148.438,46.896 151.617,65.43 134.973,56.679 118.329,65.43 121.507,46.896 108.042,33.77 126.65,31.066 "/><circle class="mycircle" fill="#'+red+'" cx="202.028" cy="58.342" r="12.26"/></svg>'; var encoded = window.btoa(svg); document.body.style.background = "url(data:image/svg+xml;base64,"+encoded+")"; Fiddle Here
Base64 for that would be: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMjJweCIgaGVpZ2h0PSIzOHB4IiB2aWV3Qm94PSIwIDAgMjIgMzgiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDIyIDM4IiB4bWw6c3BhY2U9InByZXNlcnZlIj48c3R5bGU+LnN0eWxlMHtmaWxsOgkjZjQ3MjE2O308L3N0eWxlPjxwYXRoIGQ9Ik0yLjY0MyAzOGMtMC42NCAwLTEuMjgyLTAuMjMxLTEuNzktMC42OTljLTEuMDc0LTAuOTg4LTEuMTQzLTIuNjYxLTAuMTU0LTMuNzM1bDEzLjEzLTE0LjI1OEwwLjY2NCA0LjQgYy0wLjk2Ny0xLjA5NC0wLjg2NS0yLjc2NSAwLjIyOS0zLjczMnMyLjc2NS0wLjg2NCAzLjcgMC4yMjlMMTkuMzcgMTcuNTkyYzAuODk4IDEgMC45IDIuNTQ1LTAuMDM1IDMuNTQyTDQuNTg4IDM3LjEgQzQuMDY3IDM3LjcgMy40IDM4IDIuNiAzOHoiIGNsYXNzPSJzdHlsZTAiLz48L3N2Zz4='); using a tool like http://www.base64encode.org/ This doesn't answer your question directly, but it does let us do the following. We can now test to see if: .icon:hover .style0 { fill: red; } will work, or use .icon { background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMjJweCIgaGVpZ2h0PSIzOHB4IiB2aWV3Qm94PSIwIDAgMjIgMzgiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDIyIDM4IiB4bWw6c3BhY2U9InByZXNlcnZlIj48c3R5bGU+LnN0eWxlMHtmaWxsOgkjZjQ3MjE2O308L3N0eWxlPjxwYXRoIGQ9Ik0yLjY0MyAzOGMtMC42NCAwLTEuMjgyLTAuMjMxLTEuNzktMC42OTljLTEuMDc0LTAuOTg4LTEuMTQzLTIuNjYxLTAuMTU0LTMuNzM1bDEzLjEzLTE0LjI1OEwwLjY2NCA0LjQgYy0wLjk2Ny0xLjA5NC0wLjg2NS0yLjc2NSAwLjIyOS0zLjczMnMyLjc2NS0wLjg2NCAzLjcgMC4yMjlMMTkuMzcgMTcuNTkyYzAuODk4IDEgMC45IDIuNTQ1LTAuMDM1IDMuNTQyTDQuNTg4IDM3LjEgQzQuMDY3IDM3LjcgMy40IDM4IDIuNiAzOHoiIGNsYXNzPSJzdHlsZTAiLz48L3N2Zz4='); height: 40px; width: 40px; } .icon:hover { background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMjJweCIgaGVpZ2h0PSIzOHB4IiB2aWV3Qm94PSIwIDAgMjIgMzgiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDIyIDM4IiB4bWw6c3BhY2U9InByZXNlcnZlIj48c3R5bGU+LnN0eWxlMHtmaWxsOglyZWQ7fTwvc3R5bGU+PHBhdGggZD0iTTIuNjQzIDM4Yy0wLjY0IDAtMS4yODItMC4yMzEtMS43OS0wLjY5OWMtMS4wNzQtMC45ODgtMS4xNDMtMi42NjEtMC4xNTQtMy43MzVsMTMuMTMtMTQuMjU4TDAuNjY0IDQuNCBjLTAuOTY3LTEuMDk0LTAuODY1LTIuNzY1IDAuMjI5LTMuNzMyczIuNzY1LTAuODY0IDMuNyAwLjIyOUwxOS4zNyAxNy41OTJjMC44OTggMSAwLjkgMi41NDUtMC4wMzUgMy41NDJMNC41ODggMzcuMSBDNC4wNjcgMzcuNyAzLjQgMzggMi42IDM4eiIgY2xhc3M9InN0eWxlMCIvPjwvc3ZnPg=='); } which seems inefficient to me because we are forced to replicate a lot of the same information for the hover when all we want to change is the color. working example
I want to post an answer to my own question. No exactly an answer, since it doesn't imply svg as background and base64, but it's my current alternative way, much more effective if you just need mono-color icons: just use svg as css mask, and change background color. Then you can also apply transitions on mouse events. I mean something like this: mask-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" xml:space="preserve"><path d="M11.432 9.512a.636.636 0 0 1 0 .918L2.12 19.742a.636.636 0 0 1-.458.201.637.637 0 0 1-.46-.201l-1-.998C.068 18.609 0 18.459 0 18.285s.068-.329.199-.461l7.854-7.852L.199 2.118A.638.638 0 0 1 0 1.66c0-.174.068-.327.199-.46l1-.998A.634.634 0 0 1 1.66 0c.172 0 .325.068.458.201l9.314 9.311z"/></svg>'); mask-size: auto 12px; mask-repeat: no-repeat; transition: background-color 200ms; background-color: #ff0000; Please see this fiddle for come more code and demo: https://jsfiddle.net/o25beLqj/ Also note a couple of things: mask-image does not have base64 code inside. It's just preceeded by data:image/svg+xml;utf8, mask css properties are quite about the same of css background properties, take a look to docs, and you'll see you can do really a lot and they can substitute background images in a variety of use cases