【问题标题】:Switch Logo color in Dark Mode issue在深色模式下切换徽标颜色问题
【发布时间】:2022-02-23 01:18:37
【问题描述】:

我的作品集有一个黑色徽标,我想在深色模式下将其切换为白色: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;
}

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

【问题讨论】:

    标签: javascript html css svg


    【解决方案1】:

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

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

    【讨论】:

    • 我已更改为 stroke="currentColor" 仅使用 svg inline
    【解决方案2】:

    如果您正在考虑基于 JS 的解决方案,您可以使用我在下面开发的方法。单击切换按钮会同时更改&lt;img&gt; 元素的src 属性和&lt;body&gt; 元素的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>

    【讨论】:

    • 感谢您的回复。选择 CSS 选项
    【解决方案3】:

    您可以将带有content 属性的css 变量用于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.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>

    【讨论】:

      【解决方案4】:

      Svg 非常完美——但不能在 &lt;img&gt; 元素中工作。 您可以考虑以下步骤:

      • 优化您的徽标 svg 以更一致的方式继承颜色
      • 将您的徽标减少为固定路径元素,即将内栏/管道等描边元素转换为实心形状/路径,以避免意外的打击宽度变化
      • 使用 svg &lt;use&gt; 概念 - 提供类似 &lt;img&gt; 的用法,即提供外部 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

      &lt;svg&gt;&lt;use href="#..."&gt;&lt;/svg&gt; 也适用于外部文件

      下一个示例将内联的 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>

      在上面的示例中,笔触被转换为实心路径——因此您不必费心设置笔触颜色和填充颜色。

      »银弹« currentColor?

      svg 的 currentColor 值可以方便地根据父元素的(文本)颜色为 svg 元素着色。
      例如。非常适合内联(类似图标字体)元素的行为。
      但是您不会看到应用填充颜色值的任何效果。

      fill 属性没有问题

      由于 fill 是为 svg 元素保留的 - 您不必担心会意外覆盖样式。
      所以对于某些元素来说,它可能仍然是一个更好的选择。

      【讨论】:

      • 非常感谢您的详细回答。我让它使用内联 SVG &lt;svg&gt;&lt;use href="#..."&gt;&lt;/svg&gt;fill="currentColor"stroke="currentColor"
      猜你喜欢
      • 2020-06-10
      • 1970-01-01
      • 1970-01-01
      • 2021-03-27
      • 2021-04-16
      • 1970-01-01
      • 1970-01-01
      • 2021-11-11
      • 1970-01-01
      相关资源
      最近更新 更多