ChatGPT解决这个技术问题 Extra ChatGPT

How to change the color of an svg element?

I want to use this technique and change the SVG color, but so far I haven't been able to do so. I put this in the CSS, but my image is always black, no matter what.

My code:

.change-my-color { fill: green; }

I'm no svg expert, but have you tried changing fill to background-color?
@Megan in svg background-color is specified with the 'fill' property and the border with 'stroke' (as you would do in Illustrator). w3.org/TR/SVG/propidx.html
CSS from your HTML document will not apply to SVG elements within
This is possible now. Simple and functional answer here: stackoverflow.com/a/53336754/467240
Hi, you should probably change the acceepted answer (look at the most voted one).

M
Manish Menaria

2020 answer

CSS Filter works on all current browsers

To change any SVGs color

Add the SVG image using an tag.

<img src="dotted-arrow.svg" class="filter-green"/>

To filter to a specific color, use the following Codepen(Click Here to open codepen) to convert a hex color code to a CSS filter:

For example, output for #00EE00 is

filter: invert(42%) sepia(93%) saturate(1352%) hue-rotate(87deg) brightness(119%) contrast(119%);

Add the CSS filter into this class.

    .filter-green{
        filter: invert(48%) sepia(79%) saturate(2476%) hue-rotate(86deg) brightness(118%) contrast(119%);
    }

This comes with the usual caveat about not being supported in older browser versions: developer.mozilla.org/en-US/docs/Web/CSS/…
As noted in the CodePen, if your SVG isn't black (mine was grey), adding brightness(0) saturate(100%) to the beginning of the list of filters will first turn it 100% black, which enables the other filters to change it to the correct color.
Also, lots of fascinating background on the solution in this StackOverflow question that informed the CodePen.
My guy. The support seems acceptable caniuse.com/#feat=css-filters.
but how do you specify a particular color ?
S
Sushant Pachipulusu

To change the color of any SVG you can directly change the svg code by opening the svg file in any text editor. The code may look like the below code

<?xml version="1.0" encoding="utf-8"?>
    <!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
    <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
    <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">
    <g>
        <path d="M114.26,436.584L99.023,483h301.953l-15.237-46.416H114.26z M161.629,474.404h-49.592l9.594-29.225h69.223
            C181.113,454.921,171.371,464.663,161.629,474.404z"/>
    /*Some more code goes on*/
    </g>
    </svg>

You can observe that there are some XML tags like path, circle, polygon etc. There you can add your own color with help of style attribute. Look at the below example

<path fill="#AB7C94" d="M114.26,436.584L99.023,483h301.953l-15.237-46.416H114.26z M161.629,474.404h-49.592l9.594-29.225h69.223
                C181.113,454.921,171.371,464.663,161.629,474.404z"/>

Add the style attribute to all the tags so that you can get your SVG of your required color

Edit: As per Daniel's comment, we can use fill attribute directly instead of fill element inside style attribute


Why not just using attribute fill like this: fill = "#AB7C94" ? Not sure why the style attribute is needed
Hi Daniel, yeah it works. I didn't knew that fill can be used as an attribute. Sorry for not noticing your comment so long @bg17aw
you guys saved my day
This should be the best answer because it provides the same result which much less code. Less code, better code.
If you don't want to change the color of the svg programmatically, this is the best and easiest solution. Thank you!
u
user9342572809

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); }

You can inline your SVG, tag your fallback image with a class name (my-svg-alternate):

<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" .../>
</svg>

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

And in CSS use the no-svg class from Modernizr (CDN: http://ajax.aspnetcdn.com/ajax/modernizr/modernizr-2.7.2.js ) to check for SVG support. If there is no SVG support the SVG block will be ignored and the image will be displayed, otherwise the image will be removed from the DOM tree (display: none):

.my-svg-alternate {
  display: none;
}
.no-svg .my-svg-alternate {
  display: block;
  width: 100px;
  height: 100px;
  background-image: url(image.png);
}

Then you can change the color of your inlined element:

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

You cannot style embedded object SVGs from the hosting document.
@JavierRey you could inject the styling into the object tag's contents via javascript. But you're right that it does not apply if you just add it to the hosting document's stylesheet.
I'm using the solution from @manish-menaria and it works perfectly.
Accepted answer should be changed to: stackoverflow.com/a/53336754/467240
There is a way to do it, just give the svg fill="currentColor" property, than it will get color from CSS color assigned to it (font color). See this answer stackoverflow.com/a/65147574/8230784
R
Richard Thiessen

if you want to change the color dynamically:

Open the SVG in a code editor Add or rewrite the attribute of fill of every path to fill="currentColor" Now, that svg will take the color of your font color so you can do something like:

svg {
    color : "red";
}

This is the real and the easiest answer.
This is how icons (SVGs) from font-awesome do it. Works great.
Also you may have to change stroke attributes to stroke="currentColor".
It doesn't work if SVG is saved as a file and displayed with <img> tag.
How are you including the SVG, inline or using an img tag? Please include in your answer.
s
sunkehappy

Only SVG with path information. you can't do that to the image.. as the path you can change stroke and fill information and you are done. like Illustrator

so: via CSS you can overwrite path fill value

path { fill: orange; }

but if you want more flexible way as you want to change it with a text when having some hovering effect going on.. use

path { fill: currentColor; }

body { background: #ddd; text-align: center; padding-top: 2em; } .parent { width: 320px; height: 50px; display: block; transition: all 0.3s; cursor: pointer; padding: 12px; box-sizing: border-box; } /*** desired colors for children ***/ .parent{ color: #000; background: #def; } .parent:hover{ color: #fff; background: #85c1fc; } .parent span{ font-size: 18px; margin-right: 8px; font-weight: bold; font-family: 'Helvetica'; line-height: 26px; vertical-align: top; } .parent svg{ max-height: 26px; width: auto; display: inline; } /**** magic trick *****/ .parent svg path{ fill: currentcolor; }

TEXT WITH SVG


Y
Yonatan Ayalon

Added a test page - to color SVG via Filter settings:

E.G filter: invert(0.5) sepia(1) saturate(5) hue-rotate(175deg)

Upload & Color your SVG - Jsfiddle

Took the idea from: https://blog.union.io/code/2017/08/10/img-svg-fill/


Thanks, you just save me from myself. .custom-disabled > svg {filter:invert(0.2) sepia(1) saturte(0) hue-rotate(0);} did just the job I need to disabled icon.
B
Ben Carp

Solutions 1 - Edit SVG to point to the currentColor

<svg>... fill: currentColor stroke: currentColor ...</svg>

Then you can control the color of the stroke and the fill from your css

svg {
  color: blue; // or any color of your choice.
}

Pros and cons:

Simple and uses conventional supported css.

Suitable if:

You control the SVG

SVG can be included inline in the HTML.

Solution 2 - css mask property

<i class="icon"></i>
.icon {
  -webkit-mask-size: cover;
  mask-size: cover;
  -webkit-mask-image: url(https://url.of.svg/....svg);
  mask-image: url(https://url.of.svg/....svg);
  background-color: blue; // or any color of your choice.
  width: 20px; 
  height: 20px; 
}
}

Pros and cons

Relatively easy to use

Browser support for the mask css property is partial.

Suitable if:

SVG is external, and included via URL

Meant to be used on modern known browsers.

Solution 3 - css Filter property - static color

If the color is known in advance you can use https://codepen.io/sosuke/pen/Pjoqqp to find the filter needed to change your SVG to the desired color. For example, to convert the svg to #00f:

<img src="https://url.of.svg/....svg" class="icon">
.icon {
    filter: invert(8%) sepia(100%) saturate(6481%) hue-rotate(246deg) brightness(102%) contrast(143%); 
}

if your original color isn't black prefix the list of filters with brightness(0) saturate(100%) to convert it first to black.

Pros and cons:

There might be a small, non significant difference between the result and the desired color.

Suitable if:

Desired color is known in advance.

External image


On Solution 3 pros and cons; it might be worth adding that using multiple filters on complex SVG images have a huge negative impact on performance. And should be used sparingly if at all.
v
vsync

SVG mask on a box element with a background color will result:

body{ overflow:hidden; } .icon { --size: 70px; display: inline-block; width: var(--size); height: var(--size); transition: .12s; -webkit-mask-size: cover; mask-size: cover; } .icon-bike { background: black; animation: 4s frames infinite linear; -webkit-mask-image: url(https://image.flaticon.com/icons/svg/89/89139.svg); mask-image: url(https://image.flaticon.com/icons/svg/89/89139.svg); } @keyframes frames { 0% { transform:translatex(100vw) } 25% { background: red; } 75% { background: lime; } 100% { transform:translatex(-100%) } }

Note - SVG masks are not supported in Internet Explorer browsers


Thanks a lot, @vsync this is just the best hack around for what I need.
F
Felix Hagspiel

the easiest way would be to create a font out of the SVG using a service like https://icomoon.io/app/#/select or such. upload your SVG, click "generate font", include font files and css into your side and just use and style it like any other text. I always use it like this because it makes styling much easier.

EDIT: As mentioned in the article commented by @CodeMouse92 icon fonts mess up screen readers (and are possibly bad for SEO). So rather stick to the SVGs.


It also messes up screen readers. See "Death to Icon Fonts" by Seren Davies
w
warfish

You can try to color it with this css filter hack:

.colorize-pink {
  filter: brightness(0.5) sepia(1) hue-rotate(-70deg) saturate(5);
}

.colorize-navy {
  filter: brightness(0.2) sepia(1) hue-rotate(180deg) saturate(5);
}

.colorize-blue {
  filter: brightness(0.5) sepia(1) hue-rotate(140deg) saturate(6);
}

S
Sethu Sathyan

To simply change the color of the svg :

Go to the svg file and under styles, mention the color in fill.

<style>.cls-1{fill:#FFFFFF;}</style>

Already suggested by this answer
M
Michael Philips

Target the path within the svg:

<svg>
   <path>....
</svg>

You can do inline, like:

<path fill="#ccc">

Or

svg{
   path{
        fill: #ccc

S
Sarang Kakkoth

To change color of SVG element I have found out a way while inspecting Google search box search icon below:

.search_icon { color: red; fill: currentColor; display: inline-block; width: 100px; height: 100px; }

I have used span element with "display:inline-block", height, width and setting a particular style "color: red; fill: currentColor;" to that span tag which is inherited by the child svg element.


This was the best answer. Wrapping the svg in a span or div and applying fill: currentColor; to it is the key.
c
cydoc

You can change SVG coloring with css if you use some tricks. I wrote a small script for that.

go through a list of elements which do have an svg image

load the svg file as xml

fetch only svg part

change color of path

replace src with the modified svg as inline image

$('img.svg-changeable').each(function () {
  var $e = $(this);
  var imgURL = $e.prop('src');

  $.get(imgURL, function (data) {
    // Get the SVG tag, ignore the rest
    var $svg = $(data).find('svg');

    // change the color
    $svg.find('path').attr('fill', '#000');

    $e.prop('src', "data:image/svg+xml;base64," + window.btoa($svg.prop('outerHTML')));
  });

});

the code above might not be working correctly, I've implemented this for elements with an svg background image which works nearly similar to this. But anyway you have to modify this script to fit your case. hope it helped.


By the way: If you are a RoR developer, you can add a new method for the sass precompiler which can do the job too. This is much better because you will have the base64 encoded, correct colored image in your compiled css file. No JS needed anymore! Maybe I could provide the code I have written, have to talk to the CTO.
+1 for providing a solution, rather than saying it can't be done. This answer is also relevant: stackoverflow.com/questions/11978995/…
A
Ali Besharati

here the fast&furious way :)

body{ background-color: #deff05; } svg{ width: 30%; height: auto; } svg path { color:red; fill: currentcolor; }


why vote down !? this work well you can see it in the demo
Your answer explains nothing in contrast with others: stackoverflow.com/a/20720935/3795597 stackoverflow.com/a/30419873/3795597 stackoverflow.com/a/69397734/3795597 and countless others. It only works because you embed the svg in the main document.
V
Venteens Productions

A simple way to change SVG image color is using a filter property.

Filter Generator here

Original SVG:

Filtered SVG:

.change-my-color { filter: invert(21%) sepia(100%) saturate(3618%) hue-rotate(102deg) brightness(96%) contrast(108%); } .change-my-color2 { filter: invert(90%) sepia(93%) saturate(636%) hue-rotate(338deg) brightness(112%) contrast(102%); } .change-my-color3 { filter: invert(71%) sepia(98%) saturate(1284%) hue-rotate(164deg) brightness(100%) contrast(103%); } .change-my-color4 { filter: invert(23%) sepia(99%) saturate(2151%) hue-rotate(258deg) brightness(100%) contrast(112%); }


K
Kristiyan Tsvetanov

Found this useful codepen. It asks for a color and generates an appropriate css filter that achieves your color.

For example:

filter: 'invert(48%) sepia(75%) saturate(1969%) hue-rotate(213deg) brightness(97%) contrast(87%)',

F
Flimm

For Example, in your HTML:

<body>
  <svg viewBox="" width="" height="">
    <path id="struct1" fill="#xxxxxx" d="M203.3,71.6c-.........."></path>
  </svg>
</body>

Use jQuery:

$("#struct1").css("fill","<desired colour>");

This only works if you include the SVG file inline in the HTML. I've edited your answer to make this clear.
M
MD SHAYON

Method 1

The easy and effect way

open your .svg file with any text editor

<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" 
   xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
   viewBox="0 0 477.526 477.526" style="enable-background:new 0 0 477.526 477.526; 
   fill: rgb(109, 248, 248);" xml:space="preserve"> 
<svg />

give an style attribute and fill that with color

Another way

fill with color in your shape here i have rect shape fill="white

<svg width="800" height="600" xmlns="http://www.w3.org/2000/svg">
      <g>
          <title>background</title>
          <rect fill="#fff" id="canvas_background" height="602" width="802" y="-1" 
           x="-1"/>
           <g display="none" overflow="visible" y="0" x="0" height="100%" width="100%" 
           id="canvasGrid">
              <rect fill="url(#gridpattern)" stroke-width="0" y="0" x="0" height="100%" 
              width="100%"/>
           </g>
       </g>
</svg>

D
Danny '365CSI' Engelman

2022 Web Component answer

docs: https://dev.to/dannyengelman/load-file-web-component-add-external-content-to-the-dom-1nd

customElements.define("load-file", class extends HTMLElement { // declare default connectedCallback as sync so await can be used async connectedCallback( // call connectedCallback with parameter to *replace* SVG (of persists) src = this.getAttribute("src"), // attach a shadowRoot if none exists (prevents displaying error when moving Nodes) // declare as parameter to save 4 Bytes: 'let ' shadowRoot = this.shadowRoot || this.attachShadow({mode:"open"}) ) { // load SVG file from src="" async, parse to text, add to shadowRoot.innerHTML shadowRoot.innerHTML = await (await fetch(src)).text() // append optional Elements from inside after parsed shadowRoot.append(...this.querySelectorAll("[shadowRoot]")) // if "replaceWith" attribute // then replace with loaded content // childNodes instead of children to include #textNodes also this.hasAttribute("replaceWith") && this.replaceWith(...shadowRoot.childNodes) } })


Wow this is quick, easy and has zero implementation problems (in comparison to other solutions, given my project characteristics).
O
OXiGEN

If the same SVG must be used multiple times with different colors, define the set of paths within a hidden SVG which serves as the master copy. Then place new instances which refer to the master path with their individual fills.

Note: This approach only works with inline <svg> tags. It will not work with <img> tags loading .svg files.

:root { fill: gray; } .hidden { display: none; } svg { width: 1em; height: 1em; }


P
Peter Kionga-Kamau

If you want to do this to an inline svg that is, for example, a background image in your css:

background: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='rgba(31,159,215,1)' viewBox='...'/%3E%3C/svg%3E");

of course, replace the ... with your inline image code


J
JamieGL

Use an svg <mask> element.

This is better than other solutions because:

Closely matches your original code.

Works in IE!

The embedded image can still be an external, unmodified file.

The image does not even have to be an SVG.

Color is inherited from font-color, so easy to use alongside text.

Color is a normal CSS color, not a strange combination of filters.

https://jsfiddle.net/jamiegl/5jaL0s1t/19/


Works great! Note to add: the svg should be white.
M
Mahdi Khansari

You can use font icon to use any CSS option on SVG

I was searching for a way to have any CSS options like animation for SVG, and I ended up to generate a font icon with my SVG(s) and then use it inside a span (like FontAwesome), So any CSS option like coloring is available on it.

I used https://icomoon.io to convert my SVG to font icon. Then you can use it like FontAwesome or MaterialIcon inside HTML elements.


P
Petr Tripolsky

Actually, there is a quite more flexible solution to this problem: writing a Web Component which will patch SVG as text in runtime. Also published in gist with a link to JSFiddle

👍 filter: invert(42%) sepia(93%) saturate(1352%) hue-rotate(87deg) brightness(119%) contrast(119%);

<html>

<head>
  <title>SVG with color</title>
</head>

<body>
  <script>
    (function () {
      const createSvg = (color = '#ff9933') => `
          <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="76px" height="22px" viewBox="-0.5 -0.5 76 22">
            <defs/>
              <g>
                <ellipse cx="5" cy="10" rx="5" ry="5" fill="#ff9933" stroke="none" pointer-events="all"/>
                <ellipse cx="70" cy="10" rx="5" ry="5" fill="#ff9933" stroke="none" pointer-events="all"/>
                <path d="M 9.47 12.24 L 17.24 16.12 Q 25 20 30 13 L 32.5 9.5 Q 35 6 40 9 L 42.5 10.5 Q 45 12 50 6 L 52.5 3 Q 55 0 60.73 3.23 L 66.46 6.46" fill="none" stroke="#ff9933" stroke-miterlimit="10" pointer-events="stroke"/>
              </g>
          </svg>`.split('#ff9933').join(color);

      function SvgWithColor() {
        const div = Reflect.construct(HTMLElement, [], SvgWithColor);
        const color = div.hasAttribute('color') ? div.getAttribute('color') : 'cyan';
        div.innerHTML = createSvg(color);
        return div;
      }

      SvgWithColor.prototype = Object.create(HTMLElement.prototype);
      customElements.define('svg-with-color', SvgWithColor);

      document.body.innerHTML += `<svg-with-color
        color='magenta' 
      ></svg-with-color>`;

    })();

  </script>
</body>

</html>

S
Shabeer M

There are some problem with @Manish Menaria answer, if we convert white color it shows gray.

so added some tweaks, below example specifically shows how to change color in material icon

<mat-icon class="draft-white" svgIcon="draft" aria-hidden="false"></mat-icon>


.draft-white{
    filter: brightness(0) invert(1);
}

o
omarjebari

A good approach is to use a mixin to control stroke colour and fill colour. My svgs are used as icons.

@mixin icon($color, $hoverColor) {
    svg {
        fill: $color;

        circle, line, path {
            fill: $color
        }

        &:hover {
            fill: $hoverColor;

            circle, line, path {
                fill: $hoverColor;
            }
        }
    }
}

You can then do the following in your scss:

.container {
    @include icon(white, blue);
}

P
Prottay

If you want to use css to change the colour, you could also use an online tool like this one: https://change-svg-color.vercel.app/


That answer is uninformative, it doesn't explain how to do it, nor that it's an svg filter. It would be better to comment on the top-voted answer and provide a link to that tool, which is an alternative to the codepen.
C
Chester Fung

You shall not set the color directly on the svg image, if you want to program the color of the svg.

In 2021, you can use the following css to make the color change.

html{ --iron-icon-fill-color-1:green; --iron-icon-fill-color-2:red; --iron-icon-stroke-color:white; } svg#icon-green{ fill: var(--iron-icon-fill-color-1, currentcolor); stroke: var(--iron-icon-stroke-color, none); } svg#icon-red{ fill: var(--iron-icon-fill-color-2, currentcolor); stroke: var(--iron-icon-stroke-color, none); } svg#icon{ fill: var(--iron-icon-fill-color-x, currentcolor); stroke: white; }


You do not explain why. What you are doing is simply inlining the svg to be part of the main DOM.
W
Wolfrevok Cats

shortest Bootstrap-compatible way, no JavaScript:

.cameraicon {
height: 1.6em;/* set your own icon size */
mask: url(/camera.svg); /* path to your image */
-webkit-mask: url(/camera.svg) no-repeat center;
}

and use it like:

<td class="text-center">
    <div class="bg-secondary cameraicon"/><!-- "bg-secondary" sets actual color of your icon -->
</td>