我在库中设置了一些图标,这些图标使用了一些基本的CSS和一个SVG Sprite(通过webpack生成)。
我希望能够使用多种颜色着色的一些图标。我的设置如下:
mail.svg (为简单起见,省略了svg的详细信息)
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 64 64" width="64" height="64">
<polyline class="primary-stroke" fill="none" stroke-width="2" [more-stuff-here]></polyline>
<path fill="none" stroke-width="2" [more-stuff-here]></path>
<line class="primary-stroke" fill="none" stroke-width="2" [more-stuff-here]></line>
</svg>
我的计算CSS(blue
是主要的强调色)看起来像:
svg {
fill: currentColor;
stroke: currentColor;
}
.primary-stroke {
stroke: blue;
fill: none;
}
我的HTML看起来像:
<svg><use xlink:href="#mail"></svg>
这一切都与预期完全一致,但现在我想更进一步。我希望能够在元素中添加一个类,以确定此实例是否应包含1种单色或2种颜色。
我的尝试非常简单。我刚刚在single-color
元素中添加了svg
类,如下所示:
<svg class="single-color"><use xlink:href="#mail"></svg>
并修改了SCSS。计算出的CSS看起来像:
.single-color .primary-stroke {
stroke: currentColor;
fill: none;
}
但是,它肯定不起作用。 primary
样式仍然有效。我刚开始使用SVG,我不确定是否可以使用精灵来实现我的目标?
CodePens演示此问题:
工作演示(无精灵):https://codepen.io/amlyhamm/pen/ddjXBp
不工作(使用精灵):https://codepen.io/amlyhamm/pen/paZbMq
两个示例都使用相同的类和SVG。
答案 0 :(得分:2)
<use>
元素引用的元素本身不是DOM链的一部分,它只存在于shadow DOM中,因此,您无法通过选择器访问它。
解决方案是直接定位<use>
元素本身,不要为内部.primary-stroke
设置规则,以便它们可以从<use>
继承。
/*
don't set any direct rule on the .variable ones
otherwise, they won't be able to inherit from the <use>
*/
/* target the uses */
.stroke-only use[href="#rects"] {
stroke: blue;
fill: none;
}
.stroke-and-fill use[href="#rects"] {
stroke: blue;
fill: green;
}
/* this one won't get influenced by the <use> */
.fixed {
fill: orange;
stroke: red;
}
svg { display: block; }
<svg width="0" height="0" style="position:absolute;z-index:-1">
<defs>
<g id="rects">
<rect class="variable" x=5 y=5 width=50 height=50 />
<rect class="fixed" x=60 y=5 width=50 height=50 />
</g>
</defs>
</svg>
<svg class="stroke-only" height=70 >
<use href=#rects />
</svg>
<svg class="stroke-and-fill" height=70 >
<use href=#rects />
</svg>
然后对于codepen中的示例,您需要为不改变颜色的一条路径添加特定规则,例如:
#mail path:not([class]) {
stroke: currentColor;
fill: none;
}
但最好的方法是用类来标记它(就像我对.fixed
所做的那样),如果你能控制这个精灵表。
答案 1 :(得分:1)
根据您需要支持的浏览器 - 我会使用CSS变量 它们消除了试图控制SVG颜色的所有麻烦和痛苦,它们也在阴影DOM中工作。
1)将SVG中的变量添加为具有旧版浏览器后备的样式
<path style="fill: var(--color-name, #8d5000)" fill="#8d5000" d="M...." />
CSS variable Default Fallback
2)包括你的SVG
<svg class="my-class"><use xlink:href="#resource"></svg>
3)重新定义CSS中的颜色
.my-class {
--color-one: pink;
--color-two: magenta;
}
4)就是这样: - )
答案 2 :(得分:0)
只有一个&#34; currentColor&#34;所以你只能改变一件事。但是,您可以利用元素可以使用stroke
和/或fill
来获得两种颜色选择的事实。 (这是@Kaiido&#39的例子的逻辑扩展。)
将您想要成为不同颜色的笔划转换为填充形状。将其余元素保留为描边线形式。现在,您可以使用stroke
将一些元素设置为一种颜色,其余使用fill
。
在以下示例中,顶行是<line>
。我们使用stroke
属性设置颜色。底线实际上是一个与线条形状相同的矩形。我们使用fill
属性设置颜色。
body {
color: #aaa;
display: flex;
justify-content: center;
text-align: center;
font-family: Arial;
}
.example {
padding: 10px 20px;
}
.example {
stroke: green;
fill: blue;
}
.single-color {
stroke: currentColor;
fill: currentColor;
}
&#13;
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position: absolute; width: 0; height: 0" id="__SVG_SPRITE_NODE__">
<symbol viewBox="0 0 64 64" id="mail">
<!-- The top line is an actual line. -->
<!-- We set its colour using the stroke attribute. -->
<line x1="10" y1="20" x2="54" y2="20" stroke-width="16" fill="none"/>
<!-- The bottom line is a path the same shape as the line -->
<!-- We set its colour using the fill attribute. -->
<path d="M 10,35 h44 v16 h-44 z" stroke="none" />
</symbol>
</svg>
<div class="example">
<h2>Two Colors:</h2>
<svg><use xlink:href="#mail"/></svg>
</div>
<div class="example">
<h2>Single Color:</h2>
<svg><use xlink:href="#mail" class="single-color"/></svg>
</div>
&#13;
此方法适用于您的示例图标,并且希望用于其余图标。但它不适用于每个图标。显然,它依赖于笔画形式中可表示的一种颜色。如果您的图标是两个不同颜色的blob,则可能无法使用此技术。