admin管理员组

文章数量:1332403

I have a black color logo for my portfolio and i would like to switch it white when Dark Mode : /

I have tried:

  • Using CSS Variables
<img class="nav_logo" src="assets/img/PR_logo.png" alt="original logo" />

body {
  --nav_logo: url(PR_logo.png) no-repeat;

}

body[data-theme="dark"] {
  --nav_logo: url(PR_logo_white.png) no-repeat;
}

.nav_logo {
    background: var(--nav_logo);
  } 

  • Using SVG

 <img class="nav_logo" src="assets/img/PR_logo.svg" id="svg" alt="PR Logo">


.nav_logo {
    fill: currentColor;
}

Unfortunately none of the above has worked. Any suggestion?

I have a black color logo for my portfolio and i would like to switch it white when Dark Mode : https://www.paulinerouger./

I have tried:

  • Using CSS Variables
<img class="nav_logo" src="assets/img/PR_logo.png" alt="original logo" />

body {
  --nav_logo: url(PR_logo.png) no-repeat;

}

body[data-theme="dark"] {
  --nav_logo: url(PR_logo_white.png) no-repeat;
}

.nav_logo {
    background: var(--nav_logo);
  } 

  • Using SVG

 <img class="nav_logo" src="assets/img/PR_logo.svg" id="svg" alt="PR Logo">


.nav_logo {
    fill: currentColor;
}

Unfortunately none of the above has worked. Any suggestion?

Share Improve this question edited Feb 22, 2022 at 13:04 Sercan 5,1013 gold badges23 silver badges41 bronze badges asked Feb 7, 2022 at 5:21 PaulineTWPaulineTW 411 silver badge10 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 3

If you are considering a JS-based solution, you can use the approach I developed below. Clicking the toggle button changes both the src attribute of the <img> element and the background-color style of the <body> element.

let button = document.getElementById('toggleButton');
let logo = document.getElementById('logo');

let darkImageURL = "https://cdn-icons-png.flaticon./512/196/196685.png";
let lightImageURL = "https://cdn-icons-png.flaticon./512/169/169367.png";

button.addEventListener('click', function(event) {
  if(this.innerHTML === "Dark") {
    document.body.style.background = "black";
    this.innerHTML = "Light";
    logo.src = darkImageURL;
  }
  else {
    document.body.style.background = "white";
    this.innerHTML = "Dark";
    logo.src = lightImageURL;
  }
});
<body>
  <button id="toggleButton">Dark</button>

  <img id="logo" class="nav_logo" src="https://cdn-icons-png.flaticon./512/169/169367.png" alt="original logo" width="100" height="100"/>
</body>

You can use css variables with content property for img

document.getElementById('toggleButton').addEventListener('click', function(event) {
  if (this.innerHTML === "Dark") {
    document.body.dataset.theme = "dark";
    this.innerHTML = "Light";
  } else {
    document.body.dataset.theme = "light";
    this.innerHTML = "Dark";
  }
});
body {
  --nav_logo: url('https://cdn-icons-png.flaticon./512/169/169367.png');
}

body[data-theme="dark"] {
  --nav_logo: url('https://cdn-icons-png.flaticon./512/196/196685.png');
}

.nav_logo {
  content: var(--nav_logo);
}
<body>
  <button id="toggleButton">Dark</button>

  <img id="logo" class="nav_logo" src="https://cdn-icons-png.flaticon./512/169/169367.png" alt="original logo" width="100" height="100" />
</body>

change stroke="#000" in your svg to stroke="currentColor"

body.dark-theme .nav__logo{
    color: #FFFFFF;
}

Svg is just perfect – but wont't work within an <img> element. You might consider these steps:

  • optimize your logo svg to inherit colors in a more consistent way
  • reduce your logo to fixed path elements i.e convert stroked elemnts like the inside bar/pipe to a solid shape/path to avoid accidental strike-width shifts
  • use an svg <use> concept – providing an <img> like usage i.e providing external svg files as reusable assets.

Example1

stripping hard coded svg properties for better global css styling:

function toggleDarkmode(){
  document.body.classList.toggle('darkmode')
}
* {
  box-sizing: border-box;
}

body {
  color: #000;
  transition: 0.3s;
}

.darkmode {
  color: #fff;
  background-color: #000;
}


/* just example css – not essential */

.nav__logo .logo {
  display: inline-block;
  width: 10em;
}

.svgAsset {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}
<div class="nav__logo">
  <p><button type="button" onclick="toggleDarkmode()">toggleDarkmode</button></p>
  <svg class="logo" xmlns="http://www.w3/2000/svg" viewBox="0 0 375 375" fill="currentColor">
    <path d="M 187.382812 337.265625 C 148.582031 337.265625 112.046875 322.164062 84.628906 294.691406 C 57.152344 267.273438 42.050781 230.738281 42.050781 191.933594 C 42.050781 153.132812 57.152344 116.597656 84.628906 89.179688 C 112.046875 61.703125 148.582031 46.601562 187.382812 46.601562 C 226.1875 46.601562 262.722656 61.703125 290.140625 89.179688 C 317.613281 116.652344 332.714844 153.132812 332.714844 191.933594 C 332.714844 230.738281 317.613281 267.273438 290.140625 294.691406 C 262.722656 322.164062 226.1875 337.265625 187.382812 337.265625 Z M 187.382812 55.316406 C 150.90625 55.316406 116.574219 69.546875 90.785156 95.335938 C 64.996094 121.125 50.765625 155.457031 50.765625 191.933594 C 50.765625 228.414062 64.996094 262.742188 90.785156 288.53125 C 116.574219 314.324219 150.90625 328.554688 187.382812 328.554688 C 223.863281 328.554688 258.191406 314.324219 283.980469 288.53125 C 309.773438 262.742188 324.003906 228.414062 324.003906 191.933594 C 324.003906 155.457031 309.773438 121.125 283.980469 95.335938 C 258.191406 69.546875 223.863281 55.316406 187.382812 55.316406 Z M 187.382812 55.316406"></path>
    <path d="M 35.097656 -71.835938 L 8.824219 -71.835938 L 8.824219 0 L 19.292969 0 L 19.292969 -23.910156 L 35.097656 -23.910156 C 50.59375 -23.910156 58.390625 -35.816406 58.390625 -47.820312 C 58.390625 -59.828125 50.59375 -71.835938 35.097656 -71.835938 Z M 35.097656 -34.171875 L 19.292969 -34.171875 L 19.292969 -61.367188 L 35.097656 -61.367188 C 43.820312 -61.367188 48.128906 -54.59375 48.128906 -47.71875 C 48.128906 -40.945312 43.820312 -34.171875 35.097656 -34.171875 Z M 35.097656 -34.171875" transform="translate(97.282 227.676)"></path>
    <path d="M 34.996094 -36.429688 L 22.886719 -36.429688 L 22.886719 -31.503906 L 49.054688 0 L 62.496094 0 L 39.816406 -26.988281 C 52.132812 -29.144531 58.390625 -38.792969 58.390625 -48.949219 C 58.390625 -60.34375 50.59375 -72.757812 34.996094 -72.757812 L 8.824219 -72.757812 L 8.824219 0 L 19.085938 0 L 19.085938 -62.292969 L 34.996094 -62.292969 C 43.71875 -62.292969 48.027344 -55.109375 48.027344 -48.949219 C 48.027344 -42.691406 43.71875 -36.429688 34.996094 -36.429688 Z M 34.996094 -36.429688" transform="translate(216.811 227.676)"></path>
    <path transform="matrix(0 -9.7441 10.11111 0 187.491 250.21)" d="M -0.0000988013 0.0000885473 L 11.930592 0.0000885473" stroke="currentColor" stroke-width="1"></path>
  </svg>
</div>

  • all path related fill attributes are removed (resulting in a default fill="#000" / black)
  • svg parent element gets a fill="currentColor" – inherited to all children
  • the stroke based bar/pipe element gets a stroke="currentColor" rule

Example2

<svg><use href="#..."></svg> also works fine with external files

The next example takes an inlined svg as source but will also work fine with external file references like this (provided, these external files are available on the same domain):

  <svg>
    <use href="logo.svg#logo-symbol">
  </svg>  

function toggleDarkmode(){
  document.body.classList.toggle('darkmode')
}
*{
  box-sizing:border-box;
}

body {
  color: #000;
  transition: 0.3s;
}

.darkmode {
  color: #fff;
  background-color: #000;
}

/* just example css – not essential */
.nav__logo .logo {
  display: inline-block;
  width: 10em;
}

.svgAsset{
  position:absolute;
  width:0;
  height:0;
  overflow:hidden;
}
<div class="nav__logo">
  <p><button type="button" onclick="toggleDarkmode()">toggleDarkmode</button></p>
  <svg class="logo logo-cropped" viewBox="0 0 100 100" >
    <use href="#logo-smaller" />
  </svg>
</div>

<svg class="svgAsset" xmlns="http://www.w3/2000/svg" viewBox="0 0 100 100" aria-hidden="true">
  <symbol id="logo-smaller" viewBox="0 0 100 100" fill="currentColor">
    <path id="circle" d="M50 100c-27.6 0-50-22.4-50-50c0-27.6 22.4-50 50-50c27.6 0 50 22.4 50 50c0 27.6-22.4 50-50 50zm0-97c-25.9 0-47 21.1-47 47c0 25.9 21.1 47 47 47c25.9 0 47-21.1 47-47c0-25.9-21.1-47-47-47z" />
    <path id="P" d="M31.1 37.6l-9 0l0 24.7l3.6 0l0-8.2l5.4 0c5.3 0 8-4.1 8-8.2c0-4.2-2.7-8.3-8-8.3zm0 12.9l-5.4 0l0-9.4l5.4 0c3 0 4.5 2.3 4.5 4.7c0 2.4-1.5 4.7-4.5 4.7z" />
    <path id="R" d="M72.2 49.8l-4.2 0l0 1.7l9 10.8l4.6 0l-7.8-9.3c4.2-0.7 6.4-4.1 6.4-7.6c0-3.9-2.7-8.2-8-8.2l-9 0l0 25l3.5 0l0-21.3l5.5 0c3 0 4.5 2.5 4.5 4.6c-0.1 2.1-1.5 4.3-4.5 4.3z" />
    <path id="Pipe" d="M51.4 70l-2.8 0l0-40l2.8 0l0 40z" />
  </symbol>
</svg>

In the above example, strokes are converted to solid paths – thus you don’t have to bother about styling stroke-colors and fill colors.

»Silverbullet« currentColor?

svg's currentColor value is handy to color svg elements according to their parent elements' (text) color.
E.g. perfectly suited for an inline (icon font like) element behavior.
But you won't see any effect applying fill color values.

Nothing wrong with the fill property

Since fill is reserved for svg elements – you don't have to worry about accidentally overridden styles.
So it might still be a better choice for some elements.

本文标签: javascriptSwitch Logo color in Dark Mode issueStack Overflow