How to Change Svg Color When It Is an Encoded CSS Background Image

How to modify the fill color of an SVG image when being served as background image?

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.

how to change svg fill color when used as base-64 background image data?

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

How can I change the color of an 'svg' element?

You can't change the color of an image that way. If you load SVG as an image, you can't change how it is displayed using CSS or JavaScript in the browser.

If you want to change your SVG image, you have to load it using <object>, <iframe> or using <svg> inline.

If you want to use the techniques in the page, you need the Modernizr library, where you can check for SVG support and conditionally display or not a fallback image. You can then inline your SVG and apply the styles you need.

See:

#time-3-icon {
fill: green;
}

.my-svg-alternate {
display: none;
}
.no-svg .my-svg-alternate {
display: block;
width: 100px;
height: 100px;
background-image: url(image.png);
}
<svg width="96px" height="96px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
<path id="time-3-icon" d="M256,50C142.229,50,50,142.229,50,256c0,113.77,92.229,206,206,206c113.77,0,206-92.23,206-206
C462,142.229,369.77,50,256,50z M256,417c-88.977,0-161-72.008-161-161c0-88.979,72.008-161,161-161c88.977,0,161,72.007,161,161
C417,344.977,344.992,417,256,417z M382.816,265.785c1.711,0.297,2.961,1.781,2.961,3.518v0.093c0,1.72-1.223,3.188-2.914,3.505
c-37.093,6.938-124.97,21.35-134.613,21.35c-13.808,0-25-11.192-25-25c0-9.832,14.79-104.675,21.618-143.081
c0.274-1.542,1.615-2.669,3.181-2.669h0.008c1.709,0,3.164,1.243,3.431,2.932l18.933,119.904L382.816,265.785z"/>
</svg>

<image class="my-svg-alternate" width="96" height="96" src="ppngfallback.png" />

How to change ::before SVG background-image color on hover, focus, active

The problem is that you are using SVG's data URI as a background image, meaning that its properties and styles cannot be modified—the SVG markup is not part of the DOM and therefore untouchable with CSS. It is akin to referencing a .svg image path in your background-image property.

The only solution is—as you have suspected—to simply encode a brand new SVG for the hover state:

.field {  width: 100px;  height: 100px;  display: flex;  justify-content: center;  align-items: center;  background-color: #849d8f;}
.field__search { width: 35px; height: 35px; background-color: rgba(255, 255, 255, 0.2); border-radius: 66px; position: relative;}
.field__search::before { content: ""; position: absolute; top: 8px; left: 8px; width: 22px; height: 22px; background-image: url("data:image/svg+xml;utf8, <svg xmlns='http://www.w3.org/2000/svg' width='16.687' height='16.688' viewBox='0 0 16.687 16.688'><path class='cls-1' d='M931.155,40.747H930.4l-0.264-.261a6.212,6.212,0,1,0-.675.675l0.263,0.262v0.755l4.773,4.76,1.423-1.422Zm-5.731,0a4.291,4.291,0,1,1,4.3-4.291A4.294,4.294,0,0,1,925.424,40.747Z' transform='translate(-919.219 -30.25)' fill='#fff' /></svg>"); background-repeat: no-repeat; background-position: 0 0; opacity: 1;}
.field__search:hover::before,.field__search:focus::before,.field__search:active::before { background-image: url("data:image/svg+xml;utf8, <svg xmlns='http://www.w3.org/2000/svg' width='16.687' height='16.688' viewBox='0 0 16.687 16.688'><path class='cls-1' d='M931.155,40.747H930.4l-0.264-.261a6.212,6.212,0,1,0-.675.675l0.263,0.262v0.755l4.773,4.76,1.423-1.422Zm-5.731,0a4.291,4.291,0,1,1,4.3-4.291A4.294,4.294,0,0,1,925.424,40.747Z' transform='translate(-919.219 -30.25)' fill='#000' /></svg>");}
<div class="field">  <div class="field__search"></div></div>

CSS background url SVG fill color not working (not base64) when compiling from SASS

In svg, # needs to be encoded, and replaced with %23.

So you need to create a function to do the replacement. I.E.:

@function url-encoded-color($color) {
@return '%23' + str-slice('#{$color}', 2, -1)
}

And then for svg, place it instead of variable directly:

   background: {
image: url('data:image/svg+xml;utf8, <svg xmlns="http://www.w3.org/2000/svg" width="2" height="1"><rect width="1" height="1" fill="#{url-encoded-color($body-color)}" /></svg>');
repeat: repeat;
}

Full example:
https://jsfiddle.net/niklaz/26Ljsmdu/3/

Change fill color of SVG image loaded via background-image

Edit it in an XML editor and if you know the color values, just change it.

Or, you can go to THIS LINK and make your edit.

Hope this helps.

Setting the fill color of base 64 encoded SVG on Image element?

You can base64 decode the image to svg markup, then amend it adding your style rule, base64 encode it again and set the src of the image to the new one.

I'm haven't tested it but can't see a reason why it wouldn't work.

SVG as a background-image in MIXIN setting color via a SASS variable

SVG as background image is supported by browsers. The mixin needs to url encode certain characters to create 'URL-safe' data. You are passing your color to this mixin but be careful with the character # and replace it with the url encoded version %23.

@function str-replace($string, $search, $replace: '') {
$index: str-index($string, $search);
@return if($index,
str-slice($string, 1, $index - 1) + $replace +
str-replace(str-slice($string, $index +
str-length($search)), $search, $replace),
$string);
}

@function hexToUrl($color) {
$newcolor: str-replace($color, '#', '%23');
@return $newcolor;
}
@mixin color($color) {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='#{hexToUrl($color)}'%3E%3C/svg%3E");
background-repeat: no-repeat;
}

.class{
@include color('#000');
}

This outputs:

.class {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23000'%3E%3C/svg%3E");
background-repeat: no-repeat;
}

I am using the information given in the question's link



Related Topics



Leave a reply



Submit