skip to Main Content

I have this sun svg image that switches the page to dark mode:

<svg onclick="myFunction()" width="24" height="24" viewBox="0 0 24 24" fill="#000" xmlns="http://www.w3.org/2000/svg">
    <path d="M12 3V5.25M18.364 5.63604L16.773 7.22703M21 12H18.75M18.364 18.364L16.773 16.773M12 18.75V21M7.22703 16.773L5.63604 18.364M5.25 12H3M7.22703 7.22703L5.63604 5.63604M15.75 12C15.75 14.0711 14.0711 15.75 12 15.75C9.92893 15.75 8.25 14.0711 8.25 12C8.25 9.92893 9.92893 8.25 12 8.25C14.0711 8.25 15.75 9.92893 15.75 12Z" stroke="#000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
  </path>
</svg>

this is the JavaScript:

function myFunction() {
  var element = document.body;
  element.classList.toggle("dark-mode");
}

and this is some CSS:

.dark-mode {
  background: #333;
}

.dark-mode path {
  fill: #fff;
  stroke: #fff;
}

however, I want the svg itself to be switched, too, after clicking on it as a replacement. This is the other svg to be switched to, which is a moon svg image:

<svg width="24" height="24" viewBox="0 0 24 24" fill="#000" xmlns="http://www.w3.org/2000/svg">
  <path d="M21.7519 15.0019C20.597 15.4839 19.3296 15.75 18 15.75C12.6152 15.75 8.25 11.3848 8.25 5.99999C8.25 4.67039 8.51614 3.40296 8.99806 2.24805C5.47566 3.71785 3 7.19481 3 11.25C3 16.6348 7.36522 21 12.75 21C16.8052 21 20.2821 18.5243 21.7519 15.0019Z" stroke="#000000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
  </path>
</svg>

how can this be done, please?

2

Answers


  1. You can save the paths as a dictionary and pass the svg into the myFunction, and update the innerHTML based on what classList.toggle returns:

    var lighting_mode_paths = {
      'moon': '<path d="M21.7519 15.0019C20.597 15.4839 19.3296 15.75 18 15.75C12.6152 15.75 8.25 11.3848 8.25 5.99999C8.25 4.67039 8.51614 3.40296 8.99806 2.24805C5.47566 3.71785 3 7.19481 3 11.25C3 16.6348 7.36522 21 12.75 21C16.8052 21 20.2821 18.5243 21.7519 15.0019Z" stroke="#000000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>',
      'sun': '<path d="M12 3V5.25M18.364 5.63604L16.773 7.22703M21 12H18.75M18.364 18.364L16.773 16.773M12 18.75V21M7.22703 16.773L5.63604 18.364M5.25 12H3M7.22703 7.22703L5.63604 5.63604M15.75 12C15.75 14.0711 14.0711 15.75 12 15.75C9.92893 15.75 8.25 14.0711 8.25 12C8.25 9.92893 9.92893 8.25 12 8.25C14.0711 8.25 15.75 9.92893 15.75 12Z" stroke="#000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path>',
    };
    
    function myFunction(svg) {
      var element = document.body;
      
      if (element.classList.toggle('dark-mode')) {
        svg.innerHTML = lighting_mode_paths['moon'];
      } else {
        svg.innerHTML = lighting_mode_paths['sun'];
      }
    }
    .dark-mode {
      background: #333;
    }
    
    .dark-mode path {
      fill: #fff;
      stroke: #fff;
    }
    <svg onclick="myFunction(this)" width="24" height="24" viewBox="0 0 24 24" fill="#000" xmlns="http://www.w3.org/2000/svg">
        <path d="M12 3V5.25M18.364 5.63604L16.773 7.22703M21 12H18.75M18.364 18.364L16.773 16.773M12 18.75V21M7.22703 16.773L5.63604 18.364M5.25 12H3M7.22703 7.22703L5.63604 5.63604M15.75 12C15.75 14.0711 14.0711 15.75 12 15.75C9.92893 15.75 8.25 14.0711 8.25 12C8.25 9.92893 9.92893 8.25 12 8.25C14.0711 8.25 15.75 9.92893 15.75 12Z" stroke="#000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
      </path>
    </svg>

    element.classList.toggle returns true if it has added the class to element, and returns false if it has removed the class from element.

    Login or Signup to reply.
  2. No need for JavaScript, CSS can set the d-path (except Safari 17.4 – march 24)

    For the Browser light/drark setting
    use https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme

    If you want a JavaScript solution, a native Web Component <svg-celestial-body> might be easier to work with

    customElements.define("svg-celestial-body", class extends HTMLElement {
      connectedCallback() {
        this.style.display = "inline-block";
        let stroke = "black";
        let fill = "beige";
        let width = 1.5;
        let d = "m10 1v2m6 1-1 1m4 5h-2m-1 6-1-1m-5 2v2m-5-4-1 1m-1-6h-2m4-5-1-1m10 6c0 2-2 4-4 4-2 0-4-2-4-4 0-2 2-4 4-4 2 0 4 2 4 4z";
        let isLight = matchMedia("(prefers-color-scheme: light)").matches;
        if (this.hasAttribute("light") || this.hasAttribute("dark")){
          isLight = this.hasAttribute("dark");    
        }
        if (isLight) {
          fill = "gold";
          width = 1;
          d = "M22 15C21 16 19 16 18 16 13 16 8 11 8 6 8 4 8 4 9 2 6 4 3 7 3 11 3 17 7 21 13 21 17 21 20 19 22 15Z";
        }
        let path = `<path d="${d}" stroke="${stroke}" stroke-width="${width}" fill="${fill}" stroke-linecap="round" stroke-linejoin="round"/>`;
        this.innerHTML = `<svg viewBox="0 0 24 24">`+path+`</svg>`;
    
      }
    });
    svg {
      width: 110px;
    }
    
    path {
      stroke: black;
      stroke-width: 1.5;
      stroke-linecap: round;
      stroke-linejoin: round;
    }
    
    svg[light] {
      path {
        fill: gold;
        stroke-width: 1;
        d: path("m10 1v2m6 1-1 1m4 5h-2m-1 6-1-1m-5 2v2m-5-4-1 1m-1-6h-2m4-5-1-1m10 6c0 2-2 4-4 4-2 0-4-2-4-4 0-2 2-4 4-4 2 0 4 2 4 4z")
      }
    }
    
    svg[dark] {
      path {
        fill: beige;
        d: path("M22 15C21 16 19 16 18 16 13 16 8 11 8 6 8 4 8 4 9 2 6 4 3 7 3 11 3 17 7 21 13 21 17 21 20 19 22 15Z")
      }
    }
    <svg light viewBox="0 0 24 24">
        <path/>
    </svg>
    
    <svg dark viewBox="0 0 24 24">
        <path/>
    </svg>
    
    <svg-celestial-body></svg-celestial-body>
    <svg-celestial-body light></svg-celestial-body>
    <svg-celestial-body dark></svg-celestial-body>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search