13

I am trying to use SVG on my web page.

But it's color is black. So, I want it to be changed. So, I have done-

.red_color_svg
{
    color: red;
    border: 5px solid currentColor;
    fill: currentColor;
}
<object type="image/svg+xml" data="https://rawcdn.githack.com/encharm/Font-Awesome-SVG-PNG/master/black/svg/heart.svg" class="weather_icon red_color_svg circle"></object>

To import heart_border.svg file and make its color red. But it does not work as you see i the output.

Can anyone help me please to solve this?

Thank you very much in advance for helping.

ptim
  • 14,902
  • 10
  • 83
  • 103
Abrar Jahin
  • 13,970
  • 24
  • 112
  • 161

5 Answers5

17

CSS does not apply cross document and you've two documents here heart_border.svg and the container html document.

You need to include the CSS in heart_border.svg e.g. by adding a <link> element or an <xml-stylesheet> processing instruction or by adding it inline in that file via a <style> element.

Alternatively if you add the SVG inline in the html document itself so that you only have one document the CSS will then apply.

Robert Longson
  • 118,664
  • 26
  • 252
  • 242
6

This thread is old but I wanted to share my solution, based on SVG filters. You just need to define a feColorMatrix filter as you want and apply it to the external image. See example below for more details.

Compatible with any browsers that can handle SVG.

<svg width="100%" height="100%" class="draggable">
  <defs>
    <filter id="customColor1">
      <!-- Match hex color for #50A -->
      <feColorMatrix
        in="SourceGraphic"
        type="matrix"
        values="0 0 0 0 0.3333333333333333 0 0 0 0 0 0 0 0 0 0.6666666666666666 0 0 0 1 0"
      ></feColorMatrix>
    </filter>
    
    <filter id="customColor2">
      <!-- Match hex color for #0F0 -->
      <feColorMatrix
        in="SourceGraphic"
        type="matrix"
        values="0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0"
      ></feColorMatrix>
    </filter>
  </defs>
  <image href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/icon-bike-black.svg" width="50" height="50"></image>
  <image href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/icon-bike-black.svg" filter="url(#customColor1)" width="50" height="50" x="100"></image>
  <image href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/icon-bike-black.svg" filter="url(#customColor2)" width="50" height="50" x="200"></image>
  
</svg>

[BONUS]

// A little helper to generate matrix color from source and destination colors
// To easily dive in : https://codepen.io/jacobberglund/pen/ORNQAr
// To understand what's going on here read this article by A List Apart
// https://alistapart.com/article/finessing-fecolormatrix/

interface RgbColor {
  /** Values are in percent (ex: 255,127,0,255 => 1,0.5,0,1) */
  r: number;
  g: number;
  b: number;
  a: number;
}

export class ColorMatrixHelper {
  public static getMatrix(hexColor: string) {
    const rgbColor: RgbColor = ColorMatrixHelper.hexToRgb(hexColor);
    return ColorMatrixHelper.computeMatrixColor(rgbColor);
  }

  // Inspired by this answer : https://stackoverflow.com/a/5624139/11480016
  private static hexToRgb(hex3or6): RgbColor {
    // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
    const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
    const hex6 = hex3or6.replace(shorthandRegex, (m, r, g, b) => r + r + g + g + b + b);

    var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})?$/i.exec(hex6);
    const base = 1 / 255;
    return result
      ? {
          r: parseInt(result[1], 16) * base,
          g: parseInt(result[2], 16) * base,
          b: parseInt(result[3], 16) * base,
          a: result[4] ? parseInt(result[4], 16) * base : 1,
        }
      : null;
  }

  private static computeMatrixColor(rgbColor: RgbColor): string {
    let matrix;
    if (rgbColor) {
      // Ignore original colors and apply the new one
      matrix =
        `0 0 0 0 ${rgbColor.r} ` + // Red
        `0 0 0 0 ${rgbColor.g} ` + // Green
        `0 0 0 0 ${rgbColor.b} ` + // Blue
        `0 0 0 ${rgbColor.a} 0`; // Alpha
    } else {
      // Identity (keep orignal colors)
      matrix =
        `1 0 0 0 0 ` + // Red
        `0 1 0 0 0 ` + // Green
        `0 0 1 0 0 ` + // Blue
        `0 0 0 1 0`; // Alpha
    }
    return matrix;
  }
}
aadiene
  • 327
  • 3
  • 7
-1

With your current code you set the fill on the object element.

Instead, you need to set it on the svg element.

Something like this:

.red_color_svg svg {
   fill: currentColor;
}
Danield
  • 121,619
  • 37
  • 226
  • 255
-4

The problem is that you don't target the actual SVG element, you target the "SVG container". To be able to change the color of one of the elements inside the SVG you have to target that specific element.

E.g change the fill color of all paths in a SVG:

.weather_icon path {
    fill: yellow;
}

If you want to make it easier to handle add class names to the different elements inside the svg.

<path class="my-class" ......... />

This will make it possible to target a specific element by its class:

.weather_icon .my-class {
    fill:blue;
    stroke:green;
}
Linus
  • 448
  • 2
  • 5
-7

Do you really need SVG to be external file? you might want to put svg locally once in document.

<div style="display: none">
    <svg><g id="svg1"><path d="some exampe path"/></g></svg>
</div>

And link to it in several places

<svg viewBox="0 0 64 64"><use xlink:href="#svg1"></use></svg>

Than you can style every link separately

marek
  • 1