如何为所有类型的 SVG 结构定义 CSS 样式?

How to define CSS style for ALL types of SVG'S structure?

我的页面上有很多 SVG,我将它们导入为(在 React 中):

import { ReactComponent as Logo } from "./../../../images/example.svg";

我这样使用它们:

<div className='someClassName activeClassName?'>
  <Logo />
</div>

但它们的结构各不相同。 我是什么意思?一些 SVG 看起来像:

<svg>
  <path/>
</svg>

有些喜欢:

<svg>
  <g>
     <g>
        <path/>
     </g>
  </g>
</svg>

有些看起来像:

<svg>
  <g>
     <circle/> 
     <triangle/>
  </g>
</svg>

像这样的类型有数百万种。 我有一个 'activeClassName' 以不同的颜色填充 SVG,当它处于活动状态时,但为了使其与我所有的 SVG 一起工作,我必须像这样描述我的类名样式:

&--active {
      svg {
        fill: $primaryBlue !important;
        path {
          fill: $primaryBlue !important;
        }
        g {
          fill: $primaryBlue !important;
          g path {
            fill: $primaryBlue !important;
          }
        }
      }
    }

这看起来糟透了。例如,我如何更改所有这些 SVG 的填充选项?请帮帮我...谢谢

正如@Robert Longson 和@chrwahl 指出的那样:
建议从 svg 子元素中删除填充属性。
不确定,如何“pre/postprocess”导入的 svg 组件。

在纯 js 中,您可以像这样轻松查询子元素并删除属性:

let svgAsset = document.querySelector(".svgAsset");
// query child elements – maybe includeother svg primitives like circles/rects
let svgChildEls = svgAsset.querySelectorAll("g, path, circle, rect, polygon");


function removeFills(els = svgChildEls) {
  els.forEach(function (el, i) {
      el.removeAttribute("fill");
  });
}

function addElClass(els = svgChildEls) {
  els.forEach(function (el, i) {
    let nodeName = el.nodeName.toLowerCase();
    if(nodeName!='g'){
       el.classList.add("svgChild");
    }
  });
}

function toggleActive(){
  svgAsset.classList.toggle('svgActive');
  svgAsset.classList.toggle('svgInactive');
}
svg{
  display:inline-block;
  width:200px;
}

/* inactive */
.svgInactive{
    fill: #ccc;
}

.svgActive{
  fill: orange;
}

.svgActive
.svgChild{
  fill: blue;
}
<p>
  <button onclick="toggleActive()">toggle active</button>
  <button onclick="removeFills()">Remove fill attributes</button>
  <button onclick="addElClass()">Add element Class</button>
</p>
<div class="svgWrp">
  <svg class="svgAsset svgInactive" viewBox="0 0 100 100">
    <path id="path0" fill="red" d="M0 0 l50 0 l0 50 l-50 0 z" />
    <path id="path1" class="hasClass" fill="green" d="M33 33 l50 0 l0 50 l-50 0 z" />
    <g fill="purple">
      <circle id="" cx="66.666%" cy="33.333%" r="25%" fill="none" stroke="#000" stroke-width="2" />
    </g>
  </svg>
</div>
在上面的示例中,我还包括 <g> 元素和其他形状基元,如多边形:

let svgChildEls = svgAsset.querySelectorAll("g, path, circle, rect, polygon");

您受益于较低的 css 特异性 – 因此您不需要像

这样的嵌套选择器

svg g path{ ... }

手动检查和优化您的 svg 源 material 始终是最好的方法,因为您不能期望来自不同源的图形具有连贯的结构。
例如,由 GUI 应用程序生成的 svg 往往具有稍微古怪的标记,包括许多 <g> 嵌套、未使用或太多转换(使其难以获得或操作 x/y 偏移量)等。