使用CSS

时间:2018-02-23 03:25:27

标签: javascript css svg sass

我在库中设置了一些图标,这些图标使用了一些基本的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演示此问题:

两个示例都使用相同的类和SVG。

3 个答案:

答案 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;
}

updated codepen

但最好的方法是用类来标记它(就像我对.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)就是这样: - )

Example on codepen

[enter image description here

支持:https://caniuse.com/#feat=css-variables

答案 2 :(得分:0)

只有一个&#34; currentColor&#34;所以你只能改变一件事。但是,您可以利用元素可以使用stroke和/或fill来获得两种颜色选择的事​​实。 (这是@Kaiido&#39的例子的逻辑扩展。)

将您想要成为不同颜色的笔划转换为填充形状。将其余元素保留为描边线形式。现在,您可以使用stroke将一些元素设置为一种颜色,其余使用fill

在以下示例中,顶行是<line>。我们使用stroke属性设置颜色。底线实际上是一个与线条形状相同的矩形。我们使用fill属性设置颜色。

&#13;
&#13;
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;
&#13;
&#13;

此方法适用于您的示例图标,并且希望用于其余图标。但它不适用于每个图标。显然,它依赖于笔画形式中可表示的一种颜色。如果您的图标是两个不同颜色的blob,则可能无法使用此技术。