0

I am trying to build a masonry portfolio website with a light and dark mode.

I've been following Connor Bailey's "Vanilla JavaScript: Masonry Grid Layout" tutorial. Link to video: https://www.youtube.com/watch?v=MdKDHkhdCto&ab_channel=ConorBailey Link to code: https://github.com/conorbailey90/masonry-grid-layout

I have added a light mode so when my icon is clicked, the colour scheme shifts:

var icon = document.getElementById("icon");
icon.onclick = function(){
    document.body.classList.toggle("light-theme");
}
:root {
    /* colours */
    --backgroundColour: #000000;
    --textColour: #ffffff;
    --darkGrey: #161616;
}

.light-theme {    
    --backgroundColour: #ffffff;
    --textColour: #000000;
    --darkGrey: #a5a5a5;} 

/* SVG colours */
.cls-1 {
    fill: var(--textColour);
}

This works with every element and I have defined a class in my style.css code so the SVG (that has been defined in my HTML) will change colour as the text does.

The problem comes with my svg content that has not been defined in HTML. The following code is how my images are entered into my masonry grid layout:

const posts = [];

const item0 =   ['items/svg-1.svg'];

const images = [
    item0,
];

This format works but the SVG in my masonry grid is not dynamically editable. I would like the white part of my svg to turn black when I switch light themes but it seems like there is not a way of doing this using my current reference mechanism.

Is there a different way I can reference my SVG files so that they can be modified dynamically in CSS like my other icon?

problem: When I click my "light mode" button I hoped the white parts of my SVG files would turn black (because of my defined --text-colour variable).

The text & svg defined in HTML did follow the --text-colour variable The svg defined in javascript did NOT follow the --text-colour variable.

yze
  • 1
  • 1
    As you've found in your experiments, external SVG (as opposed to SVG trees embedded in your HTML document) can't be styled in this way. There are [some workarounds](https://stackoverflow.com/a/53336754/21146235) available but nothing as convenient as drop-in CSS variables. – motto Apr 14 '23 at 17:13
  • What happens with ``const images = [item0 ]`` Show us the JavaScript code that turns this data structure into DOM elements. Please add an [Minimal minimal-reproducible-example StackOverflow Snippet](https://stackoverflow.com/help/minimal-reproducible-example) to your post. It will help readers execute your code with one click. And help create answers with one click. See [How to add a StackOverflow snippet](https://meta.stackoverflow.com/questions/269753/feedback-requested-runnable-code-snippets-in-questions-and-answers) – Danny '365CSI' Engelman Apr 15 '23 at 08:53

1 Answers1

0

You cannot change the color of the svg's if it is used by using the img tag.

Workaround:

  1. You need to use the raw svg in the html (XML code of the svg)
  2. For the dynamic image, you can create an api endpoint to return the raw xml of the svg image
  3. You can use the response from point 2, to show the dynamic svg and manipulate colors of the svg elements.

Helpful Links: SVG Tutorial

<svg width="100" height="100">
  <circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
</svg>
Shakti
  • 723
  • 8
  • 15
  • Thank you so much for your response. I am very new to all of this so you'll have to forgive my inexperience. If I understand you correctly I need to: 1. Define the SVG in my HTML 2. Create a reference for the HTML SVG 3. Reference the SVG in my Javascript I'm not exactly sure how to follow Step 2, how would I create this reference. And once I have created the reference, would I have to modify my current item setup? This is what I mean by current item setup: const posts = []; const item0 = ['items/svg-1.svg']; const images = [ item0, ]; – yze Apr 14 '23 at 17:26
  • You will need to include svg as raw xml data of svg. Open svg image (Right click to open in a notepad, and select xml data), Paste it in the html. You can give different id's and classes to the svg and it's elements based on your needs. And then you can target those elements using the id's or classes by javascript. Helpful links here: https://stackoverflow.com/questions/16830653/can-getelementbyid-decend-into-svg-docs and http://jsfiddle.net/cSk3f/ – Shakti Apr 17 '23 at 17:00