2

I am referencing an SVG image in my page as such:

<object type="image/svg+xml" data="Images/help.svg" class="svgHelp"></object>

I want to be able to use a CSS variable to set the color. So, I have the following code for the SVG:

<?xml version="1.0" encoding="UTF-8"?>
<svg viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <style>
    @import url('/site.css');
  </style>
  <path fill="var(--shape)" d="M9.5,15 C10.0522847,15 10.5,15.4477153 10.5,16 C10.5,16.5522847 10.0522847,17 9.5,17 C8.94771525,17 8.5,16.5522847 8.5,16 C8.5,15.4477153 8.94771525,15 9.5,15 Z M9.5,0 C11.9852814,0 14,2.01471863 14,4.5 C14,5.62866311 13.5819742,6.69223142 12.8447962,7.51046545 L12.6819805,7.68198052 C11.3219676,9.0419934 10.1146376,10.9892252 10.0076903,12.7498371 L10,13 L9,13 C9,10.8402177 10.3786205,8.57112697 11.9748737,6.97487373 C12.6273393,6.32240814 13,5.44133935 13,4.5 C13,2.56700338 11.4329966,1 9.5,1 C7.6314366,1 6.10487355,2.4642776 6.00517886,4.3079648 L6,4.5 L5,4.5 C5,2.01471863 7.01471863,0 9.5,0 Z"></path>
</svg>

The site.css file looks like this (the important parts anyways):

:root {
    --shape: red;
}

This all works fine. The variable gets used and the image is red. My problem is that I have a variable in another CSS file. It will not allow me to use that other CSS variable either in the SVG file or set it in the site.css for that --shape variable.

so, if there is a theme1.css with the following:

:root {
    --shape2: blue;
}

I can not go to site.css and set the variable as such (well, I can, it just doesn't work):

:root {
    --shape: var(--shape2);
}

Let's assume that my site has allows for different themes. theme1.css has all the variables for the site declared. These variables hold all the colors. In order to theme, we just swap to theme2.css which has all the same variables declared, but different colors. I want to use these variables in either the SVG file or in the site.css so that I can use the same variable name but get different colors based on the theme. None of this works though.

What's odd is that --shape which is declared in the site.css file works fine in the SVG. I can change the color, no issues. As soon as I try to set that variable with a variable from another file, it doesn't work.

Any other ideas?

So, ultimately, I want to have external SVG files that can be styled using variables from another CSS file (but read above to see why I'm stuck).

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
Steve Buchok
  • 169
  • 1
  • 10
  • `--shape: var(--shape2);` should work fine, can you share a working code to demonstrate the issue ? – Temani Afif Sep 23 '20 at 12:27
  • ok, I see the issue. You cannot do what you want with `object`. Its scope is limited to what is inside and it cannot take CSS from the outside. You need to use the SVG directly inside the code – Temani Afif Sep 23 '20 at 12:29
  • @TemaniAfif I am able to use CSS from the external file. The --shape variable works fine. The issue is try to use a global variable declared in another file doesn't seem to be allowed. So you might be right about scope though. Maybe I'm only allowed to use what's declared in that CSS file and not from any other. Hmmmm – Steve Buchok Sep 23 '20 at 12:33
  • 1
    --shape works fine because it's inside the CSS file which is inside the object. So your scope is only that file and what is inside. Any other CSS file outside the object element will have no effect inside it – Temani Afif Sep 23 '20 at 12:34
  • @TemaniAfif I'm going to post that as the answer. I had a funny feeling that might be the case, but was REALLY hoping it wasn't. Thanks – Steve Buchok Sep 23 '20 at 12:38
  • @TemaniAfif I'm trying to do this, what am I doing wrong? https://jsfiddle.net/dhz4sLer/1/ How is the root: supposed to be set up? –  Aug 11 '21 at 23:30
  • @csshtmljavascript14578 please create a new question. – Steve Buchok Aug 13 '21 at 00:24
  • I did, it's right here. https://stackoverflow.com/questions/68758444/using-root-to-manage-fill-attribute-for-svg-as-data-uri-from-css-variables –  Aug 13 '21 at 00:55

3 Answers3

4

Instead of object use use like below:

:root {
  --shape2: blue;
}
<!-- make this on the top of your code  -->
<svg viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="visibility:hidden;width:0;height:0;">
  <defs>
  <style>
    :root {
       --shape: var(--shape2,red);
    }
  </style>
  <path id="shape" fill="var(--shape)" d="M9.5,15 C10.0522847,15 10.5,15.4477153 10.5,16 C10.5,16.5522847 10.0522847,17 9.5,17 C8.94771525,17 8.5,16.5522847 8.5,16 C8.5,15.4477153 8.94771525,15 9.5,15 Z M9.5,0 C11.9852814,0 14,2.01471863 14,4.5 C14,5.62866311 13.5819742,6.69223142 12.8447962,7.51046545 L12.6819805,7.68198052 C11.3219676,9.0419934 10.1146376,10.9892252 10.0076903,12.7498371 L10,13 L9,13 C9,10.8402177 10.3786205,8.57112697 11.9748737,6.97487373 C12.6273393,6.32240814 13,5.44133935 13,4.5 C13,2.56700338 11.4329966,1 9.5,1 C7.6314366,1 6.10487355,2.4642776 6.00517886,4.3079648 L6,4.5 L5,4.5 C5,2.01471863 7.01471863,0 9.5,0 Z"></path>
  </defs>
</svg>
<!-- -->

<!-- what you will use inside the code -->
<svg>
  <use xlink:href="#shape"  />
</svg>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
0

As mentioned by @TemaniAfif above, it looks like you only have access to the CSS file that is referenced. Any other files will be out of scope and you won't be able to use those variables.

Steve Buchok
  • 169
  • 1
  • 10
0

I have decided to create a web component.

export class MY_SVG extends HTMLElement {
    constructor() {
        super();

        this.Loaded;
    }

    connectedCallback() {
        if(!this.Loaded)
            this.LoadImage();
    }

    async LoadImage() {
        let src = this.getAttribute('src');

        const res = await fetch(src);

        const textTemplate = await res.text();

        this.appendChild(new DOMParser().parseFromString(textTemplate, 'text/html').querySelector('svg'));

        this.Loaded = true;
    }
}

customElements.define('my-svg', MY_SVG);

You'd use it like so:

<my-svg src="folder/image.svg"></my-svg>

Now, I can use the css as I wanted to. I found this to be my favorite solution. Hope this helps someone else at some point too.

Steve Buchok
  • 169
  • 1
  • 10