在暗黑模式下切换标志的颜色问题

3
我的作品集中有一个黑色的徽标,我希望在深色模式下将其切换为白色: https://www.paulinerouger.com/ 我尝试过:
- 使用CSS变量
<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);
  } 

  • 使用SVG

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


.nav_logo {
    fill: currentColor;
}

很遗憾,以上所有方法均未奏效。有什么建议吗?

4个回答

3

您可以在 imgcontent 属性中使用 CSS 变量。

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.com/512/169/169367.png');
}

body[data-theme="dark"] {
  --nav_logo: url('https://cdn-icons-png.flaticon.com/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.com/512/169/169367.png" alt="original logo" width="100" height="100" />
</body>


2

将你的svg中的stroke="#000"更改为stroke="currentColor"

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

1
我已经更改为stroke="currentColor",仅在SVG内联中有效。 - PaulineTW

2

如果你在考虑使用基于JS的解决方案,你可以使用我下面开发的方法。点击切换按钮会同时改变<img>元素的src属性以及<body>元素的background-color样式。

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

let darkImageURL = "https://cdn-icons-png.flaticon.com/512/196/196685.png";
let lightImageURL = "https://cdn-icons-png.flaticon.com/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.com/512/169/169367.png" alt="original logo" width="100" height="100"/>
</body>


1
感谢您的回复。我选择了CSS选项。 - PaulineTW

0

SVG非常完美,但无法在<img>元素中使用。 您可以考虑以下步骤:

  • 优化您的logo svg以更一致的方式继承颜色
  • 将您的logo减少到固定的路径元素,即将类似内部条/管的描边元素转换为实心形状/路径,以避免意外的描边宽度变化
  • 使用SVG的<use>概念-提供像<img>一样的用法,即提供外部SVG文件作为可重用资源。

示例1

去除硬编码的SVG属性以获得更好的全局CSS样式:

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.org/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>

  • 所有与路径相关的填充属性都被移除(结果为默认填充为“#000” / 黑色)
  • SVG 父元素获得 fill="currentColor" 属性 - 继承到所有子元素
  • 基于描边的条形/管状元素获得 stroke="currentColor" 规则

示例2

<svg><use href="#..."></svg> 也可以与外部文件正常工作

下一个示例以内联 SVG 作为源,但也可以与外部文件引用一样正常工作(前提是这些外部文件在同一域中可用):

  <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.org/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>

在上面的例子中,笔画被转换为实心路径 - 因此您不必担心样式化描边颜色和填充颜色。
“Silverbullet” currentColor?
svg的currentColor值很方便,可以根据父元素(文本)颜色对svg元素进行着色。例如,非常适合内联(图标字体)元素行为。但是,应用填充颜色值时不会看到任何效果。 fill属性没有问题
由于fill保留给svg元素,因此您不必担心意外覆盖样式。因此,对于某些元素来说,它仍然可能是更好的选择。

非常感谢您详细的回答。 我已经使用内联SVG <svg><use href="#..."></svg> 并且同时使用了 fill="currentColor"stroke="currentColor" 使其正常工作。 - PaulineTW

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接