首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >可以让SVG的CSS Stroke属性从SVG标记继承颜色吗?

可以让SVG的CSS Stroke属性从SVG标记继承颜色吗?
EN

Stack Overflow用户
提问于 2021-05-06 21:39:51
回答 2查看 390关注 0票数 2

编辑:在我的例子中,我需要IE11支持,所以CSS变量不是要走的路。如果你可以使用CSS变量,见凯伊多的答案。如果没有,请看保罗的答案。

我有一个简单的网站与“光”和“黑暗”主题的概念。光的主题是白色或非常轻的背景,而黑暗的主题是一些更深的颜色。网站上的大多数组件是根据其在具有这些主题的元素中的位置来调整其颜色的。例如:

代码语言:javascript
复制
.dark-theme {
  background-color: black;
}

.light-theme  {
  background-color: white;
}

/* When the paragraph is inside a dark theme */
.dark-theme p,
.light-theme .dark-theme p {
  color: white;
}

/* When the paragraph is inside a light theme */
.light-theme p,
.dark-theme .light-theme p {
   color: black;
}

.dark-theme, .light-theme {
    padding: 10px;
}
代码语言:javascript
复制
<div class="light-theme">
  <p>Light Theme</p>
  <div class="dark-theme">
    <p>Dark Theme</p>
  </div>
</div>
<div class="dark-theme">
  <p>Dark Theme</p>
  <div class="light-theme">
    <p>Light Theme</p>
  </div>
</div>

这样我们就可以让每个组件定义它需要如何在黑暗和光明的主题中显示,它在DOM中的位置将处理其余的内容。

这里的问题是,我们必须为每一种情况写定义(暗在光,光在暗)。如果我们不定义一种情况,那么当元素嵌套时,我们就会得到不正确的行为。

但是,在SVG具有定义为stroke属性的特定场景中,我无法使它与SVG一起工作。我们正在使用来自其他地方的图标,因此调整SVG标记不是一个选项。

我们想要的是:当SVG位于光背景(.light-theme)时,SVG应该是SVG标记中的任何颜色(可能有多个)。每当一个SVG在一个黑暗的背景(.dark-theme),我们希望它是白色的(工作)。

下面是当我们使用SVG的<p>fill属性尝试相同的操作时所发生的事情。我似乎无法使用unsetinheritinitial使其返回到SVG的实际值。这是意料之中吗?

如果我不为轻量级主题定义行为,在主题嵌套的情况下,它就会失败。

因此,tl;dr是:如何覆盖使用CSS使用更具体的CSS规则设置的stroke fill fill属性,以获得SVG以使用其标记中定义的原始颜色?

代码语言:javascript
复制
/* When the paragraph is inside a dark theme */
.dark-theme p,
.light-theme .dark-theme p {
  color: white;
}

/* When the paragraph is inside a light theme */
.light-theme p,
.dark-theme .light-theme p {
   color: black;
}

/* When the circle is inside a dark theme */
.dark-theme svg circle,
.light-theme .dark-theme svg circle {
  stroke: white;
  fill: white;
}

/* When the circle is inside a light theme */
.light-theme svg circle,
.dark-theme .light-theme svg circle {
   stroke: initial; /* How to make the circle red here? */
   fill: initial; /* How to make the circle red here? */
}

/** helpers below here **/

svg {
  display: block;
  margin: 0 auto;
}

.light-theme, .dark-theme {
  padding: 10px;
}

.dark-theme {
  background-color: black;
}

.light-theme  {
  background-color: white;
}
代码语言:javascript
复制
<div class="light-theme">
  <p>Light Theme</p>
  <div class="dark-theme">
    <p>Dark Theme</p>
    <svg height="100" width="100">
      <circle cx="50" cy="50" r="40" stroke="red" stroke-width="3" fill="red" />
    </svg> 
  </div>
</div>
<div class="dark-theme">
  <p>Dark Theme</p>
  <div class="light-theme">
    <p>Light Theme</p>
    <svg height="100" width="100">
      <circle cx="50" cy="50" r="40" stroke="red" stroke-width="3" fill="red" />
    </svg> 
  </div>
</div>

通过请求:下面是一个如何嵌套的示例。基本上没有DOM约束可以依赖。

代码语言:javascript
复制
<div class="light-theme"> <!-- nesting can go light > dark > light > dark, etc -->
  <div class="dark-theme">
    <p>Dark Theme</p>
    <div class="something anything really"> <!-- this may or may not be here -->
      <div class="another container dark-theme"> <!-- this may or may not be here -->
        <div class="light-theme">
          <p>Light Theme</p>
          <svg height="100" width="100">
            <circle cx="50" cy="50" r="40" stroke="red" stroke-width="3" fill="red" />
          </svg> 
        </div>
      </div>
    </div>
  </div>
</div>

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-05-09 11:58:35

只有当它是div.dark-theme的直接子元素时,才能将深色主题颜色应用于SVG。

代码语言:javascript
复制
.dark-theme > svg circle {
  stroke: white;
  fill: white;
}

a > b的意思是,如果ba的子级之一,则应用此规则。

如果您可能有更深的嵌套,您可以按如下所示展开此规则:

代码语言:javascript
复制
.dark-theme > svg circle,
.dark-theme > :not(.light-theme) > svg circle,
.dark-theme > :not(.light-theme) > :not(.light-theme) > svg circle,
.dark-theme > :not(.light-theme) > :not(.light-theme) > :not(.light-theme) > svg circle,
.dark-theme > :not(.light-theme) > :not(.light-theme) > :not(.light-theme) > :not(.light-theme) > svg circle
{
  stroke: white;
  fill: white;
}

这可能有点难看,但它的工作和简单。:)

演示:

代码语言:javascript
复制
/* When the paragraph is inside a dark theme */
.dark-theme p,
.light-theme .dark-theme p {
  color: white;
}

/* When the paragraph is inside a light theme */
.light-theme p,
.dark-theme .light-theme p {
   color: black;
}

/* When the circle is inside a dark theme */
.dark-theme > svg circle,
.dark-theme > :not(.light-theme) > svg circle,
.dark-theme > :not(.light-theme) > :not(.light-theme) > svg circle,
.dark-theme > :not(.light-theme) > :not(.light-theme) > :not(.light-theme) > svg circle,
.dark-theme > :not(.light-theme) > :not(.light-theme) > :not(.light-theme) > :not(.light-theme) > svg circle
{
  stroke: white;
  fill: white;
}

/** helpers below here **/

svg {
  display: block;
  margin: 0 auto;
}

.light-theme, .dark-theme {
  padding: 10px;
}

.dark-theme {
  background-color: black;
}

.light-theme  {
  background-color: white;
}
代码语言:javascript
复制
<div class="light-theme">
  <p>Light Theme</p>
  <div class="dark-theme">
    <p>Dark Theme</p>
    <div class="foo">
      <svg height="100" width="100">
        <circle cx="50" cy="50" r="40" stroke="red" stroke-width="3" fill="red" />
      </svg>
    </div>
  </div>
</div>
<div class="dark-theme">
  <p>Dark Theme</p>
  <div class="light-theme">
    <p>Light Theme</p>
    <svg height="100" width="100">
      <circle cx="50" cy="50" r="40" stroke="red" stroke-width="3" fill="red" />
    </svg> 
  </div>
</div>

<!-- UPDATE -->
<div class="light-theme"> <!-- nesting can go light > dark > light > dark, etc -->
  <div class="dark-theme">
    <p>Dark Theme</p>
    <div class="something anything really"> <!-- this may or may not be here -->
      <div class="another container dark-theme"> <!-- this may or may not be here -->
        <div class="light-theme">
          <p>Light Theme</p>
          <svg height="100" width="100">
            <circle cx="50" cy="50" r="40" stroke="red" stroke-width="3" fill="red" />
          </svg> 
        </div>
      </div>
    </div>
  </div>
</div>

票数 1
EN

Stack Overflow用户

发布于 2021-05-11 06:32:15

strokefill属性直接映射到CSS属性,与任何真正的(而不是继承的) CSS属性相比具有更低的特异性。

我们应该能够通过attr() CSS函数轻松地完成您想做的事情,这将允许我们以更高的特异性复制该规则,但仍然不支持任何地方。

一个可能的解决办法,因为您愿意将您的SVGs完全重新着色为白色,就是使用过滤器这样做,而不是改变fillstroke。这样,当我们处于光模式时,我们可以强制使用filter:none .

请注意,即使对于文本的color,您的当前规则实际上也失败了,在类似于.暗-主题>..light主题>.暗-主题的情况下,这是因为这两种规则具有相同的特殊性。要解决这个问题,我们必须依赖继承,而对于filter,这意味着使用CSS-变量。

代码语言:javascript
复制
.dark-theme {
  color: white;
  --filter: brightness(0) grayscale(1) invert(1);
}
.light-theme {
   color: black;
   --filter: none;
}
svg circle {
  filter: var(--filter);
}

代码语言:javascript
复制
.dark-theme {
  color: white;
  --filter: brightness(0) grayscale(1) invert(1);
}
.light-theme {
   color: black;
   --filter: none;
}
svg circle {
  filter: var(--filter);
}

/** helpers below here **/

svg {
  display: block;
  margin: 0 auto;
}

.light-theme, .dark-theme {
  padding: 10px;
}

.dark-theme {
  background-color: black;
}

.light-theme  {
  background-color: white;
}
代码语言:javascript
复制
<div class="light-theme">
  <p>Light Theme</p>
  <div class="dark-theme">
    <p>Dark Theme</p>
    <svg height="100" width="100">
      <circle cx="50" cy="50" r="40" stroke="red" stroke-width="3" fill="red" />
    </svg> 
  </div>
</div>
<div class="dark-theme">
  <p>Dark Theme</p>
  <div class="light-theme">
    <p>Light Theme</p>
    <svg height="100" width="100">
      <circle cx="50" cy="50" r="40" stroke="red" stroke-width="3" fill="red" />
    </svg> 
  </div>
</div>
<div class="light-theme"> <!-- nesting can go light > dark > light > dark, etc -->
  <p>Light Theme</p>
  <div class="dark-theme">
    <p>Dark Theme</p>
    <div class="something anything really"> <!-- this may or may not be here -->
      <div class="another container dark-theme"> <!-- this may or may not be here -->
        <div class="light-theme">
          <p>Light Theme</p>
          <svg height="100" width="100">
            <circle cx="50" cy="50" r="40" stroke="red" stroke-width="3" fill="red" />
          </svg> 
        </div>
      </div>
    </div>
  </div>
</div>
<div class="light-theme"> <!-- nesting can go light > dark > light > dark, etc -->
  <p>Light Theme</p>
  <div class="dark-theme">
    <p>Dark Theme</p>
    <div class="something anything really"> <!-- this may or may not be here -->
      <div class="another container dark-theme"> <!-- this may or may not be here -->
        <div class="light-theme">
          <p>Light Theme</p>
          <div class="dark-theme">
            <p>Dark Theme</p>
            <svg height="100" width="100">
              <circle cx="50" cy="50" r="40" stroke="red" stroke-width="3" fill="red" />
            </svg> 
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67426284

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档