Barbara
Barbara

Reputation: 14756

How can I 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 use this in the CSS, but my image is always black, no matter what.

My code:

.change-my-color {
  fill: green;
}
<svg>
    <image class="change-my-color" xlink:href="https://svgur.com/i/AFM.svg" width="96" height="96" src="ppngfallback.png" />
</svg>

Upvotes: 1319

Views: 3268347

Answers (30)

Lev Lukomskyi
Lev Lukomskyi

Reputation: 6667

Not ideal, but I think the best way is to – use currentColor + SVG/use.

  1. You have to prepare your SVG file – change ordinary SVG markup:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
  <path stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
        d="m14 10 7-7m0 0h-4.5M21 3v4.5M10 14l-7 7m0 0h4.5M3 21v-4.5"/>
</svg>

into this:

<svg style="display:none" xmlns="http://www.w3.org/2000/svg"><symbol id="main" viewBox="0 0 24 24">
  <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
        d="m14 10 7-7m0 0h-4.5M21 3v4.5M10 14l-7 7m0 0h4.5M3 21v-4.5"/>
</symbol></svg>

Here a <symbol id="main"> tag is added and content of the original SVG is copied into it, and also viewBox attribute is moved from svg to symbol tag.

  1. Use the image on a web page this way:
<svg width="24" height="24" class="expand-icon"><use href="/expand.svg#main"></use></svg>

Here svg tag is used and use tag includes image path with #main hash.

  1. You can control the color dynamically via css color, eg:
svg { color: olive }
svg:hover { color: brown }

Only paths with stroke="currentColor" or fill="currentColor" will change the color.

Why this approach?

  1. SVG is served to user as a separate file and can be cached (unlike the approach with inlined svg – what if your page has dozens of the same images?)

  2. Changing color is just changing the usual css color value (unlike the approach with filters)

Note 1 – the approach with svg/symbol was used in the past for SVG-sprites, which is not longer a modern approach since HTTP2 is out and removed the need for sprites.

Note 2 – yes, you have to prepare each svg which needs dynamic color which takes time, and also these prepared svg files are no longer previewed in file manager or IDE, that's why this approach is not ideal. Nevertheless imho it's better than others.

Upvotes: 3

M&#225;rtin Alcal&#225;
M&#225;rtin Alcal&#225;

Reputation: 5833

If you want to change the color dynamically:

  1. Open the SVG in a code editor

  2. Add or rewrite the attribute of fill of every path to fill="currentColor"

  3. Now, that svg will take the color of your font color, so you can do something like:

    svg {
        color : "red";
    }
    

Note: this will only work if the SVG is inlined in HTML.

Upvotes: 561

dieppa
dieppa

Reputation: 190

Try adding this script to your header:

<script src="https://unpkg.com/[email protected]/index.js"></script>

Then you can add your SVG like this:

<div height="64" width="64" src="[svg url]" class="fsvg" style="fill: red;"></div>

Replace the [svg url]

And this is it. Hope it helps.

You can check the script code here.

Upvotes: -3

Peter Kionga-Kamau
Peter Kionga-Kamau

Reputation: 7057

If you want to do this to an inline SVG file, that is, for example, a background image in your CSS content:

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.

Upvotes: 3

Sergey
Sergey

Reputation: 1193

React version of this solution, "Solution 2 - CSS mask property," described in this answer: https://stackoverflow.com/a/68695062/320427.

So, if you are using React and you are loading your icon from an external source, for example, https://example.com/icons/star.svg, and you want to change the color of the icon via CSS color property, e.g.

{
   color: red;
}

In this case, create a component similar to this one:

export function Icon({
  src,
  alt,
  width,
  height,
  className,
}: {
  src: string;
  alt: string;
  width: number;
  height: number;
  className?: string;
}) {
  const cssProperties = {
    maskImage: `url(${src})`,
    maskSize: 'contain',
    maskRepeat: 'no-repeat',
    maskPosition: 'center',
    backgroundColor: 'currentColor',
    width: `${width}px`,
    height: `${height}px`,
  };

  return <i className={className} style={cssProperties} aria-label={alt} />;
}

After that, you can use it this way:

<Icon height={32} width={32} src="https://example.com/icons/star.svg" style="color:red" alt="Star"/>

Upvotes: -1

vsync
vsync

Reputation: 130055

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-lightning {
  --lightning-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' %3E%3Cpath fill-rule='evenodd' d='M14.615 1.595a.75.75 0 0 1 .359.852L12.982 9.75h7.268a.75.75 0 0 1 .548 1.262l-10.5 11.25a.75.75 0 0 1-1.272-.71l1.992-7.302H3.75a.75.75 0 0 1-.548-1.262l10.5-11.25a.75.75 0 0 1 .913-.143Z' /%3E%3C/svg%3E");

  background: black;
  animation: 2s frames infinite linear;
  
  -webkit-mask-image:var(--lightning-mask);
  mask-image:var(--lightning-mask);
}

@keyframes frames { 
  25% { background: cyan; }
  75% { background: gold; }
}
<i class="icon icon-lightning" style="--size:150px"></i>


Note - SVG masks are not supported in Internet Explorer browsers

Upvotes: 37

Mehdi
Mehdi

Reputation: 13

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Change SVG Color</title>
  <style>
    #svgContainer {
      display: flex;
      justify-content: center;
      align-items: center;
      margin-top: 50px;
    }

    #svgIcon {
      width: 100px;
      height: 100px;
    }

    #colorBtn {
      margin-top: 20px;
      padding: 10px 20px;
      font-size: 16px;
      cursor: pointer;
    }
  </style>
</head>
<body>
  <div id="svgContainer">
    <!-- SVG icon -->
    <svg id="svgIcon" fill="#000000" viewBox="0 0 36 36" version="1.1" xmlns="http://www.w3.org/2000/svg">
      <title>auto-solid</title>
      <path class="svg-path" d="M26.87,14.28A22.36,22.36,0,0,0,19.65,6.9a9.64,9.64,0,0,0-9-.7,8.6,8.6,0,0,0-4.82,6.4c-.08.49-.15,1-.21,1.4h-1A2.59,2.59,0,0,0,2,16.59v8.55a.86.86,0,0,0,.86.86H4.59c0-.13,0-.26,0-.39a5.77,5.77,0,0,1,7.71-5.45l-1,1a4.56,4.56,0,0,0-4.34,1.58,3,3,0,0,0-.63.93A4.5,4.5,0,1,0,14.82,26h5.48c0-.13,0-.26,0-.39A5.77,5.77,0,0,1,28,20.16l-1,1a4.56,4.56,0,0,0-4.34,1.58,3,3,0,0,0-.63.93A4.5,4.5,0,1,0,30.53,26h2.61a.86.86,0,0,0,.86-.86V23.36A9.39,9.39,0,0,0,26.87,14.28ZM12,14H8c0-.35.1-.71.16-1.07a6.52,6.52,0,0,1,3.87-5h0ZM10.36,28.36a2.5,2.5,0,1,1,2.5-2.5A2.5,2.5,0,0,1,10.36,28.36ZM19,19H16V17h3Zm-6-5V7.47a8.16,8.16,0,0,1,5.4,1.15A19.15,19.15,0,0,1,24,14ZM26.06,28.36a2.5,2.5,0,1,1,2.5-2.5A2.5,2.5,0,0,1,26.06,28.36Z"/>
    </svg>
  </div>
  <button id="colorBtn">Change Color</button>

  <script>
    document.getElementById('colorBtn').addEventListener('click', function() {
  // Get all path elements inside the SVG
  var paths = document.querySelectorAll('#svgIcon path');

  // Generate a random color
  var randomColor = '#' + Math.floor(Math.random()*16777215).toString(16);

  // Change the fill color of each path
  paths.forEach(function(path) {
    path.setAttribute('fill', randomColor);
  });
});

  </script>
</body>
</html>

Upvotes: -2

Mahdi Khansari
Mahdi Khansari

Reputation: 435

You can use a font icon to use any CSS option in SVG

I was searching for a way to have any CSS options, like animation for SVG, and I ended up generating a font icon with my SVG(s) and then using it inside a span (like Font Awesome), so any CSS option, like coloring, was available on it.

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

Upvotes: 0

Fletcher Johns
Fletcher Johns

Reputation: 1274

I have a solution that I think solves this problem, even though it doesn't use an <img> tag, it does allow referring to a single .svg file in multiple places allowing for different colors to be directly applied using hex codes. I felt this was the right place to put my answer since this is one of the first results when searching for changing the color of an SVG, and finding this solution is quite difficult.

The first step is to make sure your SVG is formatted correctly with dimensions and viewBox as you expect it to be. I was puzzled by the viewBox in the exported SVG having different dimensions until I set the Scale value to 1 making the exported SVG 16x16 like the Inkscape SVG I'd been working on.

Set document properties correctly

Next, build your icons if you haven't already. You can put them all next to each other on the page, but this requires repositioning later when referencing them in HTML. I prefer to put all my icons together on the same 16x16 page. You can hide the ones you're not working on on the "layers" tab. Either group all parts of an icon, or combine them using "union" to give it a label and an id. Note that "menu" is a group of 3 paths and "close" is a single path. Either way will work. ("grid" is a guide I use to design the icons and is removed from the final file).

Organise your icons in the layers tab

Right-click on the icon in the layers tab, whether it's a group or a single path, and go to Object Properties. There you can give it a label and ID.

Ensure each icon has an id

Now export it as a Plain SVG and put it in your chosen location. It will require one further modification in a text editor to replace all fill and stroke colors with "currentColor."

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg
    width="16"
    height="16"
    viewBox="0 0 16 16"
    version="1.1"
    id="svg19528"
    xml:space="preserve"
    xmlns="http://www.w3.org/2000/svg"
    xmlns:svg="http://www.w3.org/2000/svg">
<defs id="defs19525" />
<g id="layer1">
    <g
            id="menu"
            style="display:inline">
        <path
                style="opacity:1;fill:none;fill-opacity:1;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
                d="M 3,3 H 13"
                id="path20582" />
        <path
                style="opacity:1;fill:none;fill-opacity:1;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
                d="M 3,8 H 13"
                id="path20584" />
        <path
                style="opacity:1;fill:none;fill-opacity:1;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
                d="M 3,13 H 13"
                id="path20586" />
    </g>
    <path
            id="close"
            style="color:currentColor;display:inline;fill:currentColor;stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none;paint-order:fill markers stroke"
            d="m 3,2 a 1,1 0 0 0 -0.7070312,0.2929688 1,1 0 0 0 0,1.4140624 L 6.5859375,8 2.2929688,12.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 L 8,9.4140625 12.292969,13.707031 a 1,1 0 0 0 1.414062,0 1,1 0 0 0 0,-1.414062 L 9.4140625,8 13.707031,3.7070312 a 1,1 0 0 0 0,-1.4140624 A 1,1 0 0 0 13,2 1,1 0 0 0 12.292969,2.2929688 L 8,6.5859375 3.7070312,2.2929688 A 1,1 0 0 0 3,2 Z" />
</g>
</svg>

Now the SVG can be added in HTML with a <use> tag. The icon can be repositioned if it is not at the top-left of the SVG by setting the x and y attributes of the <use> tag:

<svg width="64" height="64" viewBox="0 0 16 16"
         xmlns="http://www.w3.org/2000/svg">
        <use class="my-icon"
             xlink:href="/images/icons.svg#menu"></use>
    </svg>
    <svg width="128" height="128" viewBox="0 0 16 16"
        xmlns="http://www.w3.org/2000/svg">
        <use class="my-other-icon"
             xlink:href="/images/icons.svg#close"></use>
    </svg>

Styles can be added in CSS like this:

.my-icon {
    color: #fe8721ff;
}
.my-other-icon {
    color: #1278efff;
}

This way, the .svg file is only sent to the client once and all icons are loaded from it, allowing it to set different sizes and colors easily.

Upvotes: 0

Afroz Quraishi
Afroz Quraishi

Reputation: 159

If you are using Reactjs project. You can use the below approach.

import React from 'react';

type PropsType = {
  colorprimary: string;
  onClick: () => void;
  className: string;
  height?: string;
  width?: string;
};

const HamburgerIcon: React.FC<PropsType> = (props) => {
  const { colorprimary } = props;

  return (
    <svg viewBox='0 0 19 15' fill='none' xmlns='http://www.w3.org/2000/svg' {...props}>
      <g id='Group 2603'>
        <path
          id='Path 2244'
          fillRule='evenodd'
          clipRule='evenodd'
          d='M0.451172 1.49133H18.3634V0H0.451172V1.49133Z'
          fill={colorprimary}
        />
        <path
          id='Path 2245'
          fillRule='evenodd'
          clipRule='evenodd'
          d='M0.451172 8.20227H18.3634V6.71094H0.451172V8.20227Z'
          fill={colorprimary}
        />
        <path
          id='Path 2246'
          fillRule='evenodd'
          clipRule='evenodd'
          d='M0.451172 14.9132H18.3634V13.4219H0.451172V14.9132Z'
          fill={colorprimary}
        />
      </g>
    </svg>
  );
};

HamburgerIcon.defaultProps = {
  width: '25',
  height: '20',
};
export default HamburgerIcon;

Ignore types if you are not using typescript. Above solution provide more customisation to SVG, even you can add more props to make it more customisable.

here are the benefits of the provided approach:

  1. Reusability: You can use the SVG icon component throughout your application.
  2. Customization: Easily change the icon's color, width, and height using props.
  3. Maintainability: Centralized location for icon code simplifies updates.
  4. Consistency: Ensures a uniform appearance for all instances of the icon.
  5. Scalability: Manage numerous icons neatly as separate components.
  6. Readability: Improved code readability compared to inline SVG

Upvotes: 0

Code Drop
Code Drop

Reputation: 105

I got the same problem using SVG elements with path as child in Styled-Component, selecting the child solve my problem with dynamic colors:

import { styled, css } from 'styled-component';

export const Icon = styled.svg(({ theme }) => {
  const {
    colorsValues,
  } = theme.myCustomizationObj;

  return css`
    // select the path under "svg" element
    & path {
      fill: ${colorsValue};
    }
  `;
});

Upvotes: 0

Manish Menaria
Manish Menaria

Reputation: 27381

2020 answer

CSS Filter works on all current browsers

To change any SVGs color

  1. Add the SVG image using an <img> tag.

    <img src="dotted-arrow.svg" class="filter-green"/>
    
  2. To filter to a specific color, use the following Codepen (click here to open the codepen) to convert a hexadecimal 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%);
    

    Generate a filter for any color here.

  3. Add the CSS filter into this class.

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

Upvotes: 1667

cr7 aj7
cr7 aj7

Reputation: 99

Works in Chrome last checked on August 2023

Just add a div with a class

<div class="icon"></div>

Then add this style to it

    .icon {
    -webkit-mask: url(SVG.svg);/*Your SVG file here*/
    mask: url(SVG.svg) ;
    background-color: blue; /* Or any color of your choice. */
    width: 200px !important;
    height: 200px !important;
   }

Upvotes: -2

2022 Web Component <load-file> answer

This (7 line) native Web Component (JSWC) loads external content, and injects it into the DOM.

It is explained and documented in my DEV blog post: <load-file> Web Component.

Full source code:

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 <load-file> 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 <tag [shadowRoot]> Elements from inside <load-svg> after parsed <svg>
    shadowRoot.append(...this.querySelectorAll("[shadowRoot]"))

    // if "replaceWith" attribute
    // then replace <load-svg> with loaded content <load-svg>
    // childNodes instead of children to include #textNodes also
    this.hasAttribute("replaceWith") && this.replaceWith(...shadowRoot.childNodes)
  }
})
<load-file src="//load-file.github.io/heart.svg">
  <!-- elements inside load-file are MOVED to shadowDOM -->
  <style shadowRoot>
    svg {
      height: 180px; /* Stack Overflow subwindow height */
    }
    path:nth-child(2n+2) {
      fill: GREEN; /* shadowDOM style does NOT style global DOM */
    }
  </style>
</load-file>

Upvotes: 12

NothingToSeeHere
NothingToSeeHere

Reputation: 127

I've found that Inkscape works really well. Unless you need an SVG in several colors, just make on in the color you need and use it.

After loading the image, select each path, change the color, save as a new SVG image.

Upvotes: 0

Tauseef Arshad
Tauseef Arshad

Reputation: 769

if you are using svg with path then give fill color to path:

    svg path{
fill:red;
}

Upvotes: 3

Kabeer
Kabeer

Reputation: 115

You can change the svg color using fill attribute

<svg xmlns="http://www.w3.org/2000/svg" width="0" height="0" fill="#colorcode">
    Your svg path here
</svg>

Check demo here

Upvotes: -3

Jeremy
Jeremy

Reputation: 1568

This took a while for me to workout, you can't change the colour of an imported svg (easily), how i managed to do and keep themes / colours from createStyles in my react application is like so:

<MURadio
  icon={
    <svg
      width="24px"
      height="24px"
      viewBox="0 0 24 24"
      version="1.1"
      xmlns="http://www.w3.org/2000/svg"
      style={{
        fillRule: "evenodd",
        clipRule: "evenodd",
        strokeLinejoin: "round",
        strokeMiterlimit: "2",
      }}
    >
      <g transform="matrix(1,0,0,1,-511.714,-525.038)">
        <g transform="matrix(1.04348,0,0,1.04348,511.192,523.902)">
          <circle cx="12" cy="12.589" r="11.5" style={{ fill: "white" }} />
          <path
            d="M12,1.089C18.347,1.089 23.5,6.242 23.5,12.589C23.5,18.936 18.347,24.089 12,24.089C5.653,24.089 0.5,18.936 0.5,12.589C0.5,6.242 5.653,1.089 12,1.089ZM12,2.089C6.205,2.089 1.5,6.794 1.5,12.589C1.5,18.384 6.205,23.089 12,23.089C17.795,23.089 22.5,18.384 22.5,12.589C22.5,6.794 17.795,2.089 12,2.089Z"
            className={classes.icon}
          />
        </g>
      </g>
    </svg>
  }
/>;
const useRadioButtonClasses = makeStyles<ITheme, IRadioButtonErrorProps>(
  (theme) =>
    createStyles({
      radio: { color: theme.mvf.palette.border },
      card: {
        height: '100%',
      },
      icon: ({ isError }) => ({
        fill: theme.mvf.palette.border,
        ...(isError && {
          fill: theme.mvf.palette.error,
        }),
      }),
      selectedRadioIcon: ({ isError }) => ({
        fill: theme.mvf.palette.primary.main,
        ...(isError && {
          fill: theme.mvf.palette.error,
        }),
      }),
...etc

I am assuming some level of knowledge, as this isn't full code, but MURadio is an v4 material ui radio button in use in our app, with the custom svg in one of the props by this material ui component - so you have change the default radio icon... and you can apply a theme colour to the custom radio icon (svg) dynamically, and as i am passing isError state like so const classes = useRadioButtonClasses({ isError }); so we can change the svg colour if there is an error.

Works for me and same setup (class.icon) as we style the regular components, hope it helps you.

Upvotes: 1

Bene Laci
Bene Laci

Reputation: 112

I found it a bit clumsy, but it is definitely a working way to dynamically change the color of an SVG included with <img> tag.

In the SVG file, you can add CSS content the following way:

<svg ...>
    <defs>
        <style>
            ...
        <style>
    <defs>

There you can use @media rules, with which the SVG can look outside itself for contextual circumstances. There's an aspect-ratio media feature that applies to the SVG box (e.g., the <img> tag). You can create different contexts for the SVG by stretching the SVG box a little bit.

This way you can also make the favicon the same SVG that appears on the website, but with a different color. (In this case, no other SVG boxes should be square-shaped.)

/* img stretched horizontally (if SVG is square-shaped) */
@media (min-aspect-ratio: 1000/999) {
    path {
        fill: blue;
    }
}

/* img stretched vertically (if SVG is square-shaped) */
@media (max-aspect-ratio: 999/1000) {
    path {
        fill: green;
    }
}

/* img with exact sizes */
@media (aspect-ratio: 86/74) {
    path {
        fill: red;
    }
}

/* favicon with light browser theme */
@media (aspect-ratio: 1/1) and (prefers-color-scheme: light) {
    path {
        fill: black;
    }
}

/* favicon with dark browser theme */
@media (aspect-ratio: 1/1) and (prefers-color-scheme: dark) {
    path {
        fill: white;
    }
}

One very important thing

The SVG must contain viewBox information, so that the stretching does not affect the graphics. Example:

<svg xmlns="http://www.w3.org/2000/svg" width="300" height="300" viewBox="0 0 300 300">

Upvotes: 4

jens1101
jens1101

Reputation: 660

If you have a single-colour SVG with varying opacities that you simply want to tint to a different colour then there is another approach that can be used: the feFlood SVG filter.

This solution is not as straightforward as a single-line CSS, however:

  • It works on SVGs inside of an img element.
  • This doesn't require editing the source SVG at all.
  • It allows you to simply choose a target colour for the SVG and not worry about complex colour transforms, like hue-rotate.

Here is an example:

<svg xmlns="http://www.w3.org/2000/svg" width="0" height="0">
  <defs>
    <filter id="recolourFilter" filterUnits="userSpaceOnUse">
      <feFlood flood-color="aquamarine" result="flood" />
      <feComposite in="flood" in2="SourceAlpha" operator="in" />
    </filter>
  </defs>
</svg>

<img style="filter: url(#recolourFilter);" width="300" src="https://upload.wikimedia.org/wikipedia/commons/6/6b/Bitmap_VS_SVG.svg" />

In the above example, we create an inline SVG to define the filters and then we apply it to the image. Inside of the <filter> block we first define the fill colour that we want via <feFlood> and then we create a composite image using the alpha channel of the source plus the flood colour. Finally, the filter is applied to the whole image via the filter CSS property on the img element.

I learned about this technique from this Smashing Magasine article. It's a highly recommended read if you want to learn more about SVG filters.

A few additional things to note:

  • This filter can be applied to any HTML element via the CSS filter property.
  • The same filter can be reused multiple times on the same page.
  • If you are using an inline SVG then the <defs> block can form part of the svg element and the filter can still be applied to the whole SVG or on selective elements. This avoids needing a separate SVG element for the filters.

Upvotes: 3

Ben Carp
Ben Carp

Reputation: 26498

Solution 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 content:

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, nonsignificant difference between the result and the desired color.

Suitable if:

  • Desired color is known in advance.
  • External image

Upvotes: 88

Chester Fung
Chester Fung

Reputation: 370

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 content 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;
}
<html>
<body>
<svg id="icon-green" xmlns="http://www.w3.org/2000/svg" width="40px" height="40px" style="vertical-align:text-bottom" viewbox="0 0 40 40">
  <circle cx="20" cy="20" r="18" stroke-width="3"/>
  <path d="M 10,10 30,30 M 10,30 30,10" fill="none"  stroke-width="6"/>
</svg>


<svg id="icon-red" xmlns="http://www.w3.org/2000/svg" width="40px" height="40px" style="vertical-align:text-bottom" viewbox="0 0 40 40">
  <circle cx="20" cy="20" r="18" stroke-width="3"/>
  <path d="M 10,10 30,30 M 10,30 30,10" fill="none"  stroke-width="6"/>
</svg>

<svg id="icon" xmlns="http://www.w3.org/2000/svg" width="40px" height="40px" style="vertical-align:text-bottom" viewbox="0 0 40 40">
  <circle cx="20" cy="20" r="18" stroke-width="3"/>
  <path d="M 10,10 30,30 M 10,30 30,10" fill="none"  stroke-width="6"/>
</svg>

</body>

</html>

Upvotes: -2

Sarang Kakkoth
Sarang Kakkoth

Reputation: 489

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

.search_icon {
  color: red;
  fill: currentColor;
  display: inline-block;
  width: 100px;
  height: 100px;
}
<span class="search_icon">
    <svg focusable="false" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.5 14h-.79l-.28-.27A6.471 6.471 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path></svg>
</span>

I have used a 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.

Upvotes: 16

Amit Bodaliya
Amit Bodaliya

Reputation: 126

Check out this code. It works.

<div>
   <!-- YouTube -->
   <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512">
       <path fill="white"
           d="M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.78 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821 11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305zm-317.51 213.508V175.185l142.739 81.205-142.739 81.201z" />
   </svg>

   <!-- Instagram -->
   <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
       <path fill="white"
           d="M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z" />
   </svg>
</div>

CSS

svg {
   fill: white;
}

Upvotes: 5

Evaldas
Evaldas

Reputation: 206

My answer would be this. But I’m not 100% sure if it works for everyone:

Select 'svg' and then 'path'. And you can change 'fill' then.

.eye-icon-container {
    width: 33px;
    height: 33px;
    border-radius: 5px;
    display: flex;
    justify-content: center;
    align-items: center;

    :hover {
      background-color: #ddf0ff;
    }
    :active {
      background-color: #1d398d;
      svg {
        path {
          fill: #fff;
        }
      }
    }
  }

Upvotes: 2

Kemot 90
Kemot 90

Reputation: 321

For a better resolution about Manish Menaria's (thank you so much for your help) response, use this filter generator instead a purposed generator: https://angel-rs.github.io/css-color-filter-generator/

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

Upvotes: 4

Benjamin Piette
Benjamin Piette

Reputation: 3783

For Angular users, the "inline-svg-2" npm library was quite useful:

You can now dynamically configure your CSS colors, including with CSS variables, and the SVG will adapt.

Note: The "currentColor" trick works only for inlined SVGs, this is why we need a special module for this.

Upvotes: 0

elver
elver

Reputation: 111

My usage is with Bootstrap icons, copying your SVG path.

span{
    path{
        color: red;
    }
}

One example of SVG Bootstrap:

        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
          class="bi bi-exclamation-octagon" viewBox="0 0 16 16">
          <path
            d="M4.54.146A.5.5 0 0 1 4.893 0h6.214a.5.5 0 0 1 .353.146l4.394 4.394a.5.5 0 0 1 .146.353v6.214a.5.5 0 0 1-.146.353l-4.394 4.394a.5.5 0 0 1-.353.146H4.893a.5.5 0 0 1-.353-.146L.146 11.46A.5.5 0 0 1 0 11.107V4.893a.5.5 0 0 1 .146-.353L4.54.146zM5.1 1 1 5.1v5.8L5.1 15h5.8l4.1-4.1V5.1L10.9 1H5.1z" />
          <path
            d="M7.002 11a1 1 0 1 1 2 0 1 1 0 0 1-2 0zM7.1 4.995a.905.905 0 1 1 1.8 0l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 4.995z" />
        </svg>

Upvotes: -3

Mr. Sulaman Khan
Mr. Sulaman Khan

Reputation: 475

The easiest trick is to change the color using jQuery on page load.

      $(document).ready(function () { 
              $('svg').find('path').attr('fill', '#FFF');
      });

#FFF is the color code that you want to set.

Upvotes: -3

Shabeer M
Shabeer M

Reputation: 170

There are some problems with Manish Menaria's answer, if we convert white color it shows gray.

So I added some tweaks, and the below example specifically shows how to change the color in the material icon:

<mat-icon class="draft-white" svgIcon="draft" aria-hidden="false"></mat-icon>
.draft-white{
    filter: brightness(0) invert(1);
}

Upvotes: 3

Related Questions